media: atomisp-ov2680: Turn on power only once
authorHans de Goede <hdegoede@redhat.com>
Sun, 7 Nov 2021 17:15:40 +0000 (17:15 +0000)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Mon, 15 Nov 2021 08:11:53 +0000 (08:11 +0000)
Add a power_on bool to track if the power is on, and make
power_up() a no-op if the power is already on.

This also removes a power_down() call from ov2680_s_config() since
that is a no-op now, this is ok because s_config() is only called
once on probe and the sensor is off at boot.

Besides avoiding to the work in power_up() multiple times this patch
is also a preparation for switching to the clk and regulator frameworks
which keep an enable count, so there we must call enable() and
disable() only once per power-cycle.

Link: https://lore.kernel.org/linux-media/20211107171549.267583-3-hdegoede@redhat.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
drivers/staging/media/atomisp/i2c/ov2680.h

index 56f95e4..7b7cf7a 100644 (file)
@@ -736,6 +736,9 @@ static int power_up(struct v4l2_subdev *sd)
                return -ENODEV;
        }
 
+       if (dev->power_on)
+               return 0; /* Already on */
+
        /* power control */
        ret = power_ctrl(sd, 1);
        if (ret)
@@ -760,6 +763,7 @@ static int power_up(struct v4l2_subdev *sd)
        /* according to DS, 20ms is needed between PWDN and i2c access */
        msleep(20);
 
+       dev->power_on = true;
        return 0;
 
 fail_clk:
@@ -785,6 +789,9 @@ static int power_down(struct v4l2_subdev *sd)
                return -ENODEV;
        }
 
+       if (!dev->power_on)
+               return 0; /* Already off */
+
        ret = dev->platform_data->flisclk_ctrl(sd, 0);
        if (ret)
                dev_err(&client->dev, "flisclk failed\n");
@@ -799,10 +806,13 @@ static int power_down(struct v4l2_subdev *sd)
 
        /* power control */
        ret = power_ctrl(sd, 0);
-       if (ret)
+       if (ret) {
                dev_err(&client->dev, "vprog failed.\n");
+               return ret;
+       }
 
-       return ret;
+       dev->power_on = false;
+       return 0;
 }
 
 static int ov2680_s_power(struct v4l2_subdev *sd, int on)
@@ -866,7 +876,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
        dev_dbg(&client->dev, "%s: %dx%d\n",
                __func__, fmt->width, fmt->height);
 
-       // IS IT NEEDED?
+       /* s_power has not been called yet for std v4l2 clients (camorama) */
        power_up(sd);
        ret = ov2680_write_reg_array(client, dev->res->regs);
        if (ret)
@@ -998,16 +1008,6 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
            (struct camera_sensor_platform_data *)platform_data;
 
        mutex_lock(&dev->input_lock);
-       /*
-        * power off the module, then power on it in future
-        * as first power on by board may not fulfill the
-        * power on sequqence needed by the module
-        */
-       ret = power_down(sd);
-       if (ret) {
-               dev_err(&client->dev, "ov2680 power-off err.\n");
-               goto fail_power_off;
-       }
 
        ret = power_up(sd);
        if (ret) {
@@ -1041,7 +1041,6 @@ fail_csi_cfg:
 fail_power_on:
        power_down(sd);
        dev_err(&client->dev, "sensor power-gating failed\n");
-fail_power_off:
        mutex_unlock(&dev->input_lock);
        return ret;
 }
index 9f9f669..edd87bb 100644 (file)
@@ -173,6 +173,7 @@ struct ov2680_device {
        struct v4l2_ctrl_handler ctrl_handler;
        struct ov2680_resolution *res;
        struct camera_sensor_platform_data *platform_data;
+       bool power_on;
 };
 
 /**