Hi, On 15-Mar-25 2:40 PM, Bryan O'Donoghue wrote: > Use regulator_bulk_* to get the array of potential power rails for the > ov02c10. > > The original IPU6 sensor from Intel only has code for avdd but on other > systems such as Qualcomm Co-Pilot laptops we need to manage avdd, dvdd and > dovdd with regulator_bulk_enable/disable. > > Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@xxxxxxxxxx> Ack for this change, is it ok if I squash this into the upcoming v10 ? Regards, Hans > --- > drivers/media/i2c/ov02c10.c | 38 ++++++++++++++++++++----------------- > 1 file changed, 21 insertions(+), 17 deletions(-) > > diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c > index 5626aa2fe62c..f6542cdf7472 100644 > --- a/drivers/media/i2c/ov02c10.c > +++ b/drivers/media/i2c/ov02c10.c > @@ -366,6 +366,12 @@ static const struct ov02c10_mode supported_modes[] = { > }, > }; > > +static const char * const ov02c10_supply_names[] = { > + "dovdd", /* Digital I/O power */ > + "avdd", /* Analog power */ > + "dvdd", /* Digital core power */ > +}; > + > struct ov02c10 { > struct v4l2_subdev sd; > struct media_pad pad; > @@ -380,8 +386,8 @@ struct ov02c10 { > struct v4l2_ctrl *exposure; > > struct clk *img_clk; > - struct regulator *avdd; > struct gpio_desc *reset; > + struct regulator_bulk_data supplies[ARRAY_SIZE(ov02c10_supply_names)]; > > /* Current mode */ > const struct ov02c10_mode *cur_mode; > @@ -632,6 +638,7 @@ static int ov02c10_get_pm_resources(struct device *dev) > { > struct v4l2_subdev *sd = dev_get_drvdata(dev); > struct ov02c10 *ov02c10 = to_ov02c10(sd); > + int i; > > ov02c10->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); > if (IS_ERR(ov02c10->reset)) > @@ -645,28 +652,26 @@ static int ov02c10_get_pm_resources(struct device *dev) > return dev_err_probe(dev, PTR_ERR(ov02c10->img_clk), > "failed to get imaging clock\n"); > > - ov02c10->avdd = devm_regulator_get(dev, "avdd"); > - if (IS_ERR(ov02c10->avdd)) > - return dev_err_probe(dev, PTR_ERR(ov02c10->avdd), > - "failed to get avdd regulator\n"); > + for (i = 0; i < ARRAY_SIZE(ov02c10_supply_names); i++) > + ov02c10->supplies[i].supply = ov02c10_supply_names[i]; > > - return 0; > + return devm_regulator_bulk_get(dev, ARRAY_SIZE(ov02c10_supply_names), > + ov02c10->supplies); > } > > static int ov02c10_power_off(struct device *dev) > { > struct v4l2_subdev *sd = dev_get_drvdata(dev); > struct ov02c10 *ov02c10 = to_ov02c10(sd); > - int ret = 0; > > gpiod_set_value_cansleep(ov02c10->reset, 1); > > - if (ov02c10->avdd) > - ret = regulator_disable(ov02c10->avdd); > + regulator_bulk_disable(ARRAY_SIZE(ov02c10_supply_names), > + ov02c10->supplies); > > clk_disable_unprepare(ov02c10->img_clk); > > - return ret; > + return 0; > } > > static int ov02c10_power_on(struct device *dev) > @@ -681,13 +686,12 @@ static int ov02c10_power_on(struct device *dev) > return ret; > } > > - if (ov02c10->avdd) { > - ret = regulator_enable(ov02c10->avdd); > - if (ret < 0) { > - dev_err(dev, "failed to enable avdd: %d", ret); > - clk_disable_unprepare(ov02c10->img_clk); > - return ret; > - } > + ret = regulator_bulk_enable(ARRAY_SIZE(ov02c10_supply_names), > + ov02c10->supplies); > + if (ret < 0) { > + dev_err(dev, "failed to enable regulators: %d", ret); > + clk_disable_unprepare(ov02c10->img_clk); > + return ret; > } > > gpiod_set_value_cansleep(ov02c10->reset, 0);