backports: add clock enable/disable on soc_camera_power_[on|off]()
authorLuis R. Rodriguez <mcgrof@do-not-panic.com>
Fri, 19 Jul 2013 05:50:51 +0000 (05:50 +0000)
committerLuis R. Rodriguez <mcgrof@do-not-panic.com>
Fri, 19 Jul 2013 22:05:32 +0000 (15:05 -0700)
v4l2-core now supports enabling and disabling its own clock
on turning the camera on / off. We backport v4l2-core fully
so just backport the soc calls appropriately to let SOC cameras
to turn the clock on / off when the v4l2-core clock ops are
implemented on a device driver.

Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com>
backport/backport-include/uapi/linux/v4l2-mediabus.h
backport/compat/compat-3.4.c

index 9979c23f4e88c840813a6ab8880d2a84cc298525..962f044f0604bcdfb23cf42421fac54327283a45 100644 (file)
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
 #if defined(CPTCFG_VIDEO_DEV_MODULE)
 
+#include <media/v4l2-clk.h>
+
 struct soc_camera_subdev_desc;
 
 #define soc_camera_power_on LINUX_BACKPORT(soc_camera_power_on)
 int soc_camera_power_on(struct device *dev,
-                       struct soc_camera_subdev_desc *ssdd);
+                       struct soc_camera_subdev_desc *ssdd,
+                       struct v4l2_clk *clk);
 
 #define soc_camera_power_off LINUX_BACKPORT(soc_camera_power_off)
 int soc_camera_power_off(struct device *dev,
-                       struct soc_camera_subdev_desc *ssdd);
+                       struct soc_camera_subdev_desc *ssdd,
+                       struct v4l2_clk *clk);
 
 #endif /* defined(CPTCFG_VIDEO_DEV_MODULE) */
 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) */
index b72c69c11bf8f70ca66e38c9750f6ba055f0b949..99dfb0cbf042330416ef125517cd71337597f1b9 100644 (file)
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
 
 #if defined(CPTCFG_VIDEO_V4L2_MODULE)
+#include <media/v4l2-clk.h>
 int soc_camera_power_on(struct device *dev,
-                       struct soc_camera_subdev_desc *ssdd)
+                       struct soc_camera_subdev_desc *ssdd,
+                       struct v4l2_clk *clk)
 {
-       int ret = regulator_bulk_enable(ssdd->num_regulators,
+       int ret = clk ? v4l2_clk_enable(clk) : 0;
+       if (ret < 0) {
+               dev_err(dev, "Cannot enable clock: %d\n", ret);
+               return ret;
+       }
+       ret = regulator_bulk_enable(ssdd->num_regulators,
                                        ssdd->regulators);
        if (ret < 0) {
                dev_err(dev, "Cannot enable regulators\n");
-               return ret;
+               goto eregenable;
        }
 
        if (ssdd->power) {
@@ -53,17 +60,26 @@ int soc_camera_power_on(struct device *dev,
                if (ret < 0) {
                        dev_err(dev,
                                "Platform failed to power-on the camera.\n");
-                       regulator_bulk_disable(ssdd->num_regulators,
-                                              ssdd->regulators);
+                       goto epwron;
                }
        }
 
+       return 0;
+
+epwron:
+       regulator_bulk_disable(ssdd->num_regulators,
+                              ssdd->regulators);
+eregenable:
+       if (clk)
+               v4l2_clk_disable(clk);
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(soc_camera_power_on);
 
 int soc_camera_power_off(struct device *dev,
-                        struct soc_camera_subdev_desc *ssdd)
+                        struct soc_camera_subdev_desc *ssdd,
+                        struct v4l2_clk *clk)
 {
        int ret = 0;
        int err;
@@ -84,6 +100,9 @@ int soc_camera_power_off(struct device *dev,
                ret = ret ? : err;
        }
 
+       if (clk)
+               v4l2_clk_disable(clk);
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(soc_camera_power_off);