media: i2c: ov5670: Probe regulators
authorJacopo Mondi <jacopo.mondi@ideasonboard.com>
Thu, 26 Jan 2023 16:59:04 +0000 (17:59 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Mon, 6 Feb 2023 07:46:54 +0000 (08:46 +0100)
The OV5670 has three power supplies (AVDD, DOVDD and DVDD).

Probe them in the driver to prepare controlling with runtime_pm
operations.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Luca Weiss <luca@z3ntu.xyz>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/i2c/ov5670.c

index 52b799a..e71f133 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-event.h>
@@ -88,6 +89,14 @@ struct ov5670_link_freq_config {
        const struct ov5670_reg_list reg_list;
 };
 
+static const char * const ov5670_supply_names[] = {
+       "avdd",         /* Analog power */
+       "dvdd",         /* Digital power */
+       "dovdd",        /* Digital output power */
+};
+
+#define OV5670_NUM_SUPPLIES ARRAY_SIZE(ov5670_supply_names)
+
 struct ov5670_mode {
        /* Frame width in pixels */
        u32 width;
@@ -1836,6 +1845,9 @@ struct ov5670 {
        /* xvclk input clock */
        struct clk *xvclk;
 
+       /* Regulators */
+       struct regulator_bulk_data supplies[OV5670_NUM_SUPPLIES];
+
        /* To serialize asynchronus callbacks */
        struct mutex mutex;
 
@@ -2476,6 +2488,18 @@ static const struct v4l2_subdev_internal_ops ov5670_internal_ops = {
        .open = ov5670_open,
 };
 
+static int ov5670_regulators_probe(struct ov5670 *ov5670)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
+       unsigned int i;
+
+       for (i = 0; i < OV5670_NUM_SUPPLIES; i++)
+               ov5670->supplies[i].supply = ov5670_supply_names[i];
+
+       return devm_regulator_bulk_get(&client->dev, OV5670_NUM_SUPPLIES,
+                                      ov5670->supplies);
+}
+
 static int ov5670_probe(struct i2c_client *client)
 {
        struct ov5670 *ov5670;
@@ -2510,6 +2534,12 @@ static int ov5670_probe(struct i2c_client *client)
        /* Initialize subdev */
        v4l2_i2c_subdev_init(&ov5670->sd, client, &ov5670_subdev_ops);
 
+       ret = ov5670_regulators_probe(ov5670);
+       if (ret) {
+               err_msg = "Regulators probe failed";
+               goto error_print;
+       }
+
        full_power = acpi_dev_state_d0(&client->dev);
        if (full_power) {
                /* Check module identity */