Skip to content

Commit fb6ba07

Browse files
jwrdegoedemchehab
authored andcommitted
media: ov2740: Add regulator support
On some designs the regulators for the AVDD / DOVDD / DVDD power rails are controlled by Linux. Add support to the driver for getting regulators for these 3 rails and for enabling these regulators when necessary. The datasheet specifies a delay of 0ns between enabling the regulators, IOW they can all 3 be enabled at the same time. This allows using the bulk regulator API. The regulator core will provide dummy regulators for the 3 power-rails when necessary. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Ricardo Ribalda <ribalda@chromium.org> Tested-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
1 parent fa3772f commit fb6ba07

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

drivers/media/i2c/ov2740.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/pm_runtime.h>
1212
#include <linux/nvmem-provider.h>
1313
#include <linux/regmap.h>
14+
#include <linux/regulator/consumer.h>
1415
#include <media/v4l2-ctrls.h>
1516
#include <media/v4l2-device.h>
1617
#include <media/v4l2-fwnode.h>
@@ -76,6 +77,14 @@
7677
/* OTP registers from sensor */
7778
#define OV2740_REG_OTP_CUSTOMER 0x7010
7879

80+
static const char * const ov2740_supply_name[] = {
81+
"AVDD",
82+
"DOVDD",
83+
"DVDD",
84+
};
85+
86+
#define OV2740_NUM_SUPPLIES ARRAY_SIZE(ov2740_supply_name)
87+
7988
struct nvm_data {
8089
struct nvmem_device *nvmem;
8190
struct regmap *regmap;
@@ -523,10 +532,11 @@ struct ov2740 {
523532
struct v4l2_ctrl *hblank;
524533
struct v4l2_ctrl *exposure;
525534

526-
/* GPIOs, clocks */
535+
/* GPIOs, clocks, regulators */
527536
struct gpio_desc *reset_gpio;
528537
struct gpio_desc *powerdown_gpio;
529538
struct clk *clk;
539+
struct regulator_bulk_data supplies[OV2740_NUM_SUPPLIES];
530540

531541
/* Current mode */
532542
const struct ov2740_mode *cur_mode;
@@ -1309,6 +1319,7 @@ static int ov2740_suspend(struct device *dev)
13091319
gpiod_set_value_cansleep(ov2740->reset_gpio, 1);
13101320
gpiod_set_value_cansleep(ov2740->powerdown_gpio, 1);
13111321
clk_disable_unprepare(ov2740->clk);
1322+
regulator_bulk_disable(OV2740_NUM_SUPPLIES, ov2740->supplies);
13121323
return 0;
13131324
}
13141325

@@ -1318,10 +1329,16 @@ static int ov2740_resume(struct device *dev)
13181329
struct ov2740 *ov2740 = to_ov2740(sd);
13191330
int ret;
13201331

1321-
ret = clk_prepare_enable(ov2740->clk);
1332+
ret = regulator_bulk_enable(OV2740_NUM_SUPPLIES, ov2740->supplies);
13221333
if (ret)
13231334
return ret;
13241335

1336+
ret = clk_prepare_enable(ov2740->clk);
1337+
if (ret) {
1338+
regulator_bulk_disable(OV2740_NUM_SUPPLIES, ov2740->supplies);
1339+
return ret;
1340+
}
1341+
13251342
gpiod_set_value_cansleep(ov2740->powerdown_gpio, 0);
13261343
gpiod_set_value_cansleep(ov2740->reset_gpio, 0);
13271344
msleep(20);
@@ -1334,7 +1351,7 @@ static int ov2740_probe(struct i2c_client *client)
13341351
struct device *dev = &client->dev;
13351352
struct ov2740 *ov2740;
13361353
bool full_power;
1337-
int ret;
1354+
int i, ret;
13381355

13391356
ov2740 = devm_kzalloc(&client->dev, sizeof(*ov2740), GFP_KERNEL);
13401357
if (!ov2740)
@@ -1372,6 +1389,13 @@ static int ov2740_probe(struct i2c_client *client)
13721389
return dev_err_probe(dev, PTR_ERR(ov2740->clk),
13731390
"failed to get clock\n");
13741391

1392+
for (i = 0; i < OV2740_NUM_SUPPLIES; i++)
1393+
ov2740->supplies[i].supply = ov2740_supply_name[i];
1394+
1395+
ret = devm_regulator_bulk_get(dev, OV2740_NUM_SUPPLIES, ov2740->supplies);
1396+
if (ret)
1397+
return dev_err_probe(dev, ret, "failed to get regulators\n");
1398+
13751399
full_power = acpi_dev_state_d0(&client->dev);
13761400
if (full_power) {
13771401
/* ACPI does not always clear the reset GPIO / enable the clock */

0 commit comments

Comments
 (0)