diff options
-rw-r--r-- | drivers/media/video/smiapp/smiapp-core.c | 55 | ||||
-rw-r--r-- | drivers/media/video/smiapp/smiapp.h | 1 | ||||
-rw-r--r-- | include/media/smiapp.h | 1 |
3 files changed, 50 insertions, 7 deletions
diff --git a/drivers/media/video/smiapp/smiapp-core.c b/drivers/media/video/smiapp/smiapp-core.c index a8a1db9563b1..999f3fc867c7 100644 --- a/drivers/media/video/smiapp/smiapp-core.c +++ b/drivers/media/video/smiapp/smiapp-core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/clk.h> | ||
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
30 | #include <linux/device.h> | 31 | #include <linux/device.h> |
31 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
@@ -1111,8 +1112,11 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) | |||
1111 | } | 1112 | } |
1112 | usleep_range(1000, 1000); | 1113 | usleep_range(1000, 1000); |
1113 | 1114 | ||
1114 | rval = sensor->platform_data->set_xclk(&sensor->src->sd, | 1115 | if (sensor->platform_data->set_xclk) |
1115 | sensor->platform_data->ext_clk); | 1116 | rval = sensor->platform_data->set_xclk( |
1117 | &sensor->src->sd, sensor->platform_data->ext_clk); | ||
1118 | else | ||
1119 | rval = clk_enable(sensor->ext_clk); | ||
1116 | if (rval < 0) { | 1120 | if (rval < 0) { |
1117 | dev_dbg(&client->dev, "failed to set xclk\n"); | 1121 | dev_dbg(&client->dev, "failed to set xclk\n"); |
1118 | goto out_xclk_fail; | 1122 | goto out_xclk_fail; |
@@ -1231,7 +1235,10 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) | |||
1231 | out_cci_addr_fail: | 1235 | out_cci_addr_fail: |
1232 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) | 1236 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) |
1233 | gpio_set_value(sensor->platform_data->xshutdown, 0); | 1237 | gpio_set_value(sensor->platform_data->xshutdown, 0); |
1234 | sensor->platform_data->set_xclk(&sensor->src->sd, 0); | 1238 | if (sensor->platform_data->set_xclk) |
1239 | sensor->platform_data->set_xclk(&sensor->src->sd, 0); | ||
1240 | else | ||
1241 | clk_disable(sensor->ext_clk); | ||
1235 | 1242 | ||
1236 | out_xclk_fail: | 1243 | out_xclk_fail: |
1237 | regulator_disable(sensor->vana); | 1244 | regulator_disable(sensor->vana); |
@@ -1256,7 +1263,10 @@ static void smiapp_power_off(struct smiapp_sensor *sensor) | |||
1256 | 1263 | ||
1257 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) | 1264 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) |
1258 | gpio_set_value(sensor->platform_data->xshutdown, 0); | 1265 | gpio_set_value(sensor->platform_data->xshutdown, 0); |
1259 | sensor->platform_data->set_xclk(&sensor->src->sd, 0); | 1266 | if (sensor->platform_data->set_xclk) |
1267 | sensor->platform_data->set_xclk(&sensor->src->sd, 0); | ||
1268 | else | ||
1269 | clk_disable(sensor->ext_clk); | ||
1260 | usleep_range(5000, 5000); | 1270 | usleep_range(5000, 5000); |
1261 | regulator_disable(sensor->vana); | 1271 | regulator_disable(sensor->vana); |
1262 | sensor->streaming = 0; | 1272 | sensor->streaming = 0; |
@@ -2327,6 +2337,28 @@ static int smiapp_registered(struct v4l2_subdev *subdev) | |||
2327 | return -ENODEV; | 2337 | return -ENODEV; |
2328 | } | 2338 | } |
2329 | 2339 | ||
2340 | if (!sensor->platform_data->set_xclk) { | ||
2341 | sensor->ext_clk = clk_get(&client->dev, | ||
2342 | sensor->platform_data->ext_clk_name); | ||
2343 | if (IS_ERR(sensor->ext_clk)) { | ||
2344 | dev_err(&client->dev, "could not get clock %s\n", | ||
2345 | sensor->platform_data->ext_clk_name); | ||
2346 | rval = -ENODEV; | ||
2347 | goto out_clk_get; | ||
2348 | } | ||
2349 | |||
2350 | rval = clk_set_rate(sensor->ext_clk, | ||
2351 | sensor->platform_data->ext_clk); | ||
2352 | if (rval < 0) { | ||
2353 | dev_err(&client->dev, | ||
2354 | "unable to set clock %s freq to %u\n", | ||
2355 | sensor->platform_data->ext_clk_name, | ||
2356 | sensor->platform_data->ext_clk); | ||
2357 | rval = -ENODEV; | ||
2358 | goto out_clk_set_rate; | ||
2359 | } | ||
2360 | } | ||
2361 | |||
2330 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) { | 2362 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) { |
2331 | if (gpio_request_one(sensor->platform_data->xshutdown, 0, | 2363 | if (gpio_request_one(sensor->platform_data->xshutdown, 0, |
2332 | "SMIA++ xshutdown") != 0) { | 2364 | "SMIA++ xshutdown") != 0) { |
@@ -2334,7 +2366,7 @@ static int smiapp_registered(struct v4l2_subdev *subdev) | |||
2334 | "unable to acquire reset gpio %d\n", | 2366 | "unable to acquire reset gpio %d\n", |
2335 | sensor->platform_data->xshutdown); | 2367 | sensor->platform_data->xshutdown); |
2336 | rval = -ENODEV; | 2368 | rval = -ENODEV; |
2337 | goto out_gpio_request; | 2369 | goto out_clk_set_rate; |
2338 | } | 2370 | } |
2339 | } | 2371 | } |
2340 | 2372 | ||
@@ -2589,7 +2621,11 @@ out_smiapp_power_on: | |||
2589 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) | 2621 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) |
2590 | gpio_free(sensor->platform_data->xshutdown); | 2622 | gpio_free(sensor->platform_data->xshutdown); |
2591 | 2623 | ||
2592 | out_gpio_request: | 2624 | out_clk_set_rate: |
2625 | clk_put(sensor->ext_clk); | ||
2626 | sensor->ext_clk = NULL; | ||
2627 | |||
2628 | out_clk_get: | ||
2593 | regulator_put(sensor->vana); | 2629 | regulator_put(sensor->vana); |
2594 | sensor->vana = NULL; | 2630 | sensor->vana = NULL; |
2595 | return rval; | 2631 | return rval; |
@@ -2778,7 +2814,10 @@ static int __exit smiapp_remove(struct i2c_client *client) | |||
2778 | if (sensor->power_count) { | 2814 | if (sensor->power_count) { |
2779 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) | 2815 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) |
2780 | gpio_set_value(sensor->platform_data->xshutdown, 0); | 2816 | gpio_set_value(sensor->platform_data->xshutdown, 0); |
2781 | sensor->platform_data->set_xclk(&sensor->src->sd, 0); | 2817 | if (sensor->platform_data->set_xclk) |
2818 | sensor->platform_data->set_xclk(&sensor->src->sd, 0); | ||
2819 | else | ||
2820 | clk_disable(sensor->ext_clk); | ||
2782 | sensor->power_count = 0; | 2821 | sensor->power_count = 0; |
2783 | } | 2822 | } |
2784 | 2823 | ||
@@ -2794,6 +2833,8 @@ static int __exit smiapp_remove(struct i2c_client *client) | |||
2794 | smiapp_free_controls(sensor); | 2833 | smiapp_free_controls(sensor); |
2795 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) | 2834 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) |
2796 | gpio_free(sensor->platform_data->xshutdown); | 2835 | gpio_free(sensor->platform_data->xshutdown); |
2836 | if (sensor->ext_clk) | ||
2837 | clk_put(sensor->ext_clk); | ||
2797 | if (sensor->vana) | 2838 | if (sensor->vana) |
2798 | regulator_put(sensor->vana); | 2839 | regulator_put(sensor->vana); |
2799 | 2840 | ||
diff --git a/drivers/media/video/smiapp/smiapp.h b/drivers/media/video/smiapp/smiapp.h index 35b9216e48cd..587f7f11238d 100644 --- a/drivers/media/video/smiapp/smiapp.h +++ b/drivers/media/video/smiapp/smiapp.h | |||
@@ -198,6 +198,7 @@ struct smiapp_sensor { | |||
198 | struct smiapp_subdev *pixel_array; | 198 | struct smiapp_subdev *pixel_array; |
199 | struct smiapp_platform_data *platform_data; | 199 | struct smiapp_platform_data *platform_data; |
200 | struct regulator *vana; | 200 | struct regulator *vana; |
201 | struct clk *ext_clk; | ||
201 | u32 limits[SMIAPP_LIMIT_LAST]; | 202 | u32 limits[SMIAPP_LIMIT_LAST]; |
202 | u8 nbinning_subtypes; | 203 | u8 nbinning_subtypes; |
203 | struct smiapp_binning_subtype binning_subtypes[SMIAPP_BINNING_SUBTYPES]; | 204 | struct smiapp_binning_subtype binning_subtypes[SMIAPP_BINNING_SUBTYPES]; |
diff --git a/include/media/smiapp.h b/include/media/smiapp.h index a7877cd0733d..9ab07fd45d5c 100644 --- a/include/media/smiapp.h +++ b/include/media/smiapp.h | |||
@@ -77,6 +77,7 @@ struct smiapp_platform_data { | |||
77 | struct smiapp_flash_strobe_parms *strobe_setup; | 77 | struct smiapp_flash_strobe_parms *strobe_setup; |
78 | 78 | ||
79 | int (*set_xclk)(struct v4l2_subdev *sd, int hz); | 79 | int (*set_xclk)(struct v4l2_subdev *sd, int hz); |
80 | char *ext_clk_name; | ||
80 | int xshutdown; /* gpio or SMIAPP_NO_XSHUTDOWN */ | 81 | int xshutdown; /* gpio or SMIAPP_NO_XSHUTDOWN */ |
81 | }; | 82 | }; |
82 | 83 | ||