/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Driver for STM32 Digital Camera Memory Interface Pixel Processor * * Copyright (C) STMicroelectronics SA 2023 * Authors: Hugues Fruchet <[email protected]> * Alain Volmat <[email protected]> * for STMicroelectronics. */ #ifndef _DCMIPP_COMMON_H_ #define _DCMIPP_COMMON_H_ #include <linux/interrupt.h> #include <linux/slab.h> #include <media/media-device.h> #include <media/v4l2-device.h> #include <media/v4l2-fwnode.h> #define DCMIPP_PDEV_NAME … #define DCMIPP_FRAME_MAX_WIDTH … #define DCMIPP_FRAME_MAX_HEIGHT … #define DCMIPP_FRAME_MIN_WIDTH … #define DCMIPP_FRAME_MIN_HEIGHT … #define DCMIPP_FMT_WIDTH_DEFAULT … #define DCMIPP_FMT_HEIGHT_DEFAULT … #define DCMIPP_COLORSPACE_DEFAULT … #define DCMIPP_YCBCR_ENC_DEFAULT … #define DCMIPP_QUANTIZATION_DEFAULT … #define DCMIPP_XFER_FUNC_DEFAULT … /** * dcmipp_colorimetry_clamp() - Adjust colorimetry parameters * * @fmt: the pointer to struct v4l2_pix_format or * struct v4l2_mbus_framefmt * * Entities must check if colorimetry given by the userspace is valid, if not * then set them as DEFAULT */ #define dcmipp_colorimetry_clamp(fmt) … /** * struct dcmipp_ent_device - core struct that represents a node in the topology * * @ent: the pointer to struct media_entity for the node * @pads: the list of pads of the node * @bus: struct v4l2_mbus_config_parallel describing input bus * @bus_type: type of input bus (parallel or BT656) * @handler: irq handler dedicated to the subdev * @handler_ret: value returned by the irq handler * @thread_fn: threaded irq handler * * The DCMIPP provides a single IRQ line and a IRQ status registers for all * subdevs, hence once the main irq handler (registered at probe time) is * called, it will chain calls to the irq handler of each the subdevs of the * pipelines, using the handler/handler_ret/thread_fn variables. * * Each node of the topology must create a dcmipp_ent_device struct. * Depending on the node it will be of an instance of v4l2_subdev or * video_device struct where both contains a struct media_entity. * Those structures should embedded the dcmipp_ent_device struct through * v4l2_set_subdevdata() and video_set_drvdata() respectivaly, allowing the * dcmipp_ent_device struct to be retrieved from the corresponding struct * media_entity */ struct dcmipp_ent_device { … }; /** * dcmipp_pads_init - initialize pads * * @num_pads: number of pads to initialize * @pads_flags: flags to use in each pad * * Helper functions to allocate/initialize pads */ struct media_pad *dcmipp_pads_init(u16 num_pads, const unsigned long *pads_flags); /** * dcmipp_pads_cleanup - free pads * * @pads: pointer to the pads * * Helper function to free the pads initialized with dcmipp_pads_init */ static inline void dcmipp_pads_cleanup(struct media_pad *pads) { … } /** * dcmipp_ent_sd_register - initialize and register a subdev node * * @ved: the dcmipp_ent_device struct to be initialize * @sd: the v4l2_subdev struct to be initialize and registered * @v4l2_dev: the v4l2 device to register the v4l2_subdev * @name: name of the sub-device. Please notice that the name must be * unique. * @function: media entity function defined by MEDIA_ENT_F_* macros * @num_pads: number of pads to initialize * @pads_flag: flags to use in each pad * @sd_int_ops: pointer to &struct v4l2_subdev_internal_ops * @sd_ops: pointer to &struct v4l2_subdev_ops. * @handler: func pointer of the irq handler * @thread_fn: func pointer of the threaded irq handler * * Helper function initialize and register the struct dcmipp_ent_device and * struct v4l2_subdev which represents a subdev node in the topology */ int dcmipp_ent_sd_register(struct dcmipp_ent_device *ved, struct v4l2_subdev *sd, struct v4l2_device *v4l2_dev, const char *const name, u32 function, u16 num_pads, const unsigned long *pads_flag, const struct v4l2_subdev_internal_ops *sd_int_ops, const struct v4l2_subdev_ops *sd_ops, irq_handler_t handler, irq_handler_t thread_fn); /** * dcmipp_ent_sd_unregister - cleanup and unregister a subdev node * * @ved: the dcmipp_ent_device struct to be cleaned up * @sd: the v4l2_subdev struct to be unregistered * * Helper function cleanup and unregister the struct dcmipp_ent_device and * struct v4l2_subdev which represents a subdev node in the topology */ void dcmipp_ent_sd_unregister(struct dcmipp_ent_device *ved, struct v4l2_subdev *sd); #define reg_write(device, reg, val) … #define reg_read(device, reg) … #define reg_set(device, reg, mask) … #define reg_clear(device, reg, mask) … static inline u32 __reg_read(struct device *dev, void __iomem *base, u32 reg) { … } static inline void __reg_write(struct device *dev, void __iomem *base, u32 reg, u32 val) { … } static inline void __reg_set(struct device *dev, void __iomem *base, u32 reg, u32 mask) { … } static inline void __reg_clear(struct device *dev, void __iomem *base, u32 reg, u32 mask) { … } /* DCMIPP subdev init / release entry points */ struct dcmipp_ent_device *dcmipp_par_ent_init(struct device *dev, const char *entity_name, struct v4l2_device *v4l2_dev, void __iomem *regs); void dcmipp_par_ent_release(struct dcmipp_ent_device *ved); struct dcmipp_ent_device * dcmipp_byteproc_ent_init(struct device *dev, const char *entity_name, struct v4l2_device *v4l2_dev, void __iomem *regs); void dcmipp_byteproc_ent_release(struct dcmipp_ent_device *ved); struct dcmipp_ent_device *dcmipp_bytecap_ent_init(struct device *dev, const char *entity_name, struct v4l2_device *v4l2_dev, void __iomem *regs); void dcmipp_bytecap_ent_release(struct dcmipp_ent_device *ved); #endif