diff options
Diffstat (limited to 'drivers/media/platform')
-rw-r--r-- | drivers/media/platform/imx8/max9286.h | 2 | ||||
-rw-r--r-- | drivers/media/platform/imx8/mxc-mipi-csi2.c | 118 |
2 files changed, 118 insertions, 2 deletions
diff --git a/drivers/media/platform/imx8/max9286.h b/drivers/media/platform/imx8/max9286.h index 8688b869e45a..6acfee73ce41 100644 --- a/drivers/media/platform/imx8/max9286.h +++ b/drivers/media/platform/imx8/max9286.h @@ -17,7 +17,7 @@ #define MIPI_CSI2_SENS_VCX_PADS_NUM 4 #define MAX_FPS 30 -#define MIN_FPS 15 +#define MIN_FPS 30 #define DEFAULT_FPS 30 /*! diff --git a/drivers/media/platform/imx8/mxc-mipi-csi2.c b/drivers/media/platform/imx8/mxc-mipi-csi2.c index 70481fc4df1f..8d875a4b4aae 100644 --- a/drivers/media/platform/imx8/mxc-mipi-csi2.c +++ b/drivers/media/platform/imx8/mxc-mipi-csi2.c @@ -434,7 +434,69 @@ static const struct media_entity_operations mipi_csi2_sd_media_ops = { */ static int mipi_csi2_s_power(struct v4l2_subdev *sd, int on) { - return 0; + struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); + struct media_pad *source_pad; + struct v4l2_subdev *sen_sd; + + /* Get remote source pad */ + 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_power, on); +} + +static int mipi_csi2_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) +{ + struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); + struct media_pad *source_pad; + struct v4l2_subdev *sen_sd; + + /* Get remote source pad */ + 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, video, s_parm, a); +} + +static int mipi_csi2_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) +{ + struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); + struct media_pad *source_pad; + struct v4l2_subdev *sen_sd; + + /* Get remote source pad */ + 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, video, g_parm, a); } static int mipi_csi2_s_stream(struct v4l2_subdev *sd, int enable) @@ -468,6 +530,56 @@ static int mipi_csi2_s_stream(struct v4l2_subdev *sd, int enable) return ret; } +static int mipi_csi2_enum_framesizes(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); + struct media_pad *source_pad; + struct v4l2_subdev *sen_sd; + + /* Get remote source pad */ + 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, pad, enum_frame_size, NULL, fse); +} + +static int mipi_csi2_enum_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_interval_enum *fie) +{ + struct mxc_mipi_csi2_dev *csi2dev = sd_to_mxc_mipi_csi2_dev(sd); + struct media_pad *source_pad; + struct v4l2_subdev *sen_sd; + + /* Get remote source pad */ + 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(sd, pad, enum_frame_interval, NULL, fie); +} + static int mipi_csi2_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) @@ -495,6 +607,8 @@ static const struct v4l2_subdev_internal_ops mipi_csi2_sd_internal_ops = { }; static struct v4l2_subdev_pad_ops mipi_csi2_pad_ops = { + .enum_frame_size = mipi_csi2_enum_framesizes, + .enum_frame_interval = mipi_csi2_enum_frame_interval, .get_fmt = mipi_csi2_get_fmt, .set_fmt = mipi_csi2_set_fmt, }; @@ -504,6 +618,8 @@ static struct v4l2_subdev_core_ops mipi_csi2_core_ops = { }; static struct v4l2_subdev_video_ops mipi_csi2_video_ops = { + .s_parm = mipi_csi2_s_parm, + .g_parm = mipi_csi2_g_parm, .s_stream = mipi_csi2_s_stream, }; |