aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/soc_camera/soc_camera.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/soc_camera/soc_camera.c')
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 387a232d95a4..4b8c024fc487 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -71,13 +71,23 @@ static int video_dev_create(struct soc_camera_device *icd);
71int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd, 71int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd,
72 struct v4l2_clk *clk) 72 struct v4l2_clk *clk)
73{ 73{
74 int ret = clk ? v4l2_clk_enable(clk) : 0; 74 int ret;
75 if (ret < 0) { 75 bool clock_toggle;
76 dev_err(dev, "Cannot enable clock: %d\n", ret); 76
77 return ret; 77 if (clk && (!ssdd->unbalanced_power ||
78 !test_and_set_bit(0, &ssdd->clock_state))) {
79 ret = v4l2_clk_enable(clk);
80 if (ret < 0) {
81 dev_err(dev, "Cannot enable clock: %d\n", ret);
82 return ret;
83 }
84 clock_toggle = true;
85 } else {
86 clock_toggle = false;
78 } 87 }
79 ret = regulator_bulk_enable(ssdd->num_regulators, 88
80 ssdd->regulators); 89 ret = regulator_bulk_enable(ssdd->sd_pdata.num_regulators,
90 ssdd->sd_pdata.regulators);
81 if (ret < 0) { 91 if (ret < 0) {
82 dev_err(dev, "Cannot enable regulators\n"); 92 dev_err(dev, "Cannot enable regulators\n");
83 goto eregenable; 93 goto eregenable;
@@ -95,10 +105,10 @@ int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd,
95 return 0; 105 return 0;
96 106
97epwron: 107epwron:
98 regulator_bulk_disable(ssdd->num_regulators, 108 regulator_bulk_disable(ssdd->sd_pdata.num_regulators,
99 ssdd->regulators); 109 ssdd->sd_pdata.regulators);
100eregenable: 110eregenable:
101 if (clk) 111 if (clock_toggle)
102 v4l2_clk_disable(clk); 112 v4l2_clk_disable(clk);
103 113
104 return ret; 114 return ret;
@@ -120,14 +130,14 @@ int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd
120 } 130 }
121 } 131 }
122 132
123 err = regulator_bulk_disable(ssdd->num_regulators, 133 err = regulator_bulk_disable(ssdd->sd_pdata.num_regulators,
124 ssdd->regulators); 134 ssdd->sd_pdata.regulators);
125 if (err < 0) { 135 if (err < 0) {
126 dev_err(dev, "Cannot disable regulators\n"); 136 dev_err(dev, "Cannot disable regulators\n");
127 ret = ret ? : err; 137 ret = ret ? : err;
128 } 138 }
129 139
130 if (clk) 140 if (clk && (!ssdd->unbalanced_power || test_and_clear_bit(0, &ssdd->clock_state)))
131 v4l2_clk_disable(clk); 141 v4l2_clk_disable(clk);
132 142
133 return ret; 143 return ret;
@@ -137,8 +147,8 @@ EXPORT_SYMBOL(soc_camera_power_off);
137int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd) 147int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd)
138{ 148{
139 /* Should not have any effect in synchronous case */ 149 /* Should not have any effect in synchronous case */
140 return devm_regulator_bulk_get(dev, ssdd->num_regulators, 150 return devm_regulator_bulk_get(dev, ssdd->sd_pdata.num_regulators,
141 ssdd->regulators); 151 ssdd->sd_pdata.regulators);
142} 152}
143EXPORT_SYMBOL(soc_camera_power_init); 153EXPORT_SYMBOL(soc_camera_power_init);
144 154
@@ -1346,8 +1356,8 @@ static int soc_camera_i2c_init(struct soc_camera_device *icd,
1346 * soc_camera_pdrv_probe(), make sure the subdevice driver doesn't try 1356 * soc_camera_pdrv_probe(), make sure the subdevice driver doesn't try
1347 * to allocate them again. 1357 * to allocate them again.
1348 */ 1358 */
1349 ssdd->num_regulators = 0; 1359 ssdd->sd_pdata.num_regulators = 0;
1350 ssdd->regulators = NULL; 1360 ssdd->sd_pdata.regulators = NULL;
1351 shd->board_info->platform_data = ssdd; 1361 shd->board_info->platform_data = ssdd;
1352 1362
1353 snprintf(clk_name, sizeof(clk_name), "%d-%04x", 1363 snprintf(clk_name, sizeof(clk_name), "%d-%04x",
@@ -2020,8 +2030,8 @@ static int soc_camera_pdrv_probe(struct platform_device *pdev)
2020 * that case regulators are attached to the I2C device and not to the 2030 * that case regulators are attached to the I2C device and not to the
2021 * camera platform device. 2031 * camera platform device.
2022 */ 2032 */
2023 ret = devm_regulator_bulk_get(&pdev->dev, ssdd->num_regulators, 2033 ret = devm_regulator_bulk_get(&pdev->dev, ssdd->sd_pdata.num_regulators,
2024 ssdd->regulators); 2034 ssdd->sd_pdata.regulators);
2025 if (ret < 0) 2035 if (ret < 0)
2026 return ret; 2036 return ret;
2027 2037