diff options
Diffstat (limited to 'drivers/staging/media/imx/imx-media.h')
-rw-r--r-- | drivers/staging/media/imx/imx-media.h | 189 |
1 files changed, 69 insertions, 120 deletions
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h index ac3ab11..2fd6dfd 100644 --- a/drivers/staging/media/imx/imx-media.h +++ b/drivers/staging/media/imx/imx-media.h @@ -11,6 +11,7 @@ #ifndef _IMX_MEDIA_H #define _IMX_MEDIA_H +#include <linux/platform_device.h> #include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> #include <media/v4l2-fwnode.h> @@ -19,26 +20,6 @@ #include <video/imx-ipu-v3.h> /* - * This is somewhat arbitrary, but we need at least: - * - 4 video devices per IPU - * - 3 IC subdevs per IPU - * - 1 VDIC subdev per IPU - * - 2 CSI subdevs per IPU - * - 1 mipi-csi2 receiver subdev - * - 2 video-mux subdevs - * - 2 camera sensor subdevs per IPU (1 parallel, 1 mipi-csi2) - * - */ -/* max video devices */ -#define IMX_MEDIA_MAX_VDEVS 8 -/* max subdevices */ -#define IMX_MEDIA_MAX_SUBDEVS 32 -/* max pads per subdev */ -#define IMX_MEDIA_MAX_PADS 16 -/* max links per pad */ -#define IMX_MEDIA_MAX_LINKS 8 - -/* * Pad definitions for the subdevs with multiple source or * sink pads */ @@ -51,9 +32,6 @@ enum { CSI_NUM_PADS, }; -#define CSI_NUM_SINK_PADS 1 -#define CSI_NUM_SRC_PADS 2 - /* ipu_vdic */ enum { VDIC_SINK_PAD_DIRECT = 0, @@ -62,9 +40,6 @@ enum { VDIC_NUM_PADS, }; -#define VDIC_NUM_SINK_PADS 2 -#define VDIC_NUM_SRC_PADS 1 - /* ipu_ic_prp */ enum { PRP_SINK_PAD = 0, @@ -73,9 +48,6 @@ enum { PRP_NUM_PADS, }; -#define PRP_NUM_SINK_PADS 1 -#define PRP_NUM_SRC_PADS 2 - /* ipu_ic_prpencvf */ enum { PRPENCVF_SINK_PAD = 0, @@ -83,9 +55,6 @@ enum { PRPENCVF_NUM_PADS, }; -#define PRPENCVF_NUM_SINK_PADS 1 -#define PRPENCVF_NUM_SRC_PADS 1 - /* How long to wait for EOF interrupts in the buffer-capture subdevs */ #define IMX_MEDIA_EOF_TIMEOUT 1000 @@ -110,6 +79,9 @@ struct imx_media_video_dev { /* the user format */ struct v4l2_format fmt; const struct imx_media_pixfmt *cc; + + /* links this vdev to master list */ + struct list_head list; }; static inline struct imx_media_buffer *to_imx_media_vb(struct vb2_buffer *vb) @@ -119,25 +91,24 @@ static inline struct imx_media_buffer *to_imx_media_vb(struct vb2_buffer *vb) return container_of(vbuf, struct imx_media_buffer, vbuf); } -struct imx_media_link { - struct device_node *remote_sd_node; - char remote_devname[32]; - int local_pad; - int remote_pad; -}; +/* + * to support control inheritance to video devices, this + * retrieves a pad's list_head of video devices that can + * be reached from the pad. Note that only the lists in + * source pads get populated, sink pads have empty lists. + */ +static inline struct list_head * +to_pad_vdev_list(struct v4l2_subdev *sd, int pad_index) +{ + struct list_head *vdev_list = sd->host_priv; -struct imx_media_pad { - struct media_pad pad; - struct imx_media_link link[IMX_MEDIA_MAX_LINKS]; - bool devnode; /* does this pad link to a device node */ - int num_links; - - /* - * list of video devices that can be reached from this pad, - * list is only valid for source pads. - */ - struct imx_media_video_dev *vdev[IMX_MEDIA_MAX_VDEVS]; - int num_vdevs; + return vdev_list ? &vdev_list[pad_index] : NULL; +} + +/* an entry in a pad's video device list */ +struct imx_media_pad_vdev { + struct imx_media_video_dev *vdev; + struct list_head list; }; struct imx_media_internal_sd_platformdata { @@ -146,23 +117,20 @@ struct imx_media_internal_sd_platformdata { int ipu_id; }; -struct imx_media_subdev { - struct v4l2_async_subdev asd; - struct v4l2_subdev *sd; /* set when bound */ - - struct imx_media_pad pad[IMX_MEDIA_MAX_PADS]; - int num_sink_pads; - int num_src_pads; - /* the platform device if this is an internal subdev */ +struct imx_media_async_subdev { + struct v4l2_async_subdev asd; + /* the platform device of IPU-internal subdevs */ struct platform_device *pdev; - /* the devname is needed for async devname match */ - char devname[32]; - - /* if this is a sensor */ - struct v4l2_fwnode_endpoint sensor_ep; + struct list_head list; }; +static inline struct imx_media_async_subdev * +to_imx_media_asd(struct v4l2_async_subdev *asd) +{ + return container_of(asd, struct imx_media_async_subdev, asd); +} + struct imx_media_dev { struct media_device md; struct v4l2_device v4l2_dev; @@ -172,19 +140,14 @@ struct imx_media_dev { struct mutex mutex; /* protect elements below */ - /* master subdevice list */ - struct imx_media_subdev subdev[IMX_MEDIA_MAX_SUBDEVS]; - int num_subdevs; - /* master video device list */ - struct imx_media_video_dev *vdev[IMX_MEDIA_MAX_VDEVS]; - int num_vdevs; + struct list_head vdev_list; /* IPUs this media driver control, valid after subdevs bound */ struct ipu_soc *ipu[2]; /* for async subdev registration */ - struct v4l2_async_subdev *async_ptrs[IMX_MEDIA_MAX_SUBDEVS]; + struct list_head asd_list; struct v4l2_async_notifier subdev_notifier; }; @@ -194,6 +157,7 @@ enum codespace_sel { CS_SEL_ANY, }; +/* imx-media-utils.c */ const struct imx_media_pixfmt * imx_media_find_format(u32 fourcc, enum codespace_sel cs_sel, bool allow_bayer); int imx_media_enum_format(u32 *fourcc, u32 index, enum codespace_sel cs_sel); @@ -205,7 +169,6 @@ int imx_media_enum_mbus_format(u32 *code, u32 index, enum codespace_sel cs_sel, const struct imx_media_pixfmt * imx_media_find_ipu_format(u32 code, enum codespace_sel cs_sel); int imx_media_enum_ipu_format(u32 *code, u32 index, enum codespace_sel cs_sel); - int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus, u32 width, u32 height, u32 code, u32 field, const struct imx_media_pixfmt **cc); @@ -219,48 +182,26 @@ int imx_media_mbus_fmt_to_ipu_image(struct ipu_image *image, struct v4l2_mbus_framefmt *mbus); int imx_media_ipu_image_to_mbus_fmt(struct v4l2_mbus_framefmt *mbus, struct ipu_image *image); - -struct imx_media_subdev * -imx_media_find_async_subdev(struct imx_media_dev *imxmd, - struct device_node *np, - const char *devname); -struct imx_media_subdev * -imx_media_add_async_subdev(struct imx_media_dev *imxmd, - struct device_node *np, - struct platform_device *pdev); -int imx_media_add_pad_link(struct imx_media_dev *imxmd, - struct imx_media_pad *pad, - struct device_node *remote_node, - const char *remote_devname, - int local_pad, int remote_pad); - void imx_media_grp_id_to_sd_name(char *sd_name, int sz, u32 grp_id, int ipu_id); - -int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd, - struct imx_media_subdev *csi[4]); -void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd); - -struct imx_media_subdev * -imx_media_find_subdev_by_sd(struct imx_media_dev *imxmd, - struct v4l2_subdev *sd); -struct imx_media_subdev * -imx_media_find_subdev_by_id(struct imx_media_dev *imxmd, - u32 grp_id); +struct v4l2_subdev * +imx_media_find_subdev_by_fwnode(struct imx_media_dev *imxmd, + struct fwnode_handle *fwnode); +struct v4l2_subdev * +imx_media_find_subdev_by_devname(struct imx_media_dev *imxmd, + const char *devname); int imx_media_add_video_device(struct imx_media_dev *imxmd, struct imx_media_video_dev *vdev); int imx_media_find_mipi_csi2_channel(struct imx_media_dev *imxmd, struct media_entity *start_entity); -struct imx_media_subdev * +struct media_pad * +imx_media_find_upstream_pad(struct imx_media_dev *imxmd, + struct media_entity *start_entity, + u32 grp_id); +struct v4l2_subdev * imx_media_find_upstream_subdev(struct imx_media_dev *imxmd, struct media_entity *start_entity, u32 grp_id); -struct imx_media_subdev * -__imx_media_find_sensor(struct imx_media_dev *imxmd, - struct media_entity *start_entity); -struct imx_media_subdev * -imx_media_find_sensor(struct imx_media_dev *imxmd, - struct media_entity *start_entity); struct imx_media_dma_buf { void *virt; @@ -278,6 +219,11 @@ int imx_media_pipeline_set_stream(struct imx_media_dev *imxmd, struct media_entity *entity, bool on); +/* imx-media-dev.c */ +int imx_media_add_async_subdev(struct imx_media_dev *imxmd, + struct fwnode_handle *fwnode, + struct platform_device *pdev); + /* imx-media-fim.c */ struct imx_media_fim; void imx_media_fim_eof_monitor(struct imx_media_fim *fim, ktime_t timestamp); @@ -288,14 +234,19 @@ int imx_media_fim_add_controls(struct imx_media_fim *fim); struct imx_media_fim *imx_media_fim_init(struct v4l2_subdev *sd); void imx_media_fim_free(struct imx_media_fim *fim); +/* imx-media-internal-sd.c */ +int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd); +int imx_media_create_internal_links(struct imx_media_dev *imxmd, + struct v4l2_subdev *sd); +void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd); + /* imx-media-of.c */ -struct imx_media_subdev * -imx_media_of_find_subdev(struct imx_media_dev *imxmd, - struct device_node *np, - const char *name); -int imx_media_of_parse(struct imx_media_dev *dev, - struct imx_media_subdev *(*csi)[4], - struct device_node *np); +int imx_media_add_of_subdevs(struct imx_media_dev *dev, + struct device_node *np); +int imx_media_create_of_links(struct imx_media_dev *imxmd, + struct v4l2_subdev *sd); +int imx_media_create_csi_of_links(struct imx_media_dev *imxmd, + struct v4l2_subdev *csi); /* imx-media-capture.c */ struct imx_media_video_dev * @@ -310,16 +261,14 @@ void imx_media_capture_device_set_format(struct imx_media_video_dev *vdev, void imx_media_capture_device_error(struct imx_media_video_dev *vdev); /* subdev group ids */ -#define IMX_MEDIA_GRP_ID_SENSOR (1 << 8) -#define IMX_MEDIA_GRP_ID_VIDMUX (1 << 9) -#define IMX_MEDIA_GRP_ID_CSI2 (1 << 10) -#define IMX_MEDIA_GRP_ID_CSI_BIT 11 +#define IMX_MEDIA_GRP_ID_CSI2 BIT(8) +#define IMX_MEDIA_GRP_ID_CSI_BIT 9 #define IMX_MEDIA_GRP_ID_CSI (0x3 << IMX_MEDIA_GRP_ID_CSI_BIT) -#define IMX_MEDIA_GRP_ID_CSI0 (1 << IMX_MEDIA_GRP_ID_CSI_BIT) +#define IMX_MEDIA_GRP_ID_CSI0 BIT(IMX_MEDIA_GRP_ID_CSI_BIT) #define IMX_MEDIA_GRP_ID_CSI1 (2 << IMX_MEDIA_GRP_ID_CSI_BIT) -#define IMX_MEDIA_GRP_ID_VDIC (1 << 13) -#define IMX_MEDIA_GRP_ID_IC_PRP (1 << 14) -#define IMX_MEDIA_GRP_ID_IC_PRPENC (1 << 15) -#define IMX_MEDIA_GRP_ID_IC_PRPVF (1 << 16) +#define IMX_MEDIA_GRP_ID_VDIC BIT(11) +#define IMX_MEDIA_GRP_ID_IC_PRP BIT(12) +#define IMX_MEDIA_GRP_ID_IC_PRPENC BIT(13) +#define IMX_MEDIA_GRP_ID_IC_PRPVF BIT(14) #endif |