[7/8] WmT: rcar_vin new ADV7612 support
Commit Message
Add 'struct media_pad pad' member and suitable glue code, so that
soc_camera/rcar_vin can become agnostic to whether an old or new-
style driver (wrt pad API use) can sit underneath
This version has been reworked to include appropriate constant and
datatype names for kernel v3.18
---
** this version for kernel 3.18.x+ (v4l2 constant names) **
** now including: **
| WmT: assume max resolution at init
|
| Make rcar_vin agnostic to the driver beneath having a smaller
| resolution as its default size. Previously, the logic for calculating
| cropping region size -which depends on going from larger to smaller
| values- would have been confused by this.
---
drivers/media/platform/soc_camera/rcar_vin.c | 112 +++++++++++++++++++++++---
1 file changed, 101 insertions(+), 11 deletions(-)
Comments
Hi Wills,
Same proposed wrappers could be used here.
Thanks
Guennadi
On Thu, 29 Jan 2015, William Towle wrote:
> Add 'struct media_pad pad' member and suitable glue code, so that
> soc_camera/rcar_vin can become agnostic to whether an old or new-
> style driver (wrt pad API use) can sit underneath
>
> This version has been reworked to include appropriate constant and
> datatype names for kernel v3.18
>
> ---
>
> ** this version for kernel 3.18.x+ (v4l2 constant names) **
> ** now including: **
> | WmT: assume max resolution at init
> |
> | Make rcar_vin agnostic to the driver beneath having a smaller
> | resolution as its default size. Previously, the logic for calculating
> | cropping region size -which depends on going from larger to smaller
> | values- would have been confused by this.
> ---
> drivers/media/platform/soc_camera/rcar_vin.c | 112 +++++++++++++++++++++++---
> 1 file changed, 101 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
> index e4f60d3..046fcc1 100644
> --- a/drivers/media/platform/soc_camera/rcar_vin.c
> +++ b/drivers/media/platform/soc_camera/rcar_vin.c
> @@ -932,9 +932,27 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
> u32 code;
> const struct soc_mbus_pixelfmt *fmt;
>
> - ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
> - if (ret < 0)
> - return 0;
> + // subdev_has_op -> enum_mbus_code vs enum_mbus_fmt
> + if (v4l2_subdev_has_op(sd, pad, enum_mbus_code)) {
> + struct v4l2_subdev_mbus_code_enum c;
> +
> + c.index = idx;
> +
> + ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &c);
> + if (ret < 0)
> + return 0;
> +
> +#if 1 /* ideal */
> + code = c.code;
> +#else /* Ian HACK - required with full(er) formats table */
> + code = MEDIA_BUS_FMT_RGB888_1X24; //HACK
> +#endif
> + }
> + else {
> + ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
> + if (ret < 0)
> + return 0;
> + }
>
> fmt = soc_mbus_get_fmtdesc(code);
> if (!fmt) {
> @@ -948,11 +966,28 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
>
> if (!icd->host_priv) {
> struct v4l2_mbus_framefmt mf;
> + struct v4l2_subdev_format sd_format;
> struct v4l2_rect rect;
> struct device *dev = icd->parent;
> int shift;
>
> - ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
> + // subdev_has_op -> get_fmt vs g_mbus_fmt
> + if (v4l2_subdev_has_op(sd, pad, get_fmt)) {
> + struct media_pad *remote_pad;
> +
> + remote_pad= media_entity_remote_pad(&icd->vdev->entity.pads[0]);
> + sd_format.pad= remote_pad->index;
> + sd_format.which=V4L2_SUBDEV_FORMAT_ACTIVE;
> +
> + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL,
> + &sd_format);
> + mf= sd_format.format;
> + mf.width= VIN_MAX_WIDTH;
> + mf.height= VIN_MAX_HEIGHT;
> + }
> + else {
> + ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
> + }
> if (ret < 0)
> return ret;
>
> @@ -979,10 +1014,18 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
>
> mf.width = 1280 >> shift;
> mf.height = 960 >> shift;
> - ret = v4l2_device_call_until_err(sd->v4l2_dev,
> - soc_camera_grp_id(icd),
> - video, s_mbus_fmt,
> - &mf);
> + // subdev_has_op -> set_fmt vs s_mbus_fmt
> + if (v4l2_subdev_has_op(sd, pad, set_fmt)) {
> + ret = v4l2_device_call_until_err(sd->v4l2_dev,
> + soc_camera_grp_id(icd),
> + pad, set_fmt, NULL,
> + &sd_format);
> + } else {
> + ret = v4l2_device_call_until_err(sd->v4l2_dev,
> + soc_camera_grp_id(icd),
> + video, s_mbus_fmt,
> + &mf);
> + }
> if (ret < 0)
> return ret;
> }
> @@ -1099,7 +1142,22 @@ static int rcar_vin_set_crop(struct soc_camera_device *icd,
> /* On success cam_crop contains current camera crop */
>
> /* Retrieve camera output window */
> - ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
> + // subdev_has_op -> get_fmt vs g_mbus_fmt
> + if (v4l2_subdev_has_op(sd, pad, get_fmt))
> + {
> + struct v4l2_subdev_format sd_format;
> + struct media_pad *remote_pad;
> +
> + remote_pad= media_entity_remote_pad(&icd->vdev->entity.pads[0]);
> + sd_format.pad= remote_pad->index;
> + sd_format.which= V4L2_SUBDEV_FORMAT_ACTIVE;
> + ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_format);
> +
> + mf.width= sd_format.format.width;
> + mf.height= sd_format.format.height;
> + } else {
> + ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
> + }
> if (ret < 0)
> return ret;
>
> @@ -1314,8 +1372,22 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
> mf.code = xlate->code;
> mf.colorspace = pix->colorspace;
>
> - ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
> + // subdev_has_op -> get_fmt vs try_mbus_fmt
> + if (v4l2_subdev_has_op(sd, pad, get_fmt)) {
> + struct v4l2_subdev_format sd_format;
> + struct media_pad *remote_pad;
> +
> + remote_pad= media_entity_remote_pad(
> + &icd->vdev->entity.pads[0]);
> + sd_format.pad= remote_pad->index;
> + sd_format.format= mf;
> + ret= v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
> + pad, get_fmt, NULL, &sd_format);
> + mf= sd_format.format;
> + } else {
> + ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
> video, try_mbus_fmt, &mf);
> + }
> if (ret < 0)
> return ret;
>
> @@ -1335,10 +1407,28 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
> */
> mf.width = VIN_MAX_WIDTH;
> mf.height = VIN_MAX_HEIGHT;
> - ret = v4l2_device_call_until_err(sd->v4l2_dev,
> + // subdev_has_op -> get_fmt vs try_mbus_fmt
> + if (v4l2_subdev_has_op(sd, pad, get_fmt)) {
> + struct v4l2_subdev_format sd_format;
> + struct media_pad *remote_pad;
> +
> + remote_pad= media_entity_remote_pad(
> + &icd->vdev->entity.pads[0]);
> + sd_format.pad = remote_pad->index;
> + sd_format.which= V4L2_SUBDEV_FORMAT_TRY;
> + sd_format.format= mf;
> + ret = v4l2_device_call_until_err(sd->v4l2_dev,
> + soc_camera_grp_id(icd),
> + pad, get_fmt,
> + NULL, &sd_format);
> + mf= sd_format.format;
> + } else {
> + ret = v4l2_device_call_until_err(sd->v4l2_dev,
> soc_camera_grp_id(icd),
> video, try_mbus_fmt,
> &mf);
> + }
> +
> if (ret < 0) {
> dev_err(icd->parent,
> "client try_fmt() = %d\n", ret);
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
@@ -932,9 +932,27 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
u32 code;
const struct soc_mbus_pixelfmt *fmt;
- ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
- if (ret < 0)
- return 0;
+ // subdev_has_op -> enum_mbus_code vs enum_mbus_fmt
+ if (v4l2_subdev_has_op(sd, pad, enum_mbus_code)) {
+ struct v4l2_subdev_mbus_code_enum c;
+
+ c.index = idx;
+
+ ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &c);
+ if (ret < 0)
+ return 0;
+
+#if 1 /* ideal */
+ code = c.code;
+#else /* Ian HACK - required with full(er) formats table */
+ code = MEDIA_BUS_FMT_RGB888_1X24; //HACK
+#endif
+ }
+ else {
+ ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
+ if (ret < 0)
+ return 0;
+ }
fmt = soc_mbus_get_fmtdesc(code);
if (!fmt) {
@@ -948,11 +966,28 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
if (!icd->host_priv) {
struct v4l2_mbus_framefmt mf;
+ struct v4l2_subdev_format sd_format;
struct v4l2_rect rect;
struct device *dev = icd->parent;
int shift;
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
+ // subdev_has_op -> get_fmt vs g_mbus_fmt
+ if (v4l2_subdev_has_op(sd, pad, get_fmt)) {
+ struct media_pad *remote_pad;
+
+ remote_pad= media_entity_remote_pad(&icd->vdev->entity.pads[0]);
+ sd_format.pad= remote_pad->index;
+ sd_format.which=V4L2_SUBDEV_FORMAT_ACTIVE;
+
+ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL,
+ &sd_format);
+ mf= sd_format.format;
+ mf.width= VIN_MAX_WIDTH;
+ mf.height= VIN_MAX_HEIGHT;
+ }
+ else {
+ ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
+ }
if (ret < 0)
return ret;
@@ -979,10 +1014,18 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
mf.width = 1280 >> shift;
mf.height = 960 >> shift;
- ret = v4l2_device_call_until_err(sd->v4l2_dev,
- soc_camera_grp_id(icd),
- video, s_mbus_fmt,
- &mf);
+ // subdev_has_op -> set_fmt vs s_mbus_fmt
+ if (v4l2_subdev_has_op(sd, pad, set_fmt)) {
+ ret = v4l2_device_call_until_err(sd->v4l2_dev,
+ soc_camera_grp_id(icd),
+ pad, set_fmt, NULL,
+ &sd_format);
+ } else {
+ ret = v4l2_device_call_until_err(sd->v4l2_dev,
+ soc_camera_grp_id(icd),
+ video, s_mbus_fmt,
+ &mf);
+ }
if (ret < 0)
return ret;
}
@@ -1099,7 +1142,22 @@ static int rcar_vin_set_crop(struct soc_camera_device *icd,
/* On success cam_crop contains current camera crop */
/* Retrieve camera output window */
- ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
+ // subdev_has_op -> get_fmt vs g_mbus_fmt
+ if (v4l2_subdev_has_op(sd, pad, get_fmt))
+ {
+ struct v4l2_subdev_format sd_format;
+ struct media_pad *remote_pad;
+
+ remote_pad= media_entity_remote_pad(&icd->vdev->entity.pads[0]);
+ sd_format.pad= remote_pad->index;
+ sd_format.which= V4L2_SUBDEV_FORMAT_ACTIVE;
+ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_format);
+
+ mf.width= sd_format.format.width;
+ mf.height= sd_format.format.height;
+ } else {
+ ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
+ }
if (ret < 0)
return ret;
@@ -1314,8 +1372,22 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
mf.code = xlate->code;
mf.colorspace = pix->colorspace;
- ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
+ // subdev_has_op -> get_fmt vs try_mbus_fmt
+ if (v4l2_subdev_has_op(sd, pad, get_fmt)) {
+ struct v4l2_subdev_format sd_format;
+ struct media_pad *remote_pad;
+
+ remote_pad= media_entity_remote_pad(
+ &icd->vdev->entity.pads[0]);
+ sd_format.pad= remote_pad->index;
+ sd_format.format= mf;
+ ret= v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
+ pad, get_fmt, NULL, &sd_format);
+ mf= sd_format.format;
+ } else {
+ ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
video, try_mbus_fmt, &mf);
+ }
if (ret < 0)
return ret;
@@ -1335,10 +1407,28 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
*/
mf.width = VIN_MAX_WIDTH;
mf.height = VIN_MAX_HEIGHT;
- ret = v4l2_device_call_until_err(sd->v4l2_dev,
+ // subdev_has_op -> get_fmt vs try_mbus_fmt
+ if (v4l2_subdev_has_op(sd, pad, get_fmt)) {
+ struct v4l2_subdev_format sd_format;
+ struct media_pad *remote_pad;
+
+ remote_pad= media_entity_remote_pad(
+ &icd->vdev->entity.pads[0]);
+ sd_format.pad = remote_pad->index;
+ sd_format.which= V4L2_SUBDEV_FORMAT_TRY;
+ sd_format.format= mf;
+ ret = v4l2_device_call_until_err(sd->v4l2_dev,
+ soc_camera_grp_id(icd),
+ pad, get_fmt,
+ NULL, &sd_format);
+ mf= sd_format.format;
+ } else {
+ ret = v4l2_device_call_until_err(sd->v4l2_dev,
soc_camera_grp_id(icd),
video, try_mbus_fmt,
&mf);
+ }
+
if (ret < 0) {
dev_err(icd->parent,
"client try_fmt() = %d\n", ret);