From 09ea611a49d446d5e513de3fec7e727cd8d2f33d Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 22 Nov 2021 12:31:35 +0000 Subject: [PATCH 0326/1085] media: i2c: ov5647: Add support for regulator control. The driver supported using GPIOs to control the shutdown line, but no regulator control. Add regulator hooks. Signed-off-by: Dave Stevenson --- drivers/media/i2c/ov5647.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,15 @@ #define OV5647_EXPOSURE_DEFAULT 1000 #define OV5647_EXPOSURE_MAX 65535 +/* regulator supplies */ +static const char * const ov5647_supply_names[] = { + "avdd", /* Analog power */ + "dovdd", /* Digital I/O power */ + "dvdd", /* Digital core power */ +}; + +#define OV5647_NUM_SUPPLIES ARRAY_SIZE(ov5647_supply_names) + struct regval_list { u16 addr; u8 data; @@ -104,6 +114,7 @@ struct ov5647 { struct mutex lock; struct clk *xclk; struct gpio_desc *pwdn; + struct regulator_bulk_data supplies[OV5647_NUM_SUPPLIES]; bool clock_ncont; struct v4l2_ctrl_handler ctrls; const struct ov5647_mode *mode; @@ -795,6 +806,12 @@ static int ov5647_power_on(struct device dev_dbg(dev, "OV5647 power on\n"); + ret = regulator_bulk_enable(OV5647_NUM_SUPPLIES, sensor->supplies); + if (ret < 0) { + dev_err(dev, "Failed to enable regulators\n"); + return ret; + } + if (sensor->pwdn) { gpiod_set_value_cansleep(sensor->pwdn, 0); msleep(PWDN_ACTIVE_DELAY_MS); @@ -826,6 +843,7 @@ error_clk_disable: clk_disable_unprepare(sensor->xclk); error_pwdn: gpiod_set_value_cansleep(sensor->pwdn, 1); + regulator_bulk_disable(OV5647_NUM_SUPPLIES, sensor->supplies); return ret; } @@ -855,6 +873,7 @@ static int ov5647_power_off(struct devic clk_disable_unprepare(sensor->xclk); gpiod_set_value_cansleep(sensor->pwdn, 1); + regulator_bulk_disable(OV5647_NUM_SUPPLIES, sensor->supplies); return 0; } @@ -1359,6 +1378,18 @@ static const struct v4l2_ctrl_ops ov5647 .s_ctrl = ov5647_s_ctrl, }; +static int ov5647_configure_regulators(struct device *dev, + struct ov5647 *sensor) +{ + unsigned int i; + + for (i = 0; i < OV5647_NUM_SUPPLIES; i++) + sensor->supplies[i].supply = ov5647_supply_names[i]; + + return devm_regulator_bulk_get(dev, OV5647_NUM_SUPPLIES, + sensor->supplies); +} + static int ov5647_init_controls(struct ov5647 *sensor, struct device *dev) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd); @@ -1511,6 +1542,12 @@ static int ov5647_probe(struct i2c_clien return -EINVAL; } + ret = ov5647_configure_regulators(dev, sensor); + if (ret) { + dev_err(dev, "Failed to get power regulators\n"); + return ret; + } + mutex_init(&sensor->lock); sensor->mode = OV5647_DEFAULT_MODE;