All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: William Towle <william.towle@codethink.co.uk>,
	linux-kernel@lists.codethink.co.uk,
	Linux Media Mailing List <linux-media@vger.kernel.org>,
	Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>,
	Hans Verkuil <hverkuil@xs4all.nl>
Subject: Re: [PATCH 6/8] WmT: adv7604 driver compatibility
Date: Mon, 02 Feb 2015 12:01:05 +0200	[thread overview]
Message-ID: <2552213.h99FiuUI04@avalon> (raw)
In-Reply-To: <Pine.LNX.4.64.1502011216460.9534@axis700.grange>

Hi Guennadi,

On Sunday 01 February 2015 12:26:11 Guennadi Liakhovetski wrote:
> On a second thought:
> 
> On Sun, 1 Feb 2015, Guennadi Liakhovetski wrote:
> > Hi Wills,
> > 
> > Thanks for the patch. First and foremost, the title of the patch is wrong.
> > This patch does more than just adding some "adv7604 compatibility." It's
> > adding pad-level API to soc-camera.
> > 
> > This is just a rough review. I'm not an expert in media-controller /
> > pad-level API, I hope someone with a better knowledge of those areas will
> > help me reviewing this.
> > 
> > Another general comment: it has been discussed since a long time, whether
> > a wrapper wouldn't be desired to enable a seamless use of both subdev
> > drivers using and not using the pad-level API. Maybe it's the right time
> > now?..
> 
> This would be a considerable change and would most probably take a rather
> long time, given how busy everyone is.

If I understood correctly Hans Verkuil told me over the weekend that he wanted 
to address this problem in the near future. Hans, could you detail your plans 
?

> I personally would be fine with a (yet another) intermittent solution,
> whereby we create a soc_camera_subdev.c file, in which we collect all those
> function to call either a video or a pad subdev operation, depending on
> whether the latter is available. E.g.
> 
> int soc_camera_sd_enum_mbus_fmt(sd, code)
> {
> 	int ret;
> 
> 	if (v4l2_subdev_has_op(sd, pad, enum_mbus_code)) {
> 		ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, code);
> 	} else {
> 		u32 pixcode;
> 
> 		ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, code->index, 
&pixcode);
> 		if (!ret)
> 			code->code= pixcode;
> 	}
> 
> 	return ret;
> }
> 
> Similarly for other ops.
> 
> 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
> > > ---
> > > 
> > >  drivers/media/platform/soc_camera/soc_camera.c     |  148
> > >  +++++++++++++++++++-
> > >  drivers/media/platform/soc_camera/soc_scale_crop.c |   43 +++++-
> > >  include/media/soc_camera.h                         |    1 +
> > >  3 files changed, 182 insertions(+), 10 deletions(-)
> > > 
> > > diff --git a/drivers/media/platform/soc_camera/soc_camera.c
> > > b/drivers/media/platform/soc_camera/soc_camera.c index f4be2a1..efc20bf
> > > 100644
> > > --- a/drivers/media/platform/soc_camera/soc_camera.c
> > > +++ b/drivers/media/platform/soc_camera/soc_camera.c
> > > @@ -37,8 +37,11 @@
> > > 
> > >  #include <media/v4l2-ioctl.h>
> > >  #include <media/v4l2-dev.h>
> > >  #include <media/v4l2-of.h>
> > > 
> > > +#if 0
> > > 
> > >  #include <media/videobuf-core.h>
> > >  #include <media/videobuf2-core.h>
> > > 
> > > +#endif
> > 
> > No. These headers are needed even if the code can be compiled without
> > them.
> > 
> > > +#include <media/v4l2-mediabus.h>
> > 
> > Well, maybe. This header is included indirectly via soc_mediabus.h, but
> > yes, as I just said above, headers, whose defines, structs etc. are used,
> > should be encluded directly. Further, you'll need more headers, e.g.
> > media-entity.h, maybe some more.
> > 
> > >  /* Default to VGA resolution */
> > >  #define DEFAULT_WIDTH	640
> > > 
> > > @@ -453,6 +456,98 @@ static int soc_camera_expbuf(struct file *file,
> > > void *priv,> > 
> > >  		return vb2_expbuf(&icd->vb2_vidq, p);
> > >  
> > >  }
> > > 
> > > +static int soc_camera_init_user_formats_pad(struct soc_camera_device
> > > *icd, int src_pad_idx) +{
> > > +	struct v4l2_subdev *sd= soc_camera_to_subdev(icd);
> > > +	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
> > > +	struct v4l2_subdev_mbus_code_enum code;
> > > +	int fmts= 0, raw_fmts, i, ret;
> > 
> > Please, run this patch through checkpatch.pl. It will tell you to add a
> > Signed-off-by line, (hopefully) to add spaces before "=" in multiple
> > places, to place braces correctly, to not use C++-style comments etc. Only
> > feel free to ignore 80-character warnings.
> > 
> > > +
> > > +	code.pad= src_pad_idx;
> > > +	code.index= 0;
> > > +
> > > +	// subdev_has_op -> enum_mbus_code vs enum_mbus_fmt
> > > +	if (v4l2_subdev_has_op(sd, pad, enum_mbus_code)) {
> > 
> > This function is called only once below and only after the above test has
> > already returned success. Looks like you don't need it here again and the
> > below "else" branch can be dropped completely?
> > 
> > > +		while (!v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code))
> > > +			code.index++;
> > > +	} else {
> > > +		u32 pixcode;
> > > +
> > > +		while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, code.index,
> > > &pixcode)) +		{
> > > +			code.code= pixcode;
> > > +			code.index++;
> > > +		}
> > > +	}
> > > +	raw_fmts= code.index;
> > > +
> > > +	if (!ici->ops->get_formats) {
> > > +		/*
> > > +		 * Fallback mode - the host will have to serve all
> > > +		 * sensor-provided formats one-to-one to the user
> > > +		 */
> > > +		fmts = raw_fmts;
> > > +	}
> > > +	else {
> > > +		/*
> > > +		 * First pass - only count formats this host-sensor
> > > +		 * configuration can provide
> > > +		 */
> > > +		for (i = 0; i < raw_fmts; i++) {
> > > +			int ret = ici->ops->get_formats(icd, i, NULL);
> > > +			if (ret < 0)
> > > +				return ret;
> > > +			fmts += ret;
> > > +		}
> > > +	}
> > > +
> > > +	if (!fmts)
> > > +		return -ENXIO;
> > > +
> > > +	icd->user_formats =
> > > +		vmalloc(fmts * sizeof(struct soc_camera_format_xlate));
> > > +	if (!icd->user_formats)
> > > +		return -ENOMEM;
> > > +
> > > +	dev_dbg(icd->pdev, "Found %d supported formats.\n", fmts);
> > > +
> > > +	/* Second pass - actually fill data formats */
> > > +	fmts = 0;
> > > +	for (i = 0; i < raw_fmts; i++) {
> > > +		if (!ici->ops->get_formats) {
> > > +			code.index= i;
> > > +			// subdev_has_op -> enum_mbus_code vs enum_mbus_fmt
> > > +			if (v4l2_subdev_has_op(sd, pad, enum_mbus_code)) {
> > 
> > Same test again?? Or am I missing something? If indeed these tests are
> > redundant, after you remove them this function will become very similar to
> > the original soc_camera_init_user_formats(), so, maybe some code reuse
> > will become possible.
> > 
> > > +				v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
> > > +			} else {
> > > +				u32 pixcode;
> > > +
> > > +				v4l2_subdev_call(sd, video, enum_mbus_fmt, code.index, 
&pixcode);
> > > +				code.code= pixcode;
> > > +			}
> > > +			icd->user_formats[fmts].host_fmt =
> > > +				soc_mbus_get_fmtdesc(code.code);
> > > +			if (icd->user_formats[fmts].host_fmt)
> > > +				icd->user_formats[fmts++].code = code.code;
> > > +		} else {
> > > +			ret = ici->ops->get_formats(icd, i,
> > > +						    &icd->user_formats[fmts]);
> > > +			if (ret < 0)
> > > +				goto egfmt;
> > > +			fmts += ret;
> > > +		}
> > > +	}
> > > +
> > > +	icd->num_user_formats = fmts;
> > > +	icd->current_fmt = &icd->user_formats[0];
> > > +
> > > +	return 0;
> > > +
> > > +egfmt:
> > > +	vfree(icd->user_formats);
> > > +	return ret;
> > > +}
> > > +
> > > 
> > >  /* Always entered with .host_lock held */
> > >  static int soc_camera_init_user_formats(struct soc_camera_device *icd)
> > >  {
> > > 
> > > @@ -1289,6 +1384,7 @@ static int soc_camera_probe_finish(struct
> > > soc_camera_device *icd)> > 
> > >  {
> > >  
> > >  	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
> > >  	struct v4l2_mbus_framefmt mf;
> > > 
> > > +	int src_pad_idx= -1;
> > > 
> > >  	int ret;
> > >  	
> > >  	sd->grp_id = soc_camera_grp_id(icd);
> > > 
> > > @@ -1307,7 +1403,30 @@ static int soc_camera_probe_finish(struct
> > > soc_camera_device *icd)> > 
> > >  	}
> > >  	
> > >  	/* At this point client .probe() should have run already */
> > > 
> > > -	ret = soc_camera_init_user_formats(icd);
> > > +	// subdev_has_op -> enum_mbus_code vs enum_mbus_fmt
> > > +	if (!v4l2_subdev_has_op(sd, pad, enum_mbus_code))
> > 
> > This is the test, that I meant above.
> > 
> > > +		ret = soc_camera_init_user_formats(icd);
> > > +	else {
> > > +		ret = media_entity_init(&icd->vdev->entity, 1,
> > > +					&icd->pad, 0);
> > 
> > Ok, maybe this hard-coded 1 pad with no extras is justified here, but
> > let's here what others say.
> > 
> > > +		if (!ret) {
> > > +			for (src_pad_idx= 0; src_pad_idx < sd->entity.num_pads;
> > > src_pad_idx++)
> > > +				if (sd->entity.pads[src_pad_idx].flags == 
MEDIA_PAD_FL_SOURCE)
> > > +					break;
> > > +
> > > +			if (src_pad_idx < sd->entity.num_pads) {
> > > +				ret = media_entity_create_link(
> > > +					&icd->vdev->entity, 0,
> > > +					&sd->entity, src_pad_idx,
> > > +					MEDIA_LNK_FL_IMMUTABLE |
> > > +					MEDIA_LNK_FL_ENABLED);
> > 
> > Let's try to preserve the style. I normally try to avoid splitting the
> > line after "f(" and adding at least the first function parameter above
> > will not make that line longer, than the ones above. So, let's do that.
> > 
> > > +			}
> > > +		}
> > > +
> > > +		if (!ret)
> > > +			ret = soc_camera_init_user_formats_pad(icd,
> > > +							src_pad_idx);
> > 
> > Probably no need to break the line here either.
> > 
> > > +	}
> > > 
> > >  	if (ret < 0)
> > >  	
> > >  		goto eusrfmt;
> > > 
> > > @@ -1318,11 +1437,28 @@ static int soc_camera_probe_finish(struct
> > > soc_camera_device *icd)> > 
> > >  		goto evidstart;
> > >  	
> > >  	/* Try to improve our guess of a reasonable window format */
> > > 
> > > -	if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
> > > -		icd->user_width		= mf.width;
> > > -		icd->user_height	= mf.height;
> > > -		icd->colorspace		= mf.colorspace;
> > > -		icd->field		= mf.field;
> > > +	// subdev_has_op -> get_fmt vs g_mbus_fmt
> > > +	if (v4l2_subdev_has_op(sd, pad, enum_mbus_code)
> > > +		&& v4l2_subdev_has_op(sd, pad, get_fmt)
> > > +		&& src_pad_idx != -1) {
> > 
> > The rest of the file puts operations after the first argument, not before
> > the second one when breaking the line. Let's do that here too.
> > 
> > Thanks
> > Guennadi
> > 
> > > +		struct v4l2_subdev_format sd_format;
> > > +
> > > +		sd_format.pad= src_pad_idx;
> > > +		sd_format.which= V4L2_SUBDEV_FORMAT_ACTIVE;
> > > +
> > > +		if (!v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_format)) {
> > > +			icd->user_width		= sd_format.format.width;
> > > +			icd->user_height	= sd_format.format.height;
> > > +			icd->colorspace		= sd_format.format.colorspace;
> > > +			icd->field		= sd_format.format.field;
> > > +		}
> > > +	} else {
> > > +		if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
> > > +			icd->user_width		= mf.width;
> > > +			icd->user_height	= mf.height;
> > > +			icd->colorspace		= mf.colorspace;
> > > +			icd->field		= mf.field;
> > > +		}
> > > 
> > >  	}
> > >  	soc_camera_remove_device(icd);
> > > 
> > > diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c
> > > b/drivers/media/platform/soc_camera/soc_scale_crop.c index
> > > 8e74fb7..8a1ca05 100644
> > > --- a/drivers/media/platform/soc_camera/soc_scale_crop.c
> > > +++ b/drivers/media/platform/soc_camera/soc_scale_crop.c
> > > @@ -224,9 +224,27 @@ static int client_s_fmt(struct soc_camera_device
> > > *icd,
> > > 
> > >  	bool host_1to1;
> > >  	int ret;
> > > 
> > > -	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)) {
> > > +		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;
> > > +		sd_format.format= *mf;
> > > +
> > > +		ret = v4l2_device_call_until_err(sd->v4l2_dev,
> > > +			soc_camera_grp_id(icd), pad, set_fmt, NULL,
> > > +			&sd_format);
> > > +
> > > +		mf->width = sd_format.format.width;
> > > +		mf->height = sd_format.format.height;
> > > +	} 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;
> > > 
> > > @@ -264,9 +282,26 @@ static int client_s_fmt(struct soc_camera_device
> > > *icd,
> > > 
> > >  		tmp_h = min(2 * tmp_h, max_height);
> > >  		mf->width = tmp_w;
> > >  		mf->height = tmp_h;
> > > 
> > > -		ret = v4l2_device_call_until_err(sd->v4l2_dev,
> > > +		// subdev_has_op -> set_fmt vs s_mbus_fmt
> > > +		if (v4l2_subdev_has_op(sd, pad, set_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;
> > > +			sd_format.format= *mf;
> > > +
> > > +			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);
> > > 
> > > +		}
> > > 
> > >  		dev_geo(dev, "Camera scaled to %ux%u\n",
> > >  		
> > >  			mf->width, mf->height);
> > >  		
> > >  		if (ret < 0) {
> > > 
> > > diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
> > > index 2f6261f..f0c5238 100644
> > > --- a/include/media/soc_camera.h
> > > +++ b/include/media/soc_camera.h
> > > @@ -42,6 +42,7 @@ struct soc_camera_device {
> > > 
> > >  	unsigned char devnum;		/* Device number per host */
> > >  	struct soc_camera_sense *sense;	/* See comment in struct definition 
*/
> > >  	struct video_device *vdev;
> > > 
> > > +	struct media_pad pad;
> > > 
> > >  	struct v4l2_ctrl_handler ctrl_handler;
> > >  	const struct soc_camera_format_xlate *current_fmt;
> > >  	struct soc_camera_format_xlate *user_formats;

-- 
Regards,

Laurent Pinchart


  reply	other threads:[~2015-02-02 10:00 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-29 16:19 RFC: supporting adv7604.c under soc_camera/rcar_vin William Towle
2015-01-29 16:19 ` [PATCH 1/8] Add ability to read default input port from DT William Towle
2015-01-29 20:19   ` Jean-Michel Hautbois
2015-01-29 16:19 ` [PATCH 2/8] adv7604.c: formats, default colourspace, and IRQs William Towle
2015-01-29 16:19 ` [PATCH 3/8] WmT: document "adi,adv7612" William Towle
2015-01-29 16:19 ` [PATCH 4/8] WmT: m-5mols_core style pad handling for adv7604 William Towle
2015-01-29 20:23   ` Jean-Michel Hautbois
2015-02-04 14:14     ` William Towle
2015-02-04 14:40       ` Hans Verkuil
2015-01-29 16:19 ` [PATCH 5/8] media: rcar_vin: Add RGB888_1X24 input format support William Towle
2015-01-29 17:05   ` Sergei Shtylyov
2015-01-29 18:18     ` Guennadi Liakhovetski
2015-01-29 18:28       ` Sergei Shtylyov
2015-01-29 20:19         ` Guennadi Liakhovetski
2015-01-29 20:36           ` Sergei Shtylyov
2015-01-29 20:57             ` Guennadi Liakhovetski
2015-01-29 21:11               ` Guennadi Liakhovetski
2015-02-01 18:29   ` Guennadi Liakhovetski
2015-01-29 16:19 ` [PATCH 6/8] WmT: adv7604 driver compatibility William Towle
2015-01-31 23:56   ` Guennadi Liakhovetski
2015-02-01 11:26     ` Guennadi Liakhovetski
2015-02-02 10:01       ` Laurent Pinchart [this message]
2015-02-02 10:09         ` Hans Verkuil
2015-02-03 15:22           ` Laurent Pinchart
2015-02-03 15:24             ` Hans Verkuil
2015-02-03 15:29               ` Lars-Peter Clausen
2015-02-03 15:56                 ` Laurent Pinchart
2015-02-03 15:55               ` Laurent Pinchart
2015-01-29 16:19 ` [PATCH 7/8] WmT: rcar_vin new ADV7612 support William Towle
2015-02-01 11:44   ` Guennadi Liakhovetski
2015-01-29 16:19 ` [PATCH 8/8] WmT: dts/i vin0/adv7612 (HDMI) William Towle
2015-01-29 16:51   ` Sergei Shtylyov
2015-02-01 15:51 ` RFC: supporting adv7604.c under soc_camera/rcar_vin Guennadi Liakhovetski
2015-03-04  9:51 ` [Linux-kernel] " William Towle
2015-03-04 10:19   ` Hans Verkuil
2015-03-05  8:58     ` William Towle
2015-03-25  9:55   ` William Towle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2552213.h99FiuUI04@avalon \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=g.liakhovetski@gmx.de \
    --cc=hverkuil@xs4all.nl \
    --cc=linux-kernel@lists.codethink.co.uk \
    --cc=linux-media@vger.kernel.org \
    --cc=sergei.shtylyov@cogentembedded.com \
    --cc=william.towle@codethink.co.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.