diff options
author | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2020-07-07 14:51:49 +0200 |
---|---|---|
committer | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2020-07-09 18:23:22 +0200 |
commit | 1554f7c30bb7b28ef36fa7b5b77c547edb1ba030 (patch) | |
tree | 9d80e52c390a18e25bbcdf0a3dc3869de5ecc98c /drivers/media/platform/imx8/mxc-mipi-csi2.c | |
parent | 70115fee222012ca7c7ce796d772cac596b0927b (diff) |
imx8: isi: ar0521: add initial driver
Add initial driver for the e-con Systems e-CAM50_CUIMX8.
This is the driver part from the following patch we got from Yogaesh <yogaesh@e-consystems.com> on
May 8, 2020:
apalis_imx8qm_embedded_linux_eCAM50_support.patch
Related-to: ELB-2793
Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
Diffstat (limited to 'drivers/media/platform/imx8/mxc-mipi-csi2.c')
-rw-r--r-- | drivers/media/platform/imx8/mxc-mipi-csi2.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/drivers/media/platform/imx8/mxc-mipi-csi2.c b/drivers/media/platform/imx8/mxc-mipi-csi2.c index aaa0e638800a..fc38dfda0db4 100644 --- a/drivers/media/platform/imx8/mxc-mipi-csi2.c +++ b/drivers/media/platform/imx8/mxc-mipi-csi2.c @@ -435,6 +435,158 @@ 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 media_pad *source_pad; + struct v4l2_subdev *sen_sd; + + source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev); + if (source_pad == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__); + return -EINVAL; + } + + /* Get remote source pad subdev */ + sen_sd = media_entity_to_v4l2_subdev(source_pad->entity); + if (sen_sd == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__); + 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 media_pad *source_pad; + struct v4l2_subdev *sen_sd; + + source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev); + if (source_pad == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__); + return -EINVAL; + } + + /* Get remote source pad subdev */ + sen_sd = media_entity_to_v4l2_subdev(source_pad->entity); + if (sen_sd == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__); + 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 media_pad *source_pad; + struct v4l2_subdev *sen_sd; + + source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev); + if (source_pad == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__); + return -EINVAL; + } + + /* Get remote source pad subdev */ + sen_sd = media_entity_to_v4l2_subdev(source_pad->entity); + if (sen_sd == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__); + 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 media_pad *source_pad; + struct v4l2_subdev *sen_sd; + + source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev); + if (source_pad == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__); + return -EINVAL; + } + + /* Get remote source pad subdev */ + sen_sd = media_entity_to_v4l2_subdev(source_pad->entity); + if (sen_sd == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__); + 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 media_pad *source_pad; + struct v4l2_subdev *sen_sd; + + source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev); + if (source_pad == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__); + return -EINVAL; + } + + /* Get remote source pad subdev */ + sen_sd = media_entity_to_v4l2_subdev(source_pad->entity); + if (sen_sd == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__); + 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 media_pad *source_pad; + struct v4l2_subdev *sen_sd; + + source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev); + if (source_pad == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__); + return -EINVAL; + } + + /* Get remote source pad subdev */ + sen_sd = media_entity_to_v4l2_subdev(source_pad->entity); + if (sen_sd == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__); + 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 media_pad *source_pad; + struct v4l2_subdev *sen_sd; + + source_pad = mxc_csi2_get_remote_sensor_pad(csi2dev); + if (source_pad == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote pad found!\n", __func__); + return -EINVAL; + } + + /* Get remote source pad subdev */ + sen_sd = media_entity_to_v4l2_subdev(source_pad->entity); + if (sen_sd == NULL) { + v4l2_err(&csi2dev->v4l2_dev, "%s, No remote subdev found!\n", __func__); + 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); @@ -643,6 +795,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 = { |