Re: [PATCH v3 1/1] [media] i2c: add support for OV13858 sensor

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Hyungwoo,

On Mon, May 29, 2017 at 8:26 AM, Yang, Hyungwoo <hyungwoo.yang@xxxxxxxxx> wrote:
>
> Hi Sakari,
>
> Here's my comments.
>
> -Hyungwoo
>
>
> -----Original Message-----
>> From: Sakari Ailus [mailto:sakari.ailus@xxxxxx]
>> Sent: Saturday, May 27, 2017 1:31 PM
>> To: Yang, Hyungwoo <hyungwoo.yang@xxxxxxxxx>
>> Cc: linux-media@xxxxxxxxxxxxxxx; sakari.ailus@xxxxxxxxxxxxxxx; Zheng, Jian Xu <jian.xu.zheng@xxxxxxxxx>; Hsu, Cedric <cedric.hsu@xxxxxxxxx>; tfiga@xxxxxxxxxxxx
>> Subject: Re: [PATCH v3 1/1] [media] i2c: add support for OV13858 sensor
>>
>> Hi Hyungwoo,
>>
>> Thanks for the update. A few comments below.
>>
[snip]
>> > +/* Update VTS that meets expected vertical blanking */ static int
>> > +ov13858_update_vblank(struct ov13858 *ov13858,
>> > +                            struct v4l2_ctrl *ctrl)
>> > +{
>> > +   return ov13858_write_reg(
>> > +                   ov13858, OV13858_REG_VTS,
>> > +                   OV13858_REG_VALUE_16BIT,
>> > +                   ov13858->cur_mode->height + ov13858->vblank->val); }
>> > +
>> > +/* Update analog gain */
>> > +static int ov13858_update_analog_gain(struct ov13858 *ov13858,
>> > +                                 struct v4l2_ctrl *ctrl)
>> > +{
>> > +   return ov13858_write_reg(ov13858, OV13858_REG_ANALOG_GAIN,
>> > +                            OV13858_REG_VALUE_16BIT, ctrl->val);
>>
>> I think I'd move what the four above functions do to ov13858_set_ctrl() unless they're used in more than one location.
>
> Why ? Personally I like this. Since there  wouldn't be any difference in generated machine code, I want to keep this if there's no strict rule on this.

Personally I wouldn't probably care about this, but I see one
advantage of Sakari's suggestion.

Namely, it improves code readability, because there is less
indirection and the person reading ov13858_set_ctrl() instantly knows
that all it does is directly writing the control value to hardware
registers. Otherwise, with the indirection in current version, until
you read ov13858_update_analog_gain() (or such), you don't know
whether it does some extra processing, power management or whatnot.

If ov13858_update_analog_gain() did more than just a simple register
write, it would indeed make sense to separate it, as it's intuitive
that a separate function means some more complicated work. (And vice
versa, it's counter-intuitive to have a function that is only there to
call a register accessor.)

>
>>
>> > +}
>> > +
>> > +static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl) {
>> > +   struct ov13858 *ov13858 = container_of(ctrl->handler,
>> > +                                          struct ov13858, ctrl_handler);
>> > +   struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
>> > +   int ret;
>> > +
>> > +   /* Propagate change of current control to all related controls */
>> > +   switch (ctrl->id) {
>> > +   case V4L2_CID_VBLANK:
>> > +           ov13858_update_exposure_limits(ov13858);
>> > +           break;
>> > +   };
>> > +
>> > +   /*
>> > +    * Applying V4L2 control value only happens
>> > +    * when power is up for streaming
>> > +    */
>> > +   if (pm_runtime_get_if_in_use(&client->dev) <= 0)
>> > +           return 0;
>> > +
>> > +   ret = 0;
>> > +   switch (ctrl->id) {
>> > +   case V4L2_CID_ANALOGUE_GAIN:
>> > +           ret = ov13858_update_analog_gain(ov13858, ctrl);
>> > +           break;
>> > +   case V4L2_CID_EXPOSURE:
>> > +           ret = ov13858_update_exposure(ov13858, ctrl);
>> > +           break;
>> > +   case V4L2_CID_VBLANK:
>> > +           ret = ov13858_update_vblank(ov13858, ctrl);
>> > +           break;
>> > +   default:
>> > +           dev_info(&client->dev,
>> > +                    "ctrl(id:0x%x,val:0x%x) is not handled\n",
>> > +                    ctrl->id, ctrl->val);
>> > +           break;
>> > +   };
>> > +
>> > +   pm_runtime_put(&client->dev);
>> > +
>> > +   return ret;
>> > +}
>> > +
>                 :
>                 :
>> > +/*
>> > + * Prepare streaming by writing default values and customized values.
>> > + * This should be called with ov13858->mutex acquired.
>> > + */
>> > +static int ov13858_prepare_streaming(struct ov13858 *ov13858)
>> > +{
>> > +   struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
>> > +   const struct ov13858_reg_list *reg_list;
>> > +   int ret, link_freq_index;
>> > +
>> > +   /* Get out of from software reset */
>> > +   ret = ov13858_write_reg(ov13858, OV13858_REG_SOFTWARE_RST,
>> > +                           OV13858_REG_VALUE_08BIT, OV13858_SOFTWARE_RST);
>> > +   if (ret) {
>> > +           dev_err(&client->dev, "%s failed to set powerup registers\n",
>> > +                   __func__);
>> > +           return ret;
>> > +   }
>> > +
>> > +   /* Setup PLL */
>> > +   link_freq_index = ov13858->cur_mode->link_freq_index;
>> > +   reg_list = &link_freq_configs[link_freq_index].reg_list;
>> > +   ret = ov13858_write_reg_list(ov13858, reg_list);
>> > +   if (ret) {
>> > +           dev_err(&client->dev, "%s failed to set plls\n", __func__);
>> > +           return ret;
>> > +   }
>> > +
>> > +   /* Apply default values of current mode */
>> > +   reg_list = &ov13858->cur_mode->reg_list;
>> > +   ret = ov13858_write_reg_list(ov13858, reg_list);
>> > +   if (ret) {
>> > +           dev_err(&client->dev, "%s failed to set mode\n", __func__);
>> > +           return ret;
>> > +   }
>> > +
>> > +   /* Apply customized values from user */
>> > +   return __v4l2_ctrl_handler_setup(ov13858->sd.ctrl_handler);
>> > +}
>> > +
>> > +/* Start streaming */
>> > +static int ov13858_start_streaming(struct ov13858 *ov13858)
>> > +{
>> > +   int ret;
>> > +
>> > +   /* Write default & customized values */
>> > +   ret = ov13858_prepare_streaming(ov13858);
>>
>> Could you merge this with ov13858_prepare_streaming()?
>>
>
> Why ? I want to keep this. If you want to worry about 1 more jump then, if it is really there, I can make this function "inline"

I doubt it's about the number of jumps. The same argument of code
readability as I mentioned above applies here as well. I see no point
in having ov13858_start_streaming() separate if all it does on top of
ov13858_prepare_streaming() is a register write, it is
counter-intuitive for readers of the code.

Best regards,
Tomasz



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux