From bedf6b87ad311e97254f3e9144202dc7d3bb5d48 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 19 Jul 2013 05:50:51 +0000 Subject: [PATCH] backports: add clock enable/disable on soc_camera_power_[on|off]() 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 --- .../uapi/linux/v4l2-mediabus.h | 8 +++-- backport/compat/compat-3.4.c | 31 +++++++++++++++---- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/backport/backport-include/uapi/linux/v4l2-mediabus.h b/backport/backport-include/uapi/linux/v4l2-mediabus.h index 9979c23f4e88..962f044f0604 100644 --- a/backport/backport-include/uapi/linux/v4l2-mediabus.h +++ b/backport/backport-include/uapi/linux/v4l2-mediabus.h @@ -20,15 +20,19 @@ #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) #if defined(CPTCFG_VIDEO_DEV_MODULE) +#include + 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)) */ diff --git a/backport/compat/compat-3.4.c b/backport/compat/compat-3.4.c index b72c69c11bf8..99dfb0cbf042 100644 --- a/backport/compat/compat-3.4.c +++ b/backport/compat/compat-3.4.c @@ -38,14 +38,21 @@ #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) #if defined(CPTCFG_VIDEO_V4L2_MODULE) +#include 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); -- 2.30.2