[PATCH v8 10/14] media: ov02c10: ov02c10_get_pm_resources() fixes

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

 



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@xxxxxxxxxx>
---
 drivers/media/i2c/ov02c10.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c
index 38918b1b6a95..a46cacf301a2 100644
--- a/drivers/media/i2c/ov02c10.c
+++ b/drivers/media/i2c/ov02c10.c
@@ -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))
-- 
2.48.1





[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