diff mbox series

[3/6] media: i2c: ov5670: Probe regulators

Message ID 20220310130829.96001-4-jacopo@jmondi.org (mailing list archive)
State New, archived
Headers show
Series media: i2c: ov5670: OF support, runtime_pm, regulators | expand

Commit Message

Jacopo Mondi March 10, 2022, 1:08 p.m. UTC
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@jmondi.org>
---
 drivers/media/i2c/ov5670.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

Comments

Laurent Pinchart March 13, 2022, 2:35 p.m. UTC | #1
Hi Jacopo,

Thank you for the patch.

On Thu, Mar 10, 2022 at 02:08:26PM +0100, Jacopo Mondi wrote:
> 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@jmondi.org>
> ---
>  drivers/media/i2c/ov5670.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c
> index 39786f3c9489..cba310aec011 100644
> --- a/drivers/media/i2c/ov5670.c
> +++ b/drivers/media/i2c/ov5670.c
> @@ -7,6 +7,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>
> @@ -85,6 +86,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;
> @@ -1830,6 +1839,9 @@ struct ov5670 {
>  	/* Current mode */
>  	const struct ov5670_mode *cur_mode;
>  
> +	/* Regulators */
> +	struct regulator_bulk_data supplies[OV5670_NUM_SUPPLIES];
> +
>  	/* To serialize asynchronus callbacks */
>  	struct mutex mutex;
>  
> @@ -2470,6 +2482,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;
> @@ -2492,6 +2516,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";

That's not common.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +		goto error_print;
> +	}
> +
>  	full_power = acpi_dev_state_d0(&client->dev);
>  	if (full_power) {
>  		/* Check module identity */
diff mbox series

Patch

diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c
index 39786f3c9489..cba310aec011 100644
--- a/drivers/media/i2c/ov5670.c
+++ b/drivers/media/i2c/ov5670.c
@@ -7,6 +7,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>
@@ -85,6 +86,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;
@@ -1830,6 +1839,9 @@  struct ov5670 {
 	/* Current mode */
 	const struct ov5670_mode *cur_mode;
 
+	/* Regulators */
+	struct regulator_bulk_data supplies[OV5670_NUM_SUPPLIES];
+
 	/* To serialize asynchronus callbacks */
 	struct mutex mutex;
 
@@ -2470,6 +2482,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;
@@ -2492,6 +2516,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 */