diff options
Diffstat (limited to 'drivers/staging/media/imx')
-rw-r--r-- | drivers/staging/media/imx/imx8-isi-cap.c | 155 | ||||
-rw-r--r-- | drivers/staging/media/imx/imx8-mipi-csi2.c | 96 |
2 files changed, 250 insertions, 1 deletions
diff --git a/drivers/staging/media/imx/imx8-isi-cap.c b/drivers/staging/media/imx/imx8-isi-cap.c index 5ff28bfb32d3..220b533489fc 100644 --- a/drivers/staging/media/imx/imx8-isi-cap.c +++ b/drivers/staging/media/imx/imx8-isi-cap.c @@ -34,6 +34,14 @@ struct mxc_isi_fmt mxc_isi_out_formats[] = { { + .name = "UYVY-16", + .fourcc = V4L2_PIX_FMT_UYVY, + .depth = { 16 }, + .color = MXC_ISI_OUT_FMT_YUV422_1P8P, + .memplanes = 1, + .colplanes = 1, + .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, + }, { .name = "RGB565", .fourcc = V4L2_PIX_FMT_RGB565, .depth = { 16 }, @@ -535,6 +543,8 @@ static struct vb2_ops mxc_cap_vb2_qops = { .stop_streaming = cap_vb2_stop_streaming, }; +/* To enable ctrls in sensor driver, we need to comment the ISI ctrls */ +#ifndef CONFIG_VIDEO_ECAM /* * V4L2 controls handling */ @@ -624,6 +634,7 @@ void mxc_isi_ctrls_delete(struct mxc_isi_cap_dev *isi_cap) ctrls->alpha = NULL; } } +#endif static struct media_pad *mxc_isi_get_remote_source_pad(struct mxc_isi_cap_dev *isi_cap) @@ -1261,6 +1272,129 @@ static int mxc_isi_cap_enum_frameintervals(struct file *file, void *fh, return 0; } +#ifdef CONFIG_VIDEO_ECAM +static int mxc_vidioc_queryctrl(struct file *file, void *fh, + struct v4l2_queryctrl *a) +{ + struct mxc_isi_cap_dev *isi_cap = video_drvdata(file); + struct v4l2_subdev *sd; + + sd = mxc_get_remote_subdev(isi_cap, __func__); + if (!sd) + return -EINVAL; + + return v4l2_subdev_call(sd, core, queryctrl, a); +} + +static int mxc_vidioc_query_ext_ctrl(struct file *file, void *fh, + struct v4l2_query_ext_ctrl *qec) +{ + struct v4l2_queryctrl qc = { + .id = qec->id + }; + int ret; + + ret = mxc_vidioc_queryctrl(file, fh, &qc); + + if (ret) + return ret; + + qec->id = qc.id; + qec->type = qc.type; + strlcpy(qec->name, qc.name, sizeof(qec->name)); + qec->maximum = qc.maximum; + qec->minimum = qc.minimum; + qec->step = qc.step; + qec->default_value = qc.default_value; + qec->flags = qc.flags; + qec->elem_size = 4; + qec->elems = 1; + qec->nr_of_dims = 0; + memset(qec->dims, 0, sizeof(qec->dims)); + memset(qec->reserved, 0, sizeof(qec->reserved)); + + return 0; +} + +static int mxc_isi_vidioc_querymenu(struct file *file, void *fh, + struct v4l2_querymenu *qm) +{ + struct mxc_isi_cap_dev *isi_cap = video_drvdata(file); + struct v4l2_subdev *sd; + + sd = mxc_get_remote_subdev(isi_cap, __func__); + if (!sd) + return -EINVAL; + + return v4l2_subdev_call(sd, core, querymenu, qm); +} + +static int mxc_isi_vidioc_g_ctrl(struct file *file, void *fh, + struct v4l2_control *a) +{ + struct mxc_isi_cap_dev *isi_cap = video_drvdata(file); + struct v4l2_subdev *sd; + + sd = mxc_get_remote_subdev(isi_cap, __func__); + if (!sd) + return -EINVAL; + + return v4l2_subdev_call(sd, core, g_ctrl, a); +} + +static int mxc_isi_vidioc_s_ctrl(struct file *file, void *fh, + struct v4l2_control *a) +{ + struct mxc_isi_cap_dev *isi_cap = video_drvdata(file); + struct v4l2_subdev *sd; + + sd = mxc_get_remote_subdev(isi_cap, __func__); + if (!sd) + return -EINVAL; + + return v4l2_subdev_call(sd, core, s_ctrl, a); +} + +static int mxc_isi_vidioc_g_ext_ctrls(struct file *file, void *fh, + struct v4l2_ext_controls *a) +{ + struct mxc_isi_cap_dev *isi_cap = video_drvdata(file); + struct v4l2_subdev *sd; + + sd = mxc_get_remote_subdev(isi_cap, __func__); + if (!sd) + return -EINVAL; + + return v4l2_subdev_call(sd, core, g_ext_ctrls, a); +} + +static int mxc_isi_vidioc_try_ext_ctrls(struct file *file, void *fh, + struct v4l2_ext_controls *a) +{ + struct mxc_isi_cap_dev *isi_cap = video_drvdata(file); + struct v4l2_subdev *sd; + + sd = mxc_get_remote_subdev(isi_cap, __func__); + if (!sd) + return -EINVAL; + + return v4l2_subdev_call(sd, core, try_ext_ctrls, a); +} + +static int mxc_isi_vidioc_s_ext_ctrls(struct file *file, void *fh, + struct v4l2_ext_controls *a) +{ + struct mxc_isi_cap_dev *isi_cap = video_drvdata(file); + struct v4l2_subdev *sd; + + sd = mxc_get_remote_subdev(isi_cap, __func__); + if (!sd) + return -EINVAL; + + return v4l2_subdev_call(sd, core, s_ext_ctrls, a); +} +#endif + static const struct v4l2_ioctl_ops mxc_isi_capture_ioctl_ops = { .vidioc_querycap = mxc_isi_cap_querycap, @@ -1288,6 +1422,16 @@ static const struct v4l2_ioctl_ops mxc_isi_capture_ioctl_ops = { .vidioc_enum_framesizes = mxc_isi_cap_enum_framesizes, .vidioc_enum_frameintervals = mxc_isi_cap_enum_frameintervals, +#ifdef CONFIG_VIDEO_ECAM + .vidioc_queryctrl = mxc_vidioc_queryctrl, + .vidioc_query_ext_ctrl = mxc_vidioc_query_ext_ctrl, + .vidioc_querymenu = mxc_isi_vidioc_querymenu, + .vidioc_g_ctrl = mxc_isi_vidioc_g_ctrl, + .vidioc_s_ctrl = mxc_isi_vidioc_s_ctrl, + .vidioc_g_ext_ctrls = mxc_isi_vidioc_g_ext_ctrls, + .vidioc_s_ext_ctrls = mxc_isi_vidioc_s_ext_ctrls, + .vidioc_try_ext_ctrls = mxc_isi_vidioc_try_ext_ctrls +#endif }; /* Capture subdev media entity operations */ @@ -1604,22 +1748,28 @@ static int mxc_isi_register_cap_device(struct mxc_isi_cap_dev *isi_cap, if (ret) goto err_free_ctx; +/* To enable ctrls in sensor driver, we need to comment the ISI ctrls */ +#ifndef CONFIG_VIDEO_ECAM ret = mxc_isi_ctrls_create(isi_cap); if (ret) goto err_me_cleanup; +#endif ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (ret) goto err_ctrl_free; - +#ifndef CONFIG_VIDEO_ECAM vdev->ctrl_handler = &isi_cap->ctrls.handler; +#endif v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n", vdev->name, video_device_node_name(vdev)); return 0; err_ctrl_free: +#ifndef CONFIG_VIDEO_ECAM mxc_isi_ctrls_delete(isi_cap); +#endif err_me_cleanup: media_entity_cleanup(&vdev->entity); err_free_ctx: @@ -1657,7 +1807,10 @@ static void mxc_isi_subdev_unregistered(struct v4l2_subdev *sd) vdev = &isi_cap->vdev; if (video_is_registered(vdev)) { video_unregister_device(vdev); +/* To enable ctrls in sensor driver, we need to comment the ISI ctrls*/ +#ifndef CONFIG_VIDEO_ECAM mxc_isi_ctrls_delete(isi_cap); +#endif media_entity_cleanup(&vdev->entity); } mutex_unlock(&isi_cap->lock); diff --git a/drivers/staging/media/imx/imx8-mipi-csi2.c b/drivers/staging/media/imx/imx8-mipi-csi2.c index 19b76fa72782..13a615381c47 100644 --- a/drivers/staging/media/imx/imx8-mipi-csi2.c +++ b/drivers/staging/media/imx/imx8-mipi-csi2.c @@ -801,6 +801,93 @@ static const struct media_entity_operations mipi_csi2_sd_media_ops = { /* * V4L2 subdev operations */ +#ifdef CONFIG_VIDEO_ECAM +static int mipi_csi2_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm) +{ + struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); + struct v4l2_subdev *sen_sd; + + sen_sd = mxc_get_remote_subdev(csi2dev, __func__); + if (!sen_sd) + return -EINVAL; + + return v4l2_subdev_call(sen_sd, core, querymenu, qm); +} + +static int mipi_csi2_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) +{ + struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); + struct v4l2_subdev *sen_sd; + + sen_sd = mxc_get_remote_subdev(csi2dev, __func__); + if (!sen_sd) + return -EINVAL; + + return v4l2_subdev_call(sen_sd, core, queryctrl, qc); +} + +static int mipi_csi2_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); + struct v4l2_subdev *sen_sd; + + sen_sd = mxc_get_remote_subdev(csi2dev, __func__); + if (!sen_sd) + return -EINVAL; + + return v4l2_subdev_call(sen_sd, core, g_ctrl, ctrl); +} + +static int mipi_csi2_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + + struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); + struct v4l2_subdev *sen_sd; + + sen_sd = mxc_get_remote_subdev(csi2dev, __func__); + if (!sen_sd) + return -EINVAL; + + return v4l2_subdev_call(sen_sd, core, s_ctrl, ctrl); +} + +static int mipi_csi2_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls) +{ + struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); + struct v4l2_subdev *sen_sd; + + sen_sd = mxc_get_remote_subdev(csi2dev, __func__); + if (!sen_sd) + return -EINVAL; + + return v4l2_subdev_call(sen_sd, core, g_ext_ctrls, ctrls); +} + +static int mipi_csi2_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls) +{ + struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); + struct v4l2_subdev *sen_sd; + + sen_sd = mxc_get_remote_subdev(csi2dev, __func__); + if (!sen_sd) + return -EINVAL; + + return v4l2_subdev_call(sen_sd, core, try_ext_ctrls, ctrls); +} + +static int mipi_csi2_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls) +{ + struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); + struct v4l2_subdev *sen_sd; + + sen_sd = mxc_get_remote_subdev(csi2dev, __func__); + if (!sen_sd) + return -EINVAL; + + return v4l2_subdev_call(sen_sd, core, s_ext_ctrls, ctrls); +} +#endif + static int mipi_csi2_s_power(struct v4l2_subdev *sd, int on) { struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); @@ -952,6 +1039,15 @@ static struct v4l2_subdev_pad_ops mipi_csi2_pad_ops = { static struct v4l2_subdev_core_ops mipi_csi2_core_ops = { .s_power = mipi_csi2_s_power, +#ifdef CONFIG_VIDEO_ECAM + .queryctrl = mipi_csi2_queryctrl, + .g_ctrl = mipi_csi2_g_ctrl, + .s_ctrl = mipi_csi2_s_ctrl, + .g_ext_ctrls = mipi_csi2_g_ext_ctrls, + .s_ext_ctrls = mipi_csi2_s_ext_ctrls, + .try_ext_ctrls = mipi_csi2_try_ext_ctrls, + .querymenu = mipi_csi2_querymenu, +#endif }; static struct v4l2_subdev_video_ops mipi_csi2_video_ops = { |