Re: [PATCH v1 2/2] media: ov02c10: Fix sensor power sequencing
From: Loic Poulain
Date: Fri Oct 23 2026 - 08:54:46 EST
On Thu, Oct 22, 2026 at 9:14 AM Saikiran <bjsaikiran@xxxxxxxxx> wrote:
>
> The OV02C10 driver enables MCLK before the sensor supplies and disables it
> after the supplies. This can back-power the sensor through MCLK while its
> supplies are off and contributes to camera brownouts on the Lenovo Yoga
> Slim 7x.
>
> Follow the power sequence used by the firmware on this platform: enable the
> supplies before MCLK and disable MCLK before the supplies. Hold reset for
> at least 1 ms before disabling MCLK on power-off, and wait at least 10 ms
> after releasing reset on power-on to allow the sensor to start up.
>
> Update the power-on error path to disable the supplies if enabling MCLK
> fails.
>
> Tested-on: Lenovo Yoga Slim 7x (Snapdragon X Elite)
> Signed-off-by: Saikiran <bjsaikiran@xxxxxxxxx>
Should it come with a Fixes tag?
Reviewed-by: Loic Poulain <loic.poulain@xxxxxxxxxxxxxxxx>
> ---
> drivers/media/i2c/ov02c10.c | 20 +++++++++++---------
> 1 file changed, 11 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c
> index 221cb93126ec..42aa43ea0a22 100644
> --- a/drivers/media/i2c/ov02c10.c
> +++ b/drivers/media/i2c/ov02c10.c
> @@ -661,12 +661,13 @@ static int ov02c10_power_off(struct device *dev)
> struct ov02c10 *ov02c10 = to_ov02c10(sd);
>
> gpiod_set_value_cansleep(ov02c10->reset, 1);
> + usleep_range(1000, 1100);
> +
> + clk_disable_unprepare(ov02c10->img_clk);
>
> regulator_bulk_disable(ARRAY_SIZE(ov02c10_supply_names),
> ov02c10->supplies);
>
> - clk_disable_unprepare(ov02c10->img_clk);
> -
> return 0;
> }
>
> @@ -682,23 +683,24 @@ static int ov02c10_power_on(struct device *dev)
> usleep_range(5000, 6000);
> }
>
> - ret = clk_prepare_enable(ov02c10->img_clk);
> + ret = regulator_bulk_enable(ARRAY_SIZE(ov02c10_supply_names),
> + ov02c10->supplies);
> if (ret < 0) {
> - dev_err(dev, "failed to enable imaging clock: %d", ret);
> + dev_err(dev, "failed to enable regulators: %d", ret);
> return ret;
> }
>
> - ret = regulator_bulk_enable(ARRAY_SIZE(ov02c10_supply_names),
> - ov02c10->supplies);
> + ret = clk_prepare_enable(ov02c10->img_clk);
> if (ret < 0) {
> - dev_err(dev, "failed to enable regulators: %d", ret);
> - clk_disable_unprepare(ov02c10->img_clk);
> + dev_err(dev, "failed to enable imaging clock: %d", ret);
> + regulator_bulk_disable(ARRAY_SIZE(ov02c10_supply_names),
> + ov02c10->supplies);
> return ret;
> }
>
> if (ov02c10->reset) {
> gpiod_set_value_cansleep(ov02c10->reset, 0);
> - usleep_range(5000, 5500);
> + usleep_range(10000, 11000);
> }
>
> return 0;
> --
> 2.56.0
>