linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Sakari Ailus <sakari.ailus@iki.fi>
Cc: linux-media@vger.kernel.org, hverkuil@xs4all.nl,
	teturtia@gmail.com, dacohen@gmail.com, snjw23@gmail.com,
	andriy.shevchenko@linux.intel.com, t.stanislaws@samsung.com,
	tuukkat76@gmail.com, k.debski@gmail.com, riverful@gmail.com
Subject: Re: [PATCH v3 32/33] smiapp: Add driver.
Date: Wed, 29 Feb 2012 10:35:26 +0100	[thread overview]
Message-ID: <3598400.2MKjxpiZx5@avalon> (raw)
In-Reply-To: <20120229054149.GB14920@valkosipuli.localdomain>

Hi Sakari,

On Wednesday 29 February 2012 07:41:50 Sakari Ailus wrote:
> On Mon, Feb 27, 2012 at 04:38:49PM +0100, Laurent Pinchart wrote:
> > On Monday 20 February 2012 03:57:11 Sakari Ailus wrote:
> > > From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
> > > 
> > > Add driver for SMIA++/SMIA image sensors. The driver exposes the sensor
> > > as three subdevs, pixel array, binner and scaler --- in case the device
> > > has a scaler.
> > > 
> > > Currently it relies on the board code for external clock handling. There
> > > is no fast way out of this dependency before the ISP drivers (omap3isp)
> > > among others will be able to export that clock through the clock
> > > framework instead.
> > > 
> > > Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>

[snip]

> > > +
> > > +	dev_dbg(&client->dev, "format_model_type %s\n",
> > > +		fmt_model_type == SMIAPP_FRAME_FORMAT_MODEL_TYPE_2BYTE
> > > +		? "2 byte" :
> > > +		fmt_model_type == SMIAPP_FRAME_FORMAT_MODEL_TYPE_4BYTE
> > > +		? "4 byte" : "is simply bad");
> > 
> > Simply ? :-)
> 
> Yeah, well, it's not that complex. :-) Do you think I should change that to
> something else?

No, that's fine. I just found it funny that the format could be "simply bad" 
:-)

[snip]

> > > +	if (embedded_start == -1 || embedded_end == -1)
> > > +		embedded_start = embedded_end = 0;
> > 
> > One assignment per line please.
> 
> I'm not sure if you gain any clarity with that, but I guess it's a norm
> still. Fixed.

It's very easy to miss one of the assignments if you group them in a single 
line.Or at least it is for me.

[snip]

> > > +	case V4L2_CID_VBLANK:
> > > +		exposure = sensor->exposure->val;
> > > +
> > > +		__smiapp_update_exposure_limits(sensor);
> > > +
> > > +		if (exposure > sensor->exposure->maximum) {
> > > +			sensor->exposure->val =
> > > +				sensor->exposure->maximum;
> > > +			rval = smiapp_set_ctrl(
> > > +				sensor->exposure);
> > 
> > Shouldn't you call the V4L2 control API here instead ? Otherwise no
> > control change event will be generated for the exposure time. Will this
> > work as expected if the user sets the exposure time in the same
> > VIDIOC_S_EXT_CTRLS call ?
> 
> Good question. I'm holding the ctrl handler lock here and so can't use the
> regular functions to perform the change. Perhaps time to implement
> __v4l2_subdev_s_ext_ctrls() and use that?

Do you mean __v4l2_ctrl_s_ctrl() ? I think it would make sense, yes.

> > > +	if (sensor->pixel_array->ctrl_handler.error) {
> > > +		dev_err(&client->dev,
> > > +			"pixel array controls initialization failed (%d)\n",
> > > +			sensor->pixel_array->ctrl_handler.error);
> > 
> > Shouldn't you call v4l2_ctrl_handler_free() here ?
> 
> Yes. Fixed.
> 
> > > +		return sensor->pixel_array->ctrl_handler.error;
> > > +	}
> > > +
> > > +	sensor->pixel_array->sd.ctrl_handler =
> > > +		&sensor->pixel_array->ctrl_handler;
> > > +
> > > +	v4l2_ctrl_cluster(2, &sensor->hflip);
> > 
> > Shouldn't you move this before the control handler check ?
> 
> Why? It can't fail.

I thought it could fail. You could then leave it here, but it would be easier 
from a maintenance point of view to check the error code after completing all 
control-related initialization, as it would avoid introducing a bug if for 
some reason the v4l2_ctrl_cluster() function needs to return an error later.

[snip]

> > > +static int smiapp_update_mode(struct smiapp_sensor *sensor)
> > > +{
> > 
> > This function isn't protected by the sensor mutex when called from
> > s_power, but it changes controls. The other call paths seem OK, but you
> > might want to double-check them.
> 
> It's actually not an issue. When s_power is being called there are no other
> users and the power_lock serialises it.

Are you sure about that? s_power can be called from both the subdev video node 
open() handlers (assuming the sensor is in the pipe).

> I implemented it this way since the control setup acquires the same lock
> that I would have to hold while powering up. The power_lock fixes this
> issue.
> 
> I cleaned this up so that I won't take sensor->mutex at all anymore.

[snip]

> > > +	dev_dbg(&client->dev, "module 0x%2.2x-0x%4.4x\n",
> > 
> > "module 0x%02x-0x%04x\n" (and similarly below) ?
> 
> Hmm. %y.yx means exactly y characters of %x. What does %0yx mean?

at least y characters, pad with 0. You can keep %y.yx if you prefer it.

> > > +		minfo->manufacturer_id, minfo->model_id);
> > > +
> > > +	dev_dbg(&client->dev,
> > > +		"module revision 0x%2.2x-0x%2.2x date %2.2d-%2.2d-%2.2d\n",
> > > +		minfo->revision_number_major, minfo->revision_number_minor,
> > > +		minfo->module_year, minfo->module_month, minfo->module_day);
> > > +
> > > +	dev_dbg(&client->dev, "sensor 0x%2.2x-0x%4.4x\n",
> > > +		minfo->sensor_manufacturer_id, minfo->sensor_model_id);
> > > +
> > > +	dev_dbg(&client->dev,
> > > +		"sensor revision 0x%2.2x firmware version 0x%2.2x\n",
> > > +		minfo->sensor_revision_number, minfo->sensor_firmware_version);
> > > +
> > > +	dev_dbg(&client->dev, "smia version %2.2d smiapp version %2.2d\n",
> > > +		minfo->smia_version, minfo->smiapp_version);
> > > +
> > 
> > Could you please add a short comment to explain why this is needed ?
> 
> The one below?

Yes, the lines below, sorry.

> Some devices just have bad data in these variables. Hopefully the other
> variables have better stuff.

I knew why this was needed, but other readers might not :-) That's why a 
comment would be good.

> The lvalues are module parameters whereas the rvalues are sensor parameters.
>
> > > +	if (!minfo->manufacturer_id && !minfo->model_id) {
> > > +		minfo->manufacturer_id = minfo->sensor_manufacturer_id;
> > > +		minfo->model_id = minfo->sensor_model_id;
> > > +		minfo->revision_number_major = minfo->sensor_revision_number;
> > > +	}
> > > +
> > > +	for (i = 0; i < ARRAY_SIZE(smiapp_module_idents); i++) {
> > > +		if (smiapp_module_idents[i].manufacturer_id
> > > +		    != minfo->manufacturer_id)
> > > +			continue;
> > > +		if (smiapp_module_idents[i].model_id != minfo->model_id)
> > > +			continue;
> > > +		if (smiapp_module_idents[i].flags
> > > +		    & SMIAPP_MODULE_IDENT_FLAG_REV_LE) {
> > > +			if (smiapp_module_idents[i].revision_number_major
> > > +			    < minfo->revision_number_major)
> > > +				continue;
> > > +		} else {
> > > +			if (smiapp_module_idents[i].revision_number_major
> > > +			    != minfo->revision_number_major)
> > > +				continue;
> > > +		}
> > > +
> > > +		minfo->name = smiapp_module_idents[i].name;
> > > +		minfo->quirk = smiapp_module_idents[i].quirk;
> > > +		break;
> > > +	}
> > > +
> > > +	if (i >= ARRAY_SIZE(smiapp_module_idents))
> > > +		dev_warn(&client->dev, "no quirks for this module\n");
> > 
> > Maybe a message such as "unknown SMIA++ module - trying generic support"
> > would be better ? Many of the known modules have no quirks.
> 
> I'd like to think it as a positive message of the conformance of the sensor
> --- still it may inform that the quirks are actually missing. What do you
> think?

In that case I think something similar to my message is better :-) I agree 
about the meaning the message should convey.

> > > +
> > > +	dev_dbg(&client->dev, "the sensor is called %s, ident
> > > %2.2x%4.4x%2.2x\n",
> > > +		minfo->name, minfo->manufacturer_id, minfo->model_id,
> > > +		minfo->revision_number_major);
> > > +
> > > +	strlcpy(subdev->name, sensor->minfo.name, sizeof(subdev->name));
> > > +
> > > +	return 0;
> > > +}

[snip]

> > > +static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh
> > > *fh)
> > > +{
> > > +	struct smiapp_subdev *ssd = to_smiapp_subdev(sd);
> > > +	struct v4l2_subdev_selection sel;
> > > +	struct v4l2_rect *try_sel;
> > > +	int i;
> > > +	int rval;
> > > +
> > > +	mutex_lock(&ssd->sensor->power_mutex);
> > > +	mutex_lock(&ssd->sensor->mutex);
> > > +
> > > +	for (i = 0; i < ssd->npads; i++) {
> > > +		struct v4l2_subdev_format fmt;
> > > +		struct v4l2_mbus_framefmt *try_fmt;
> > > +
> > > +		fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> > > +		fmt.pad = i;
> > > +		__smiapp_get_format(sd, fh, &fmt);
> > > +		try_fmt = v4l2_subdev_get_try_format(fh, i);
> > > +		*try_fmt = fmt.format;
> > > +
> > > +		sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> > > +		sel.pad = i;
> > > +		sel.target = V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE;
> > > +		__smiapp_get_selection(sd, fh, &sel);
> > > +		try_sel = v4l2_subdev_get_try_crop(fh, i);
> > > +		*try_sel = sel.r;
> > 
> > Wouldn't it be better to use the default values instead of the active ones
> > here ?
> 
> Good question.
> 
> > > +	}
> > > +
> > > +	if (ssd != ssd->sensor->pixel_array) {
> > > +		sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> > > +		sel.pad = SMIAPP_PAD_SINK;
> > > +		sel.target = V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTIVE;
> > > +		__smiapp_get_selection(sd, fh, &sel);
> > > +		try_sel = v4l2_subdev_get_try_compose(fh, SMIAPP_PAD_SINK);
> > > +		*try_sel = sel.r;
> > > +	}
> > > +
> > > +	rval = smiapp_set_power(sd, 1);
> > > +
> > > +	mutex_unlock(&ssd->sensor->mutex);
> > > +
> > > +	if (rval < 0)
> > > +		goto out;
> > > +
> > > +	/* Was the sensor already powered on? */
> > > +	if (ssd->sensor->power_count > 1)
> > 
> > power_count is accessed in smiapp_set_power without taking the power_mutex
> > lock. Are two locks really needed ?
> 
> Well, now that you mention it, control handler setup function that wouldn't
> take the locks would resolve the issue, I think. Should I create one?

I'd ask Hans about that.

[snip]

> > > --git a/drivers/media/video/smiapp/smiapp-reg.h
> > > b/drivers/media/video/smiapp/smiapp-reg.h new file mode 100644
> > > index 0000000..126ca5b
> > > --- /dev/null
> > > +++ b/drivers/media/video/smiapp/smiapp-reg.h
> > 
> > [snip]
> > 
> > > +#define SMIAPP_SCALING_CAPABILITY_NONE			0
> > > +#define SMIAPP_SCALING_CAPABILITY_HORIZONTAL		1
> > > +#define SMIAPP_SCALING_CAPABILITY_BOTH			2 /* horizontal/both */
> > 
> > Do you mean horizontal/vertical ?
> 
> No. The BOTH capability means that either horizontal or (horizontal and
> vertical) scaling is supported (parentheses for precedence).

I was referring to the comment on the third line.

[snip]

> > > +static uint32_t float_to_u32_mul_1000000(struct i2c_client *client,
> > > +					 uint32_t phloat)
> > 
> > Now that's creative :-)
> 
> I couldn't figure out a way to avoid that, unfortunately. There are a few
> corresponding functions in math emulation libraries but it seems onethey
> would require significant changes to be usable for this driver.

I should have been more specific, I was referring to the name 'phloat' :-)

[snip]

> > > diff --git a/drivers/media/video/smiapp/smiapp.h
> > > b/drivers/media/video/smiapp/smiapp.h new file mode 100644
> > > index 0000000..df514dd
> > > --- /dev/null
> > > +++ b/drivers/media/video/smiapp/smiapp.h
> > 
> > [snip]
> > 
> > > +struct smiapp_module_ident {
> > > +	u8 manufacturer_id;
> > > +	u16 model_id;
> > > +	u8 revision_number_major;
> > > +
> > > +	u8 flags;
> > > +
> > > +	char *name;
> > > +	const struct smiapp_quirk *quirk;
> > > +} __packed;
> > 
> > Is there really a need to pack this ? You could just move
> > revision_number_major above model_id to save a couple of bytes and leave
> > packing out.
> 
> The order is there for readability, packing to save memory. I can change the
> order, too, if you think it's a good idea.

Packing usually increases the run time (and possibly code size), as the CPU 
will need to perform unaligned access. I don't think it's worth it in this 
case. At second thought moving the fields around won't save any memory, so I 
would just remove __packed.

> > > +#define SMIAPP_IDENT_FQ(manufacturer, model, rev, fl, _name, _quirk)	
\
> > > +	{ .manufacturer_id = manufacturer,				\
> > > +			.model_id = model,				\
> > > +			.revision_number_major = rev,			\
> > > +			.flags = fl,					\
> > > +			.name = _name,					\
> > > +			.quirk = _quirk, }
> > 
> > Any reason for the strange indentation ?
> 
> This is standard indentation in my Emacsitor. Hmm. I think I might be fine
> even if it indented less. It looks like it wouldn't be indended to work that
> way.

Maybe it's time to switch to vi ? :-D

-- 
Regards,

Laurent Pinchart


  reply	other threads:[~2012-02-29  9:35 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-20  1:56 [PATCH v3 0/33] V4L2 subdev and sensor control changes, SMIA++ driver and N9 camera board code Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 01/33] v4l: Introduce integer menu controls Sakari Ailus
2012-02-20 17:36   ` Sylwester Nawrocki
2012-02-20  1:56 ` [PATCH v3 02/33] v4l: Document " Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 03/33] vivi: Add an integer menu test control Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 04/33] v4l: VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs Sakari Ailus
2012-02-21 14:34   ` Laurent Pinchart
2012-02-23  5:49     ` Sakari Ailus
2012-02-21 16:15   ` Laurent Pinchart
2012-02-23  6:01     ` Sakari Ailus
2012-02-27  0:22       ` Laurent Pinchart
2012-02-27  0:57         ` Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 05/33] v4l: vdev_to_v4l2_subdev() should have return type "struct v4l2_subdev *" Sakari Ailus
2012-02-21 14:37   ` Laurent Pinchart
2012-02-20  1:56 ` [PATCH v3 06/33] v4l: Check pad number in get try pointer functions Sakari Ailus
2012-02-21 14:42   ` Laurent Pinchart
2012-02-23  5:57     ` Sakari Ailus
2012-02-27  0:33       ` Laurent Pinchart
2012-02-27 12:27         ` Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 07/33] v4l: Support s_crop and g_crop through s/g_selection Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 08/33] v4l: Add subdev selections documentation: svg and dia files Sakari Ailus
2012-02-21 15:00   ` Laurent Pinchart
2012-02-26 18:56     ` Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 09/33] v4l: Add subdev selections documentation Sakari Ailus
2012-02-21 16:41   ` Laurent Pinchart
2012-02-26 21:42     ` Sakari Ailus
2012-02-28 11:42       ` Laurent Pinchart
2012-03-02 12:24         ` Sakari Ailus
2012-03-02 17:54           ` Laurent Pinchart
2012-03-02 18:01             ` Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 10/33] v4l: Mark VIDIOC_SUBDEV_G_CROP and VIDIOC_SUBDEV_S_CROP obsolete Sakari Ailus
2012-02-21 16:42   ` Laurent Pinchart
2012-02-20  1:56 ` [PATCH v3 11/33] v4l: Image source control class Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 12/33] v4l: Image processing " Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 13/33] v4l: Document raw bayer 4CC codes Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 14/33] v4l: Add DPCM compressed formats Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 15/33] media: Add link_validate() op to check links to the sink pad Sakari Ailus
2012-02-22 10:05   ` Laurent Pinchart
2012-02-23 15:04     ` Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 16/33] v4l: Improve sub-device documentation for pad ops Sakari Ailus
2012-02-22 10:06   ` Laurent Pinchart
2012-02-20  1:56 ` [PATCH v3 17/33] v4l: Implement v4l2_subdev_link_validate() Sakari Ailus
2012-02-22 10:14   ` Laurent Pinchart
2012-02-23 16:07     ` Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 18/33] v4l: Allow changing control handler lock Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 19/33] omap3isp: Support additional in-memory compressed bayer formats Sakari Ailus
2012-02-20  1:56 ` [PATCH v3 20/33] omap3isp: Move definitions required by board code under include/media Sakari Ailus
2012-02-20  1:57 ` [PATCH v3 21/33] omap3: add definition for CONTROL_CAMERA_PHY_CTRL Sakari Ailus
2012-02-20  1:57 ` [PATCH v3 22/33] omap3isp: Assume media_entity_pipeline_start may fail Sakari Ailus
2012-02-22 10:48   ` Laurent Pinchart
2012-02-26  1:08     ` Sakari Ailus
2012-02-20  1:57 ` [PATCH v3 23/33] omap3isp: Add lane configuration to platform data Sakari Ailus
2012-02-20  1:57 ` [PATCH v3 24/33] omap3isp: Add information on external subdev to struct isp_pipeline Sakari Ailus
2012-02-20  1:57 ` [PATCH v3 25/33] omap3isp: Introduce omap3isp_get_external_info() Sakari Ailus
2012-02-22 10:55   ` Laurent Pinchart
2012-02-26  1:09     ` Sakari Ailus
2012-02-20  1:57 ` [PATCH v3 26/33] omap3isp: Default link validation for ccp2, csi2, preview and resizer Sakari Ailus
2012-02-22 11:01   ` Laurent Pinchart
2012-02-25  1:34     ` Sakari Ailus
2012-02-26 23:14       ` Laurent Pinchart
2012-02-26 23:40         ` Sakari Ailus
2012-02-20  1:57 ` [PATCH v3 27/33] omap3isp: Implement proper CCDC link validation, check pixel rate Sakari Ailus
2012-02-22 11:11   ` Laurent Pinchart
2012-02-25  1:42     ` Sakari Ailus
2012-02-20  1:57 ` [PATCH v3 28/33] omap3isp: Move setting constaints above media_entity_pipeline_start Sakari Ailus
2012-02-22 11:12   ` Laurent Pinchart
2012-02-25  1:46     ` Sakari Ailus
2012-02-20  1:57 ` [PATCH v3 29/33] omap3isp: Configure CSI-2 phy based on platform data Sakari Ailus
2012-02-22 11:21   ` Laurent Pinchart
2012-02-25  1:49     ` Sakari Ailus
2012-02-20  1:57 ` [PATCH v3 30/33] omap3isp: Add resizer data rate configuration to resizer_set_stream Sakari Ailus
2012-02-22 11:24   ` Laurent Pinchart
2012-02-26  1:10     ` Sakari Ailus
2012-02-20  1:57 ` [PATCH v3 31/33] omap3isp: Remove isp_validate_pipeline and other old stuff Sakari Ailus
2012-02-22 11:26   ` Laurent Pinchart
2012-02-25  1:52     ` Sakari Ailus
2012-02-20  1:57 ` [PATCH v3 32/33] smiapp: Add driver Sakari Ailus
2012-02-27 15:38   ` Laurent Pinchart
2012-02-29  5:41     ` Sakari Ailus
2012-02-29  9:35       ` Laurent Pinchart [this message]
2012-02-29 10:00         ` Sylwester Nawrocki
2012-03-01 14:01         ` Sakari Ailus
2012-03-01 14:56           ` Laurent Pinchart
2012-02-20  1:57 ` [PATCH v3 33/33] rm680: Add camera init Sakari Ailus
2012-02-27  1:06   ` Laurent Pinchart
2012-02-28 19:05     ` Sakari Ailus
2012-02-20  2:03 ` [PATCH v3 0/33] V4L2 subdev and sensor control changes, SMIA++ driver and N9 camera board code Sakari Ailus

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=3598400.2MKjxpiZx5@avalon \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=dacohen@gmail.com \
    --cc=hverkuil@xs4all.nl \
    --cc=k.debski@gmail.com \
    --cc=linux-media@vger.kernel.org \
    --cc=riverful@gmail.com \
    --cc=sakari.ailus@iki.fi \
    --cc=snjw23@gmail.com \
    --cc=t.stanislaws@samsung.com \
    --cc=teturtia@gmail.com \
    --cc=tuukkat76@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).