@@ -642,26 +642,23 @@ static int ov02c10_get_pm_resources(struct device *dev)
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct ov02c10 *ov02c10 = to_ov02c10(sd);
- int ret;
- ov02c10->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+ ov02c10->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(ov02c10->reset))
return dev_err_probe(dev, PTR_ERR(ov02c10->reset),
"failed to get reset gpio\n");
+ if (ov02c10->reset)
+ fsleep(1000);
ov02c10->img_clk = devm_clk_get_optional(dev, NULL);
if (IS_ERR(ov02c10->img_clk))
return dev_err_probe(dev, PTR_ERR(ov02c10->img_clk),
"failed to get imaging clock\n");
- ov02c10->avdd = devm_regulator_get_optional(dev, "avdd");
- if (IS_ERR(ov02c10->avdd)) {
- ret = PTR_ERR(ov02c10->avdd);
- ov02c10->avdd = NULL;
- if (ret != -ENODEV)
- return dev_err_probe(dev, ret,
- "failed to get avdd regulator\n");
- }
+ ov02c10->avdd = devm_regulator_get(dev, "avdd");
+ if (IS_ERR(ov02c10->avdd))
+ return dev_err_probe(dev, PTR_ERR(ov02c10->avdd),
+ "failed to get avdd regulator\n");
return 0;
}
@@ -966,13 +963,16 @@ static int ov02c10_probe(struct i2c_client *client)
if (!ov02c10)
return -ENOMEM;
+ v4l2_i2c_subdev_init(&ov02c10->sd, client, &ov02c10_subdev_ops);
+
/* Check HW config */
ret = ov02c10_check_hwcfg(&client->dev, ov02c10);
if (ret)
return ret;
- v4l2_i2c_subdev_init(&ov02c10->sd, client, &ov02c10_subdev_ops);
- ov02c10_get_pm_resources(&client->dev);
+ ret = ov02c10_get_pm_resources(&client->dev);
+ if (ret)
+ return ret;
ov02c10->regmap = devm_cci_regmap_init_i2c(client, 16);
if (IS_ERR(ov02c10->regmap))
A set of ov02c10_get_pm_resources() fixes: 1. Reset should only be de-asserted after enabling the regulators and clocks. Request the reset GPIO with GPIOD_OUT_HIGH and on success sleep for 1 ms to ensure that it is asserted for at least 1 ms before ov02c10_power_on() de-asserts it. 2. Use plain devm_regulator_get() for avdd. 3. Add error checking to the ov02c10_get_pm_resources() call in probe(), it may fail with -EPROBE_DEFER. 4. While at it move the v4l2_i2c_subdev_init() call to directly after allocating the ov02c10 struct, it has nothing to do with the ov02c10_get_pm_resources() call. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/media/i2c/ov02c10.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)