From 917fb6ce45971f4570646ad2f094057e9b418af9 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Sun, 7 Apr 2024 19:20:10 +0800 Subject: [PATCH] media: i2c: dw9800w add power control Signed-off-by: Zefa Chen Change-Id: Id5bb35d36c3438a3ddc63b5ba8448703b66b4cbf --- drivers/media/i2c/dw9800w.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/media/i2c/dw9800w.c b/drivers/media/i2c/dw9800w.c index 21fe6a40775b..ce534c9631f4 100644 --- a/drivers/media/i2c/dw9800w.c +++ b/drivers/media/i2c/dw9800w.c @@ -32,6 +32,12 @@ #define DW9800W_CHIP_ID 0xF2 #define DW9800W_REG_CHIP_ID 0x00 +static const char * const dw9800w_supply_names[] = { + "avdd", /* Analog power */ +}; + +#define DW9800W_NUM_SUPPLIES ARRAY_SIZE(dw9800w_supply_names) + enum mode_e { SAC2_MODE, SAC3_MODE, @@ -43,6 +49,7 @@ enum mode_e { /* dw9800w device structure */ struct dw9800w_device { + struct regulator_bulk_data supplies[DW9800W_NUM_SUPPLIES]; struct v4l2_ctrl_handler ctrls_vcm; struct v4l2_ctrl *focus; struct i2c_client *client; @@ -564,9 +571,19 @@ static int dw9800w_init_controls(struct dw9800w_device *dev_vcm) static int __dw9800w_set_power(struct dw9800w_device *dw9800w_dev, bool on) { + int ret = 0; + if (dw9800w_dev->power_gpio) gpiod_direction_output(dw9800w_dev->power_gpio, on); + if (on) { + ret = regulator_bulk_enable(DW9800W_NUM_SUPPLIES, dw9800w_dev->supplies); + if (ret < 0) + dev_err(&dw9800w_dev->client->dev, "Failed to enable regulators\n"); + usleep_range(5000, 6000); + } else { + regulator_bulk_disable(DW9800W_NUM_SUPPLIES, dw9800w_dev->supplies); + } return 0; } @@ -604,6 +621,18 @@ err: return -1; } +static int dw9800w_configure_regulators(struct dw9800w_device *dw9800w_dev) +{ + unsigned int i; + + for (i = 0; i < DW9800W_NUM_SUPPLIES; i++) + dw9800w_dev->supplies[i].supply = dw9800w_supply_names[i]; + + return devm_regulator_bulk_get(&dw9800w_dev->client->dev, + DW9800W_NUM_SUPPLIES, + dw9800w_dev->supplies); +} + static int dw9800w_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -693,6 +722,12 @@ static int dw9800w_probe(struct i2c_client *client, "Failed to get power-gpios, maybe no use\n"); } + ret = dw9800w_configure_regulators(dw9800w_dev); + if (ret) { + dev_err(&client->dev, "Failed to get power regulators\n"); + return ret; + } + ret = dw9800w_check_id(dw9800w_dev); if (ret) goto err_power_off;