Re: [PATCH] dw9714: Initial driver for dw9714 VCM

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

 



Hi Sakari,

On Tue, May 9, 2017 at 4:55 AM, Sakari Ailus <sakari.ailus@xxxxxx> wrote:
> Hi Rajmohan,
>
> A few comments below...
>
> On Sun, May 07, 2017 at 04:33:24AM -0700, rajmohan.mani@xxxxxxxxx wrote:
[snip]
>> +     rval = v4l2_async_register_subdev(&dw9714_dev->sd);
>> +     if (rval < 0)
>> +             goto err_cleanup;
>> +
>> +     pm_runtime_enable(&client->dev);
>
> Getting PM runtime right doesn't seem to be easy. :-I
>
> pm_runtime_enable() alone doesn't do the trick. I wonder if adding
> pm_runtime_suspend() would do the trick.

Is this something specific for I2C devices? For platform devices,
typically pm_runtime_enable() is the only thing you would need to do.

>
>> +
>> +     return 0;
>> +
>> +err_cleanup:
>> +     dw9714_subdev_cleanup(dw9714_dev);
>> +     dev_err(&client->dev, "Probe failed: %d\n", rval);
>> +     return rval;
>> +}
>> +
>> +static int dw9714_remove(struct i2c_client *client)
>> +{
>> +     struct v4l2_subdev *sd = i2c_get_clientdata(client);
>> +     struct dw9714_device *dw9714_dev = container_of(sd,
>> +                                                     struct dw9714_device,
>> +                                                     sd);
>> +
>> +     pm_runtime_disable(&client->dev);
>> +     dw9714_subdev_cleanup(dw9714_dev);
>> +
>> +     return 0;
>> +}
>> +
>> +#ifdef CONFIG_PM
>> +
>> +static int dw9714_runtime_suspend(struct device *dev)
>> +{
>> +     return 0;
>> +}
>> +
>> +static int dw9714_runtime_resume(struct device *dev)
>> +{
>> +     return 0;
>
> I think it'd be fine to remove empty callbacks.

It's actually a bit more complicated (if a PM domain is attached, the
callbacks must be present), however in case of external I2C devices it
should be fine indeed. However, AFAIK, pm_runtime_no_callbacks()
should be called.

>
>> +}
>> +
>> +/* This function sets the vcm position, so it consumes least current */
>> +static int dw9714_suspend(struct device *dev)
>> +{
>> +     struct i2c_client *client = to_i2c_client(dev);
>> +     struct v4l2_subdev *sd = i2c_get_clientdata(client);
>> +     struct dw9714_device *dw9714_dev = container_of(sd,
>> +                                                     struct dw9714_device,
>> +                                                     sd);
>> +     int ret, val;
>> +
>> +     dev_dbg(dev, "%s\n", __func__);
>> +
>> +     for (val = dw9714_dev->current_val & ~(DW9714_CTRL_STEPS - 1);
>> +          val >= 0; val -= DW9714_CTRL_STEPS) {
>> +             ret = dw9714_i2c_write(client,
>> +                                    DW9714_VAL((u16) val, DW9714_DEFAULT_S));
>> +             if (ret)
>> +                     dev_err(dev, "%s I2C failure: %d", __func__, ret);
>> +             usleep_range(DW9714_CTRL_DELAY_US, DW9714_CTRL_DELAY_US + 10);
>> +     }
>> +     return 0;
>> +}
>> +
>> +/*
>> + * This function sets the vcm position, so the focus position is set
>> + * closer to the camera
>> + */
>> +static int dw9714_resume(struct device *dev)
>> +{
>> +     struct i2c_client *client = to_i2c_client(dev);
>> +     struct v4l2_subdev *sd = i2c_get_clientdata(client);
>> +     struct dw9714_device *dw9714_dev = container_of(sd,
>> +                                                     struct dw9714_device,
>> +                                                     sd);
>> +     int ret, val;
>> +
>> +     dev_dbg(dev, "%s\n", __func__);
>> +
>> +     for (val = dw9714_dev->current_val % DW9714_CTRL_STEPS;
>> +          val < dw9714_dev->current_val + DW9714_CTRL_STEPS - 1;
>> +          val += DW9714_CTRL_STEPS) {
>> +             ret = dw9714_i2c_write(client,
>> +                                    DW9714_VAL((u16) val, DW9714_DEFAULT_S));
>> +             if (ret)
>> +                     dev_err(dev, "%s I2C failure: %d", __func__, ret);
>> +             usleep_range(DW9714_CTRL_DELAY_US, DW9714_CTRL_DELAY_US + 10);
>> +     }
>> +
>> +     /* restore v4l2 control values */
>> +     ret = v4l2_ctrl_handler_setup(&dw9714_dev->ctrls_vcm);
>
> Doesn't this need to be done for runtime_resume as well?

This driver doesn't seem to be doing any physical power off in its
runtime_suspend and I don't expect an I2C device to be put in a PM
domain, so possibly no need for it.

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