Re: [PATCH v4 19/27] rcar-vin: use different v4l2 operations in media controller mode

2017-05-04 Thread Sakari Ailus
Hi Niklas,

On Fri, Apr 28, 2017 at 12:41:55AM +0200, Niklas Söderlund wrote:
> When the driver runs in media controller mode it should not directly
> control the subdevice instead userspace will be responsible for
> configuring the pipeline. To be able to run in this mode a different set
> of v4l2 operations needs to be used.
> 
> Add a new set of v4l2 operations to support the running without directly
> interacting with the source subdevice.
> 
> Signed-off-by: Niklas Söderlund 
> ---
>  drivers/media/platform/rcar-vin/rcar-core.c |  25 ++-
>  drivers/media/platform/rcar-vin/rcar-dma.c  |   3 +-
>  drivers/media/platform/rcar-vin/rcar-v4l2.c | 239 
> 
>  drivers/media/platform/rcar-vin/rcar-vin.h  |   3 +
>  4 files changed, 268 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
> b/drivers/media/platform/rcar-vin/rcar-core.c
> index 8b30d8d3ec7d9c04..7aaa01dee014d64b 100644
> --- a/drivers/media/platform/rcar-vin/rcar-core.c
> +++ b/drivers/media/platform/rcar-vin/rcar-core.c
> @@ -256,6 +256,21 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
>  }
>  
>  /* 
> -
> + * Group async notifier
> + */
> +
> +static int rvin_group_init(struct rvin_dev *vin)
> +{
> + int ret;
> +
> + ret = rvin_v4l2_mc_probe(vin);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> +/* 
> -
>   * Platform Device Driver
>   */
>  
> @@ -347,7 +362,10 @@ static int rcar_vin_probe(struct platform_device *pdev)
>   if (ret)
>   return ret;
>  
> - ret = rvin_digital_graph_init(vin);
> + if (vin->info->use_mc)
> + ret = rvin_group_init(vin);
> + else
> + ret = rvin_digital_graph_init(vin);
>   if (ret < 0)
>   goto error;
>  
> @@ -371,6 +389,11 @@ static int rcar_vin_remove(struct platform_device *pdev)
>  
>   v4l2_async_notifier_unregister(>notifier);
>  
> + if (vin->info->use_mc)
> + rvin_v4l2_mc_remove(vin);
> + else
> + rvin_v4l2_remove(vin);
> +
>   rvin_dma_remove(vin);
>  
>   return 0;
> diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
> b/drivers/media/platform/rcar-vin/rcar-dma.c
> index fef31aac0ed40979..34f01f32bab7bd32 100644
> --- a/drivers/media/platform/rcar-vin/rcar-dma.c
> +++ b/drivers/media/platform/rcar-vin/rcar-dma.c
> @@ -628,7 +628,8 @@ static int rvin_setup(struct rvin_dev *vin)
>   /* Default to TB */
>   vnmc = VNMC_IM_FULL;
>   /* Use BT if video standard can be read and is 60 Hz format */
> - if (!v4l2_subdev_call(vin_to_source(vin), video, g_std, )) {
> + if (!vin->info->use_mc &&
> + !v4l2_subdev_call(vin_to_source(vin), video, g_std, )) {
>   if (std & V4L2_STD_525_60)
>   vnmc = VNMC_IM_FULL | VNMC_FOC;
>   }
> diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
> b/drivers/media/platform/rcar-vin/rcar-v4l2.c
> index 1ee9dcb621350f77..ae6910ac87ec7f6a 100644
> --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
> +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
> @@ -23,6 +23,9 @@
>  #include "rcar-vin.h"
>  
>  #define RVIN_DEFAULT_FORMAT  V4L2_PIX_FMT_YUYV
> +#define RVIN_DEFAULT_WIDTH   800
> +#define RVIN_DEFAULT_HEIGHT  600
> +#define RVIN_DEFAULT_COLORSPACE  V4L2_COLORSPACE_SRGB
>  
>  /* 
> -
>   * Format Conversions
> @@ -694,6 +697,126 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = {
>  };
>  
>  /* 
> -
> + * V4L2 Media Controller
> + */
> +
> +static int __rvin_mc_try_format(struct rvin_dev *vin,
> + struct v4l2_pix_format *pix)
> +{
> + const struct rvin_video_format *info;
> + u32 walign;
> +
> + /* Keep current field if no specific one is asked for */
> + if (pix->field == V4L2_FIELD_ANY)
> + pix->field = vin->format.field;
> +
> + switch (pix->field) {
> + case V4L2_FIELD_TOP:
> + case V4L2_FIELD_BOTTOM:
> + case V4L2_FIELD_ALTERNATE:
> + case V4L2_FIELD_NONE:
> + case V4L2_FIELD_INTERLACED_TB:
> + case V4L2_FIELD_INTERLACED_BT:
> + case V4L2_FIELD_INTERLACED:
> + break;
> + default:
> + pix->field = V4L2_FIELD_NONE;
> + break;
> + }
> +
> + /* Check that colorspace is resonable, if not keep current */
> + if (!pix->colorspace || pix->colorspace >= 0xff)
> + pix->colorspace = vin->format.colorspace;
> +
> + info = rvin_format_from_pixel(pix->pixelformat);
> + if (!info) {
> + vin_dbg(vin, 

[PATCH v4 19/27] rcar-vin: use different v4l2 operations in media controller mode

2017-04-27 Thread Niklas Söderlund
When the driver runs in media controller mode it should not directly
control the subdevice instead userspace will be responsible for
configuring the pipeline. To be able to run in this mode a different set
of v4l2 operations needs to be used.

Add a new set of v4l2 operations to support the running without directly
interacting with the source subdevice.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-core.c |  25 ++-
 drivers/media/platform/rcar-vin/rcar-dma.c  |   3 +-
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 239 
 drivers/media/platform/rcar-vin/rcar-vin.h  |   3 +
 4 files changed, 268 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 8b30d8d3ec7d9c04..7aaa01dee014d64b 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -256,6 +256,21 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 }
 
 /* 
-
+ * Group async notifier
+ */
+
+static int rvin_group_init(struct rvin_dev *vin)
+{
+   int ret;
+
+   ret = rvin_v4l2_mc_probe(vin);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
+/* 
-
  * Platform Device Driver
  */
 
@@ -347,7 +362,10 @@ static int rcar_vin_probe(struct platform_device *pdev)
if (ret)
return ret;
 
-   ret = rvin_digital_graph_init(vin);
+   if (vin->info->use_mc)
+   ret = rvin_group_init(vin);
+   else
+   ret = rvin_digital_graph_init(vin);
if (ret < 0)
goto error;
 
@@ -371,6 +389,11 @@ static int rcar_vin_remove(struct platform_device *pdev)
 
v4l2_async_notifier_unregister(>notifier);
 
+   if (vin->info->use_mc)
+   rvin_v4l2_mc_remove(vin);
+   else
+   rvin_v4l2_remove(vin);
+
rvin_dma_remove(vin);
 
return 0;
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index fef31aac0ed40979..34f01f32bab7bd32 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -628,7 +628,8 @@ static int rvin_setup(struct rvin_dev *vin)
/* Default to TB */
vnmc = VNMC_IM_FULL;
/* Use BT if video standard can be read and is 60 Hz format */
-   if (!v4l2_subdev_call(vin_to_source(vin), video, g_std, )) {
+   if (!vin->info->use_mc &&
+   !v4l2_subdev_call(vin_to_source(vin), video, g_std, )) {
if (std & V4L2_STD_525_60)
vnmc = VNMC_IM_FULL | VNMC_FOC;
}
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 1ee9dcb621350f77..ae6910ac87ec7f6a 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -23,6 +23,9 @@
 #include "rcar-vin.h"
 
 #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV
+#define RVIN_DEFAULT_WIDTH 800
+#define RVIN_DEFAULT_HEIGHT600
+#define RVIN_DEFAULT_COLORSPACEV4L2_COLORSPACE_SRGB
 
 /* 
-
  * Format Conversions
@@ -694,6 +697,126 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = {
 };
 
 /* 
-
+ * V4L2 Media Controller
+ */
+
+static int __rvin_mc_try_format(struct rvin_dev *vin,
+   struct v4l2_pix_format *pix)
+{
+   const struct rvin_video_format *info;
+   u32 walign;
+
+   /* Keep current field if no specific one is asked for */
+   if (pix->field == V4L2_FIELD_ANY)
+   pix->field = vin->format.field;
+
+   switch (pix->field) {
+   case V4L2_FIELD_TOP:
+   case V4L2_FIELD_BOTTOM:
+   case V4L2_FIELD_ALTERNATE:
+   case V4L2_FIELD_NONE:
+   case V4L2_FIELD_INTERLACED_TB:
+   case V4L2_FIELD_INTERLACED_BT:
+   case V4L2_FIELD_INTERLACED:
+   break;
+   default:
+   pix->field = V4L2_FIELD_NONE;
+   break;
+   }
+
+   /* Check that colorspace is resonable, if not keep current */
+   if (!pix->colorspace || pix->colorspace >= 0xff)
+   pix->colorspace = vin->format.colorspace;
+
+   info = rvin_format_from_pixel(pix->pixelformat);
+   if (!info) {
+   vin_dbg(vin, "Format %x not found, keeping %x\n",
+   pix->pixelformat, vin->format.pixelformat);
+   pix->pixelformat = vin->format.pixelformat;
+   info = rvin_format_from_pixel(pix->pixelformat);
+   }
+
+