diff options
Diffstat (limited to 'arch/arm/mach-tegra/board-cardhu-sensors.c')
-rw-r--r-- | arch/arm/mach-tegra/board-cardhu-sensors.c | 1001 |
1 files changed, 1001 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu-sensors.c b/arch/arm/mach-tegra/board-cardhu-sensors.c new file mode 100644 index 00000000000..5e39e347993 --- /dev/null +++ b/arch/arm/mach-tegra/board-cardhu-sensors.c | |||
@@ -0,0 +1,1001 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/board-cardhu-sensors.c | ||
3 | * | ||
4 | * Copyright (c) 2010-2011, NVIDIA CORPORATION, All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are | ||
8 | * met: | ||
9 | * | ||
10 | * Redistributions of source code must retain the above copyright notice, | ||
11 | * this list of conditions and the following disclaimer. | ||
12 | * | ||
13 | * Redistributions in binary form must reproduce the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer in the | ||
15 | * documentation and/or other materials provided with the distribution. | ||
16 | * | ||
17 | * Neither the name of NVIDIA CORPORATION nor the names of its contributors | ||
18 | * may be used to endorse or promote products derived from this software | ||
19 | * without specific prior written permission. | ||
20 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
25 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | ||
27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
32 | */ | ||
33 | |||
34 | #include <linux/i2c.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/regulator/consumer.h> | ||
37 | #include <linux/i2c/pca954x.h> | ||
38 | #include <linux/i2c/pca953x.h> | ||
39 | #include <linux/nct1008.h> | ||
40 | #include <mach/fb.h> | ||
41 | #include <mach/gpio.h> | ||
42 | #include <media/ov5650.h> | ||
43 | #include <media/ov14810.h> | ||
44 | #include <media/ov2710.h> | ||
45 | #include <media/tps61050.h> | ||
46 | #include <generated/mach-types.h> | ||
47 | #include "gpio-names.h" | ||
48 | #include "board.h" | ||
49 | #include <linux/mpu.h> | ||
50 | #include <media/sh532u.h> | ||
51 | #include <linux/bq27x00.h> | ||
52 | #include <mach/gpio.h> | ||
53 | #include <mach/edp.h> | ||
54 | #include <mach/thermal.h> | ||
55 | |||
56 | #include "gpio-names.h" | ||
57 | #include "board-cardhu.h" | ||
58 | #include "cpu-tegra.h" | ||
59 | |||
60 | static struct regulator *cardhu_1v8_cam1 = NULL; | ||
61 | static struct regulator *cardhu_1v8_cam2 = NULL; | ||
62 | static struct regulator *cardhu_1v8_cam3 = NULL; | ||
63 | static struct regulator *cardhu_vdd_2v8_cam1 = NULL; | ||
64 | static struct regulator *cardhu_vdd_2v8_cam2 = NULL; | ||
65 | static struct regulator *cardhu_vdd_cam3 = NULL; | ||
66 | |||
67 | static struct board_info board_info; | ||
68 | |||
69 | static struct pca954x_platform_mode cardhu_pca954x_modes[] = { | ||
70 | { .adap_id = PCA954x_I2C_BUS0, .deselect_on_exit = true, }, | ||
71 | { .adap_id = PCA954x_I2C_BUS1, .deselect_on_exit = true, }, | ||
72 | { .adap_id = PCA954x_I2C_BUS2, .deselect_on_exit = true, }, | ||
73 | { .adap_id = PCA954x_I2C_BUS3, .deselect_on_exit = true, }, | ||
74 | }; | ||
75 | |||
76 | static struct pca954x_platform_data cardhu_pca954x_data = { | ||
77 | .modes = cardhu_pca954x_modes, | ||
78 | .num_modes = ARRAY_SIZE(cardhu_pca954x_modes), | ||
79 | }; | ||
80 | |||
81 | static int cardhu_camera_init(void) | ||
82 | { | ||
83 | int ret; | ||
84 | |||
85 | /* Boards E1198 and E1291 are of Cardhu personality | ||
86 | * and donot have TCA6416 exp for camera */ | ||
87 | if ((board_info.board_id == BOARD_E1198) || | ||
88 | (board_info.board_id == BOARD_E1291)) { | ||
89 | tegra_gpio_enable(CAM1_POWER_DWN_GPIO); | ||
90 | ret = gpio_request(CAM1_POWER_DWN_GPIO, "camera_power_en"); | ||
91 | if (ret < 0) | ||
92 | pr_err("%s: gpio_request failed for gpio %s\n", | ||
93 | __func__, "CAM1_POWER_DWN_GPIO"); | ||
94 | tegra_gpio_enable(CAM3_POWER_DWN_GPIO); | ||
95 | ret = gpio_request(CAM3_POWER_DWN_GPIO, "cam3_power_en"); | ||
96 | if (ret < 0) | ||
97 | pr_err("%s: gpio_request failed for gpio %s\n", | ||
98 | __func__, "CAM3_POWER_DWN_GPIO"); | ||
99 | |||
100 | tegra_gpio_enable(CAM2_POWER_DWN_GPIO); | ||
101 | ret = gpio_request(CAM2_POWER_DWN_GPIO, "camera2_power_en"); | ||
102 | if (ret < 0) | ||
103 | pr_err("%s: gpio_request failed for gpio %s\n", | ||
104 | __func__, "CAM2_POWER_DWN_GPIO"); | ||
105 | |||
106 | tegra_gpio_enable(OV5650_RESETN_GPIO); | ||
107 | ret = gpio_request(OV5650_RESETN_GPIO, "camera_reset"); | ||
108 | if (ret < 0) | ||
109 | pr_err("%s: gpio_request failed for gpio %s\n", | ||
110 | __func__, "OV5650_RESETN_GPIO"); | ||
111 | |||
112 | gpio_direction_output(CAM3_POWER_DWN_GPIO, 1); | ||
113 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 1); | ||
114 | gpio_direction_output(CAM2_POWER_DWN_GPIO, 1); | ||
115 | mdelay(10); | ||
116 | |||
117 | gpio_direction_output(OV5650_RESETN_GPIO, 1); | ||
118 | mdelay(5); | ||
119 | gpio_direction_output(OV5650_RESETN_GPIO, 0); | ||
120 | mdelay(5); | ||
121 | gpio_direction_output(OV5650_RESETN_GPIO, 1); | ||
122 | mdelay(5); | ||
123 | } | ||
124 | |||
125 | /* To select the CSIB MUX either for cam2 or cam3 */ | ||
126 | tegra_gpio_enable(CAMERA_CSI_MUX_SEL_GPIO); | ||
127 | ret = gpio_request(CAMERA_CSI_MUX_SEL_GPIO, "camera_csi_sel"); | ||
128 | if (ret < 0) | ||
129 | pr_err("%s: gpio_request failed for gpio %s\n", | ||
130 | __func__, "CAMERA_CSI_MUX_SEL_GPIO"); | ||
131 | gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 0); | ||
132 | gpio_export(CAMERA_CSI_MUX_SEL_GPIO, false); | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static int cardhu_left_ov5650_power_on(void) | ||
138 | { | ||
139 | /* Boards E1198 and E1291 are of Cardhu personality | ||
140 | * and donot have TCA6416 exp for camera */ | ||
141 | if ((board_info.board_id == BOARD_E1198) || | ||
142 | (board_info.board_id == BOARD_E1291)) { | ||
143 | |||
144 | if (cardhu_vdd_2v8_cam1 == NULL) { | ||
145 | cardhu_vdd_2v8_cam1 = regulator_get(NULL, "vdd_2v8_cam1"); | ||
146 | if (WARN_ON(IS_ERR(cardhu_vdd_2v8_cam1))) { | ||
147 | pr_err("%s: couldn't get regulator vdd_2v8_cam1: %ld\n", | ||
148 | __func__, PTR_ERR(cardhu_vdd_2v8_cam1)); | ||
149 | goto reg_alloc_fail; | ||
150 | } | ||
151 | } | ||
152 | regulator_enable(cardhu_vdd_2v8_cam1); | ||
153 | mdelay(5); | ||
154 | } | ||
155 | |||
156 | /* Enable VDD_1V8_Cam1 */ | ||
157 | if (cardhu_1v8_cam1 == NULL) { | ||
158 | cardhu_1v8_cam1 = regulator_get(NULL, "vdd_1v8_cam1"); | ||
159 | if (WARN_ON(IS_ERR(cardhu_1v8_cam1))) { | ||
160 | pr_err("%s: couldn't get regulator vdd_1v8_cam1: %ld\n", | ||
161 | __func__, PTR_ERR(cardhu_1v8_cam1)); | ||
162 | goto reg_alloc_fail; | ||
163 | } | ||
164 | } | ||
165 | regulator_enable(cardhu_1v8_cam1); | ||
166 | |||
167 | mdelay(5); | ||
168 | if ((board_info.board_id == BOARD_E1198) || | ||
169 | (board_info.board_id == BOARD_E1291)) { | ||
170 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 0); | ||
171 | mdelay(20); | ||
172 | gpio_direction_output(OV5650_RESETN_GPIO, 0); | ||
173 | mdelay(100); | ||
174 | gpio_direction_output(OV5650_RESETN_GPIO, 1); | ||
175 | } | ||
176 | |||
177 | if (board_info.board_id == BOARD_PM269) { | ||
178 | gpio_direction_output(CAM1_RST_L_GPIO, 0); | ||
179 | mdelay(100); | ||
180 | gpio_direction_output(CAM1_RST_L_GPIO, 1); | ||
181 | } | ||
182 | |||
183 | return 0; | ||
184 | |||
185 | reg_alloc_fail: | ||
186 | if (cardhu_1v8_cam1) { | ||
187 | regulator_put(cardhu_1v8_cam1); | ||
188 | cardhu_1v8_cam1 = NULL; | ||
189 | } | ||
190 | if (cardhu_vdd_2v8_cam1) { | ||
191 | regulator_put(cardhu_vdd_2v8_cam1); | ||
192 | cardhu_vdd_2v8_cam1 = NULL; | ||
193 | } | ||
194 | |||
195 | return -ENODEV; | ||
196 | |||
197 | } | ||
198 | |||
199 | static int cardhu_left_ov5650_power_off(void) | ||
200 | { | ||
201 | /* Boards E1198 and E1291 are of Cardhu personality | ||
202 | * and donot have TCA6416 exp for camera */ | ||
203 | if ((board_info.board_id == BOARD_E1198) || | ||
204 | (board_info.board_id == BOARD_E1291)) { | ||
205 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 1); | ||
206 | gpio_direction_output(CAM2_POWER_DWN_GPIO, 1); | ||
207 | gpio_direction_output(CAM3_POWER_DWN_GPIO, 1); | ||
208 | } | ||
209 | if (cardhu_1v8_cam1) | ||
210 | regulator_disable(cardhu_1v8_cam1); | ||
211 | if (cardhu_vdd_2v8_cam1) | ||
212 | regulator_disable(cardhu_vdd_2v8_cam1); | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | struct ov5650_platform_data cardhu_left_ov5650_data = { | ||
218 | .power_on = cardhu_left_ov5650_power_on, | ||
219 | .power_off = cardhu_left_ov5650_power_off, | ||
220 | }; | ||
221 | |||
222 | #ifdef CONFIG_VIDEO_OV14810 | ||
223 | static int cardhu_ov14810_power_on(void) | ||
224 | { | ||
225 | if (board_info.board_id == BOARD_E1198) { | ||
226 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 1); | ||
227 | mdelay(20); | ||
228 | gpio_direction_output(OV14810_RESETN_GPIO, 0); | ||
229 | mdelay(100); | ||
230 | gpio_direction_output(OV14810_RESETN_GPIO, 1); | ||
231 | } | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int cardhu_ov14810_power_off(void) | ||
237 | { | ||
238 | if (board_info.board_id == BOARD_E1198) { | ||
239 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 1); | ||
240 | gpio_direction_output(CAM2_POWER_DWN_GPIO, 1); | ||
241 | gpio_direction_output(CAM3_POWER_DWN_GPIO, 1); | ||
242 | } | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | struct ov14810_platform_data cardhu_ov14810_data = { | ||
248 | .power_on = cardhu_ov14810_power_on, | ||
249 | .power_off = cardhu_ov14810_power_off, | ||
250 | }; | ||
251 | |||
252 | struct ov14810_platform_data cardhu_ov14810uC_data = { | ||
253 | .power_on = NULL, | ||
254 | .power_off = NULL, | ||
255 | }; | ||
256 | |||
257 | struct ov14810_platform_data cardhu_ov14810SlaveDev_data = { | ||
258 | .power_on = NULL, | ||
259 | .power_off = NULL, | ||
260 | }; | ||
261 | |||
262 | static struct i2c_board_info cardhu_i2c_board_info_e1214[] = { | ||
263 | { | ||
264 | I2C_BOARD_INFO("ov14810", 0x36), | ||
265 | .platform_data = &cardhu_ov14810_data, | ||
266 | }, | ||
267 | { | ||
268 | I2C_BOARD_INFO("ov14810uC", 0x67), | ||
269 | .platform_data = &cardhu_ov14810uC_data, | ||
270 | }, | ||
271 | { | ||
272 | I2C_BOARD_INFO("ov14810SlaveDev", 0x69), | ||
273 | .platform_data = &cardhu_ov14810SlaveDev_data, | ||
274 | } | ||
275 | }; | ||
276 | #endif | ||
277 | |||
278 | static int cardhu_right_ov5650_power_on(void) | ||
279 | { | ||
280 | /* CSI-B and front sensor are muxed on cardhu */ | ||
281 | gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 0); | ||
282 | |||
283 | /* Boards E1198 and E1291 are of Cardhu personality | ||
284 | * and donot have TCA6416 exp for camera */ | ||
285 | if ((board_info.board_id == BOARD_E1198) || | ||
286 | (board_info.board_id == BOARD_E1291)) { | ||
287 | |||
288 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 0); | ||
289 | gpio_direction_output(CAM2_POWER_DWN_GPIO, 0); | ||
290 | mdelay(10); | ||
291 | |||
292 | if (cardhu_vdd_2v8_cam2 == NULL) { | ||
293 | cardhu_vdd_2v8_cam2 = regulator_get(NULL, "vdd_2v8_cam2"); | ||
294 | if (WARN_ON(IS_ERR(cardhu_vdd_2v8_cam2))) { | ||
295 | pr_err("%s: couldn't get regulator vdd_2v8_cam2: %ld\n", | ||
296 | __func__, PTR_ERR(cardhu_vdd_2v8_cam2)); | ||
297 | goto reg_alloc_fail; | ||
298 | } | ||
299 | } | ||
300 | regulator_enable(cardhu_vdd_2v8_cam2); | ||
301 | mdelay(5); | ||
302 | } | ||
303 | |||
304 | /* Enable VDD_1V8_Cam2 */ | ||
305 | if (cardhu_1v8_cam2 == NULL) { | ||
306 | cardhu_1v8_cam2 = regulator_get(NULL, "vdd_1v8_cam2"); | ||
307 | if (WARN_ON(IS_ERR(cardhu_1v8_cam2))) { | ||
308 | pr_err("%s: couldn't get regulator vdd_1v8_cam2: %ld\n", | ||
309 | __func__, PTR_ERR(cardhu_1v8_cam2)); | ||
310 | goto reg_alloc_fail; | ||
311 | } | ||
312 | } | ||
313 | regulator_enable(cardhu_1v8_cam2); | ||
314 | |||
315 | mdelay(5); | ||
316 | |||
317 | if (board_info.board_id == BOARD_PM269) { | ||
318 | gpio_direction_output(CAM2_RST_L_GPIO, 0); | ||
319 | mdelay(100); | ||
320 | gpio_direction_output(CAM2_RST_L_GPIO, 1); | ||
321 | } | ||
322 | |||
323 | return 0; | ||
324 | |||
325 | reg_alloc_fail: | ||
326 | if (cardhu_1v8_cam2) { | ||
327 | regulator_put(cardhu_1v8_cam2); | ||
328 | cardhu_1v8_cam2 = NULL; | ||
329 | } | ||
330 | if (cardhu_vdd_2v8_cam2) { | ||
331 | regulator_put(cardhu_vdd_2v8_cam2); | ||
332 | cardhu_vdd_2v8_cam2 = NULL; | ||
333 | } | ||
334 | |||
335 | return -ENODEV; | ||
336 | |||
337 | } | ||
338 | |||
339 | static int cardhu_right_ov5650_power_off(void) | ||
340 | { | ||
341 | /* CSI-B and front sensor are muxed on cardhu */ | ||
342 | gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 0); | ||
343 | |||
344 | /* Boards E1198 and E1291 are of Cardhu personality | ||
345 | * and donot have TCA6416 exp for camera */ | ||
346 | if ((board_info.board_id == BOARD_E1198) || | ||
347 | (board_info.board_id == BOARD_E1291)) { | ||
348 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 1); | ||
349 | gpio_direction_output(CAM2_POWER_DWN_GPIO, 1); | ||
350 | gpio_direction_output(CAM3_POWER_DWN_GPIO, 1); | ||
351 | } | ||
352 | |||
353 | if (cardhu_1v8_cam2) | ||
354 | regulator_disable(cardhu_1v8_cam2); | ||
355 | if (cardhu_vdd_2v8_cam2) | ||
356 | regulator_disable(cardhu_vdd_2v8_cam2); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | static void cardhu_ov5650_synchronize_sensors(void) | ||
362 | { | ||
363 | if (board_info.board_id == BOARD_E1198) { | ||
364 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 1); | ||
365 | mdelay(50); | ||
366 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 0); | ||
367 | mdelay(50); | ||
368 | } | ||
369 | else if (board_info.board_id == BOARD_E1291) { | ||
370 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 1); | ||
371 | gpio_direction_output(CAM2_POWER_DWN_GPIO, 1); | ||
372 | mdelay(50); | ||
373 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 0); | ||
374 | gpio_direction_output(CAM2_POWER_DWN_GPIO, 0); | ||
375 | mdelay(50); | ||
376 | } | ||
377 | else | ||
378 | pr_err("%s: UnSupported BoardId\n", __func__); | ||
379 | } | ||
380 | |||
381 | struct ov5650_platform_data cardhu_right_ov5650_data = { | ||
382 | .power_on = cardhu_right_ov5650_power_on, | ||
383 | .power_off = cardhu_right_ov5650_power_off, | ||
384 | .synchronize_sensors = cardhu_ov5650_synchronize_sensors, | ||
385 | }; | ||
386 | |||
387 | static int cardhu_ov2710_power_on(void) | ||
388 | { | ||
389 | /* CSI-B and front sensor are muxed on cardhu */ | ||
390 | gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 1); | ||
391 | |||
392 | /* Boards E1198 and E1291 are of Cardhu personality | ||
393 | * and donot have TCA6416 exp for camera */ | ||
394 | if ((board_info.board_id == BOARD_E1198) || | ||
395 | (board_info.board_id == BOARD_E1291)) { | ||
396 | |||
397 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 0); | ||
398 | gpio_direction_output(CAM2_POWER_DWN_GPIO, 0); | ||
399 | gpio_direction_output(CAM3_POWER_DWN_GPIO, 0); | ||
400 | mdelay(10); | ||
401 | |||
402 | if (cardhu_vdd_cam3 == NULL) { | ||
403 | cardhu_vdd_cam3 = regulator_get(NULL, "vdd_cam3"); | ||
404 | if (WARN_ON(IS_ERR(cardhu_vdd_cam3))) { | ||
405 | pr_err("%s: couldn't get regulator vdd_cam3: %ld\n", | ||
406 | __func__, PTR_ERR(cardhu_vdd_cam3)); | ||
407 | goto reg_alloc_fail; | ||
408 | } | ||
409 | } | ||
410 | regulator_enable(cardhu_vdd_cam3); | ||
411 | } | ||
412 | |||
413 | /* Enable VDD_1V8_Cam3 */ | ||
414 | if (cardhu_1v8_cam3 == NULL) { | ||
415 | cardhu_1v8_cam3 = regulator_get(NULL, "vdd_1v8_cam3"); | ||
416 | if (WARN_ON(IS_ERR(cardhu_1v8_cam3))) { | ||
417 | pr_err("%s: couldn't get regulator vdd_1v8_cam3: %ld\n", | ||
418 | __func__, PTR_ERR(cardhu_1v8_cam3)); | ||
419 | goto reg_alloc_fail; | ||
420 | } | ||
421 | } | ||
422 | regulator_enable(cardhu_1v8_cam3); | ||
423 | mdelay(5); | ||
424 | |||
425 | return 0; | ||
426 | |||
427 | reg_alloc_fail: | ||
428 | if (cardhu_1v8_cam3) { | ||
429 | regulator_put(cardhu_1v8_cam3); | ||
430 | cardhu_1v8_cam3 = NULL; | ||
431 | } | ||
432 | if (cardhu_vdd_cam3) { | ||
433 | regulator_put(cardhu_vdd_cam3); | ||
434 | cardhu_vdd_cam3 = NULL; | ||
435 | } | ||
436 | |||
437 | return -ENODEV; | ||
438 | } | ||
439 | |||
440 | static int cardhu_ov2710_power_off(void) | ||
441 | { | ||
442 | /* CSI-B and front sensor are muxed on cardhu */ | ||
443 | gpio_direction_output(CAMERA_CSI_MUX_SEL_GPIO, 1); | ||
444 | |||
445 | /* Boards E1198 and E1291 are of Cardhu personality | ||
446 | * and donot have TCA6416 exp for camera */ | ||
447 | if ((board_info.board_id == BOARD_E1198) || | ||
448 | (board_info.board_id == BOARD_E1291)) { | ||
449 | gpio_direction_output(CAM1_POWER_DWN_GPIO, 1); | ||
450 | gpio_direction_output(CAM2_POWER_DWN_GPIO, 1); | ||
451 | gpio_direction_output(CAM3_POWER_DWN_GPIO, 1); | ||
452 | } | ||
453 | |||
454 | if (cardhu_1v8_cam3) | ||
455 | regulator_disable(cardhu_1v8_cam3); | ||
456 | if (cardhu_vdd_cam3) | ||
457 | regulator_disable(cardhu_vdd_cam3); | ||
458 | |||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | struct ov2710_platform_data cardhu_ov2710_data = { | ||
463 | .power_on = cardhu_ov2710_power_on, | ||
464 | .power_off = cardhu_ov2710_power_off, | ||
465 | }; | ||
466 | |||
467 | static const struct i2c_board_info cardhu_i2c3_board_info[] = { | ||
468 | { | ||
469 | I2C_BOARD_INFO("pca9546", 0x70), | ||
470 | .platform_data = &cardhu_pca954x_data, | ||
471 | }, | ||
472 | }; | ||
473 | |||
474 | static struct sh532u_platform_data sh532u_left_pdata = { | ||
475 | .num = 1, | ||
476 | .sync = 2, | ||
477 | .dev_name = "focuser", | ||
478 | .gpio_reset = TEGRA_GPIO_PBB0, | ||
479 | }; | ||
480 | |||
481 | static struct sh532u_platform_data sh532u_right_pdata = { | ||
482 | .num = 2, | ||
483 | .sync = 1, | ||
484 | .dev_name = "focuser", | ||
485 | .gpio_reset = TEGRA_GPIO_PBB0, | ||
486 | }; | ||
487 | |||
488 | static struct sh532u_platform_data pm269_sh532u_left_pdata = { | ||
489 | .num = 1, | ||
490 | .sync = 2, | ||
491 | .dev_name = "focuser", | ||
492 | .gpio_reset = CAM1_RST_L_GPIO, | ||
493 | }; | ||
494 | |||
495 | static struct sh532u_platform_data pm269_sh532u_right_pdata = { | ||
496 | .num = 2, | ||
497 | .sync = 1, | ||
498 | .dev_name = "focuser", | ||
499 | .gpio_reset = CAM2_RST_L_GPIO, | ||
500 | }; | ||
501 | |||
502 | static struct nvc_torch_pin_state cardhu_tps61050_pinstate = { | ||
503 | .mask = 0x0008, /*VGP3*/ | ||
504 | .values = 0x0008, | ||
505 | }; | ||
506 | |||
507 | static struct tps61050_platform_data cardhu_tps61050_pdata = { | ||
508 | .dev_name = "torch", | ||
509 | .pinstate = &cardhu_tps61050_pinstate, | ||
510 | }; | ||
511 | |||
512 | static const struct i2c_board_info cardhu_i2c_board_info_tps61050[] = { | ||
513 | { | ||
514 | I2C_BOARD_INFO("tps61050", 0x33), | ||
515 | .platform_data = &cardhu_tps61050_pdata, | ||
516 | }, | ||
517 | }; | ||
518 | |||
519 | static struct i2c_board_info cardhu_i2c6_board_info[] = { | ||
520 | { | ||
521 | I2C_BOARD_INFO("ov5650L", 0x36), | ||
522 | .platform_data = &cardhu_left_ov5650_data, | ||
523 | }, | ||
524 | { | ||
525 | I2C_BOARD_INFO("sh532u", 0x72), | ||
526 | .platform_data = &sh532u_left_pdata, | ||
527 | }, | ||
528 | }; | ||
529 | |||
530 | static struct i2c_board_info cardhu_i2c7_board_info[] = { | ||
531 | { | ||
532 | I2C_BOARD_INFO("ov5650R", 0x36), | ||
533 | .platform_data = &cardhu_right_ov5650_data, | ||
534 | }, | ||
535 | { | ||
536 | I2C_BOARD_INFO("sh532u", 0x72), | ||
537 | .platform_data = &sh532u_right_pdata, | ||
538 | }, | ||
539 | }; | ||
540 | |||
541 | static struct i2c_board_info pm269_i2c6_board_info[] = { | ||
542 | { | ||
543 | I2C_BOARD_INFO("ov5650L", 0x36), | ||
544 | .platform_data = &cardhu_left_ov5650_data, | ||
545 | }, | ||
546 | { | ||
547 | I2C_BOARD_INFO("sh532u", 0x72), | ||
548 | .platform_data = &pm269_sh532u_left_pdata, | ||
549 | }, | ||
550 | }; | ||
551 | |||
552 | static struct i2c_board_info pm269_i2c7_board_info[] = { | ||
553 | { | ||
554 | I2C_BOARD_INFO("ov5650R", 0x36), | ||
555 | .platform_data = &cardhu_right_ov5650_data, | ||
556 | }, | ||
557 | { | ||
558 | I2C_BOARD_INFO("sh532u", 0x72), | ||
559 | .platform_data = &pm269_sh532u_right_pdata, | ||
560 | }, | ||
561 | }; | ||
562 | |||
563 | static struct i2c_board_info cardhu_i2c8_board_info[] = { | ||
564 | { | ||
565 | I2C_BOARD_INFO("ov2710", 0x36), | ||
566 | .platform_data = &cardhu_ov2710_data, | ||
567 | }, | ||
568 | }; | ||
569 | |||
570 | static int nct_get_temp(void *_data, long *temp) | ||
571 | { | ||
572 | struct nct1008_data *data = _data; | ||
573 | return nct1008_thermal_get_temp(data, temp); | ||
574 | } | ||
575 | |||
576 | static int nct_get_temp_low(void *_data, long *temp) | ||
577 | { | ||
578 | struct nct1008_data *data = _data; | ||
579 | return nct1008_thermal_get_temp_low(data, temp); | ||
580 | } | ||
581 | |||
582 | static int nct_set_limits(void *_data, | ||
583 | long lo_limit_milli, | ||
584 | long hi_limit_milli) | ||
585 | { | ||
586 | struct nct1008_data *data = _data; | ||
587 | return nct1008_thermal_set_limits(data, | ||
588 | lo_limit_milli, | ||
589 | hi_limit_milli); | ||
590 | } | ||
591 | |||
592 | static int nct_set_alert(void *_data, | ||
593 | void (*alert_func)(void *), | ||
594 | void *alert_data) | ||
595 | { | ||
596 | struct nct1008_data *data = _data; | ||
597 | return nct1008_thermal_set_alert(data, alert_func, alert_data); | ||
598 | } | ||
599 | |||
600 | static int nct_set_shutdown_temp(void *_data, long shutdown_temp) | ||
601 | { | ||
602 | struct nct1008_data *data = _data; | ||
603 | return nct1008_thermal_set_shutdown_temp(data, shutdown_temp); | ||
604 | } | ||
605 | |||
606 | static void nct1008_probe_callback(struct nct1008_data *data) | ||
607 | { | ||
608 | struct tegra_thermal_device *thermal_device; | ||
609 | |||
610 | thermal_device = kzalloc(sizeof(struct tegra_thermal_device), | ||
611 | GFP_KERNEL); | ||
612 | if (!thermal_device) { | ||
613 | pr_err("unable to allocate thermal device\n"); | ||
614 | return; | ||
615 | } | ||
616 | |||
617 | thermal_device->name = "nct1008"; | ||
618 | thermal_device->data = data; | ||
619 | thermal_device->offset = TDIODE_OFFSET; | ||
620 | thermal_device->get_temp = nct_get_temp; | ||
621 | thermal_device->get_temp_low = nct_get_temp_low; | ||
622 | thermal_device->set_limits = nct_set_limits; | ||
623 | thermal_device->set_alert = nct_set_alert; | ||
624 | thermal_device->set_shutdown_temp = nct_set_shutdown_temp; | ||
625 | |||
626 | tegra_thermal_set_device(thermal_device); | ||
627 | } | ||
628 | |||
629 | static struct nct1008_platform_data cardhu_nct1008_pdata = { | ||
630 | .supported_hwrev = true, | ||
631 | .ext_range = true, | ||
632 | .conv_rate = 0x08, | ||
633 | .offset = 8, /* 4 * 2C. Bug 844025 - 1C for device accuracies */ | ||
634 | .probe_callback = nct1008_probe_callback, | ||
635 | }; | ||
636 | |||
637 | static struct i2c_board_info cardhu_i2c4_bq27510_board_info[] = { | ||
638 | { | ||
639 | I2C_BOARD_INFO("bq27510", 0x55), | ||
640 | }, | ||
641 | }; | ||
642 | |||
643 | static struct i2c_board_info cardhu_i2c4_nct1008_board_info[] = { | ||
644 | { | ||
645 | I2C_BOARD_INFO("nct1008", 0x4C), | ||
646 | .platform_data = &cardhu_nct1008_pdata, | ||
647 | .irq = -1, | ||
648 | } | ||
649 | }; | ||
650 | |||
651 | static int cardhu_nct1008_init(void) | ||
652 | { | ||
653 | int nct1008_port = -1; | ||
654 | int ret = 0; | ||
655 | |||
656 | if ((board_info.board_id == BOARD_E1198) || | ||
657 | (board_info.board_id == BOARD_E1291) || | ||
658 | (board_info.board_id == BOARD_E1257) || | ||
659 | (board_info.board_id == BOARD_PM269) || | ||
660 | (board_info.board_id == BOARD_PM305) || | ||
661 | (board_info.board_id == BOARD_PM311)) { | ||
662 | nct1008_port = TEGRA_GPIO_PN6; | ||
663 | } else if ((board_info.board_id == BOARD_E1186) || | ||
664 | (board_info.board_id == BOARD_E1187) || | ||
665 | (board_info.board_id == BOARD_E1256)) { | ||
666 | /* FIXME: seems to be conflicting with usb3 vbus on E1186 */ | ||
667 | /* nct1008_port = TEGRA_GPIO_PH7; */ | ||
668 | } | ||
669 | |||
670 | if (nct1008_port >= 0) { | ||
671 | /* FIXME: enable irq when throttling is supported */ | ||
672 | cardhu_i2c4_nct1008_board_info[0].irq = TEGRA_GPIO_TO_IRQ(nct1008_port); | ||
673 | |||
674 | ret = gpio_request(nct1008_port, "temp_alert"); | ||
675 | if (ret < 0) | ||
676 | return ret; | ||
677 | |||
678 | ret = gpio_direction_input(nct1008_port); | ||
679 | if (ret < 0) | ||
680 | gpio_free(nct1008_port); | ||
681 | else | ||
682 | tegra_gpio_enable(nct1008_port); | ||
683 | } | ||
684 | |||
685 | return ret; | ||
686 | } | ||
687 | |||
688 | #if defined(CONFIG_GPIO_PCA953X) | ||
689 | static struct pca953x_platform_data cardhu_pmu_tca6416_data = { | ||
690 | .gpio_base = PMU_TCA6416_GPIO_BASE, | ||
691 | }; | ||
692 | |||
693 | static const struct i2c_board_info cardhu_i2c4_board_info_tca6416[] = { | ||
694 | { | ||
695 | I2C_BOARD_INFO("tca6416", 0x20), | ||
696 | .platform_data = &cardhu_pmu_tca6416_data, | ||
697 | }, | ||
698 | }; | ||
699 | |||
700 | static struct pca953x_platform_data cardhu_cam_tca6416_data = { | ||
701 | .gpio_base = CAM_TCA6416_GPIO_BASE, | ||
702 | }; | ||
703 | |||
704 | static const struct i2c_board_info cardhu_i2c2_board_info_tca6416[] = { | ||
705 | { | ||
706 | I2C_BOARD_INFO("tca6416", 0x20), | ||
707 | .platform_data = &cardhu_cam_tca6416_data, | ||
708 | }, | ||
709 | }; | ||
710 | |||
711 | static int __init pmu_tca6416_init(void) | ||
712 | { | ||
713 | if ((board_info.board_id == BOARD_E1198) || | ||
714 | (board_info.board_id == BOARD_E1291)) | ||
715 | return 0; | ||
716 | |||
717 | pr_info("Registering pmu pca6416\n"); | ||
718 | i2c_register_board_info(4, cardhu_i2c4_board_info_tca6416, | ||
719 | ARRAY_SIZE(cardhu_i2c4_board_info_tca6416)); | ||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | static int __init cam_tca6416_init(void) | ||
724 | { | ||
725 | /* Boards E1198 and E1291 are of Cardhu personality | ||
726 | * and donot have TCA6416 exp for camera */ | ||
727 | if ((board_info.board_id == BOARD_E1198) || | ||
728 | (board_info.board_id == BOARD_E1291)) | ||
729 | return 0; | ||
730 | |||
731 | pr_info("Registering cam pca6416\n"); | ||
732 | i2c_register_board_info(2, cardhu_i2c2_board_info_tca6416, | ||
733 | ARRAY_SIZE(cardhu_i2c2_board_info_tca6416)); | ||
734 | return 0; | ||
735 | } | ||
736 | #else | ||
737 | static int __init pmu_tca6416_init(void) | ||
738 | { | ||
739 | return 0; | ||
740 | } | ||
741 | |||
742 | static int __init cam_tca6416_init(void) | ||
743 | { | ||
744 | return 0; | ||
745 | } | ||
746 | #endif | ||
747 | |||
748 | /* MPU board file definition */ | ||
749 | #if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050) | ||
750 | #define MPU_GYRO_NAME "mpu3050" | ||
751 | #endif | ||
752 | #if (MPU_GYRO_TYPE == MPU_TYPE_MPU6050) | ||
753 | #define MPU_GYRO_NAME "mpu6050" | ||
754 | #endif | ||
755 | static struct mpu_platform_data mpu_gyro_data = { | ||
756 | .int_config = 0x10, | ||
757 | .level_shifter = 0, | ||
758 | .orientation = MPU_GYRO_ORIENTATION, /* Located in board_[platformname].h */ | ||
759 | }; | ||
760 | |||
761 | #if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050) | ||
762 | static struct ext_slave_platform_data mpu_accel_data = { | ||
763 | .address = MPU_ACCEL_ADDR, | ||
764 | .irq = 0, | ||
765 | .adapt_num = MPU_ACCEL_BUS_NUM, | ||
766 | .bus = EXT_SLAVE_BUS_SECONDARY, | ||
767 | .orientation = MPU_ACCEL_ORIENTATION, /* Located in board_[platformname].h */ | ||
768 | }; | ||
769 | #endif | ||
770 | |||
771 | static struct ext_slave_platform_data mpu_compass_data = { | ||
772 | .address = MPU_COMPASS_ADDR, | ||
773 | .irq = 0, | ||
774 | .adapt_num = MPU_COMPASS_BUS_NUM, | ||
775 | .bus = EXT_SLAVE_BUS_PRIMARY, | ||
776 | .orientation = MPU_COMPASS_ORIENTATION, /* Located in board_[platformname].h */ | ||
777 | }; | ||
778 | |||
779 | static struct i2c_board_info __initdata inv_mpu_i2c2_board_info[] = { | ||
780 | { | ||
781 | I2C_BOARD_INFO(MPU_GYRO_NAME, MPU_GYRO_ADDR), | ||
782 | .irq = TEGRA_GPIO_TO_IRQ(MPU_GYRO_IRQ_GPIO), | ||
783 | .platform_data = &mpu_gyro_data, | ||
784 | }, | ||
785 | #if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050) | ||
786 | { | ||
787 | I2C_BOARD_INFO(MPU_ACCEL_NAME, MPU_ACCEL_ADDR), | ||
788 | #if MPU_ACCEL_IRQ_GPIO | ||
789 | .irq = TEGRA_GPIO_TO_IRQ(MPU_ACCEL_IRQ_GPIO), | ||
790 | #endif | ||
791 | .platform_data = &mpu_accel_data, | ||
792 | }, | ||
793 | #endif | ||
794 | { | ||
795 | I2C_BOARD_INFO(MPU_COMPASS_NAME, MPU_COMPASS_ADDR), | ||
796 | #if MPU_COMPASS_IRQ_GPIO | ||
797 | .irq = TEGRA_GPIO_TO_IRQ(MPU_COMPASS_IRQ_GPIO), | ||
798 | #endif | ||
799 | .platform_data = &mpu_compass_data, | ||
800 | }, | ||
801 | }; | ||
802 | |||
803 | static void mpuirq_init(void) | ||
804 | { | ||
805 | int ret = 0; | ||
806 | |||
807 | pr_info("*** MPU START *** mpuirq_init...\n"); | ||
808 | |||
809 | #if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050) | ||
810 | #if MPU_ACCEL_IRQ_GPIO | ||
811 | /* ACCEL-IRQ assignment */ | ||
812 | tegra_gpio_enable(MPU_ACCEL_IRQ_GPIO); | ||
813 | ret = gpio_request(MPU_ACCEL_IRQ_GPIO, MPU_ACCEL_NAME); | ||
814 | if (ret < 0) { | ||
815 | pr_err("%s: gpio_request failed %d\n", __func__, ret); | ||
816 | return; | ||
817 | } | ||
818 | |||
819 | ret = gpio_direction_input(MPU_ACCEL_IRQ_GPIO); | ||
820 | if (ret < 0) { | ||
821 | pr_err("%s: gpio_direction_input failed %d\n", __func__, ret); | ||
822 | gpio_free(MPU_ACCEL_IRQ_GPIO); | ||
823 | return; | ||
824 | } | ||
825 | #endif | ||
826 | #endif | ||
827 | |||
828 | /* MPU-IRQ assignment */ | ||
829 | tegra_gpio_enable(MPU_GYRO_IRQ_GPIO); | ||
830 | ret = gpio_request(MPU_GYRO_IRQ_GPIO, MPU_GYRO_NAME); | ||
831 | if (ret < 0) { | ||
832 | pr_err("%s: gpio_request failed %d\n", __func__, ret); | ||
833 | return; | ||
834 | } | ||
835 | |||
836 | ret = gpio_direction_input(MPU_GYRO_IRQ_GPIO); | ||
837 | if (ret < 0) { | ||
838 | pr_err("%s: gpio_direction_input failed %d\n", __func__, ret); | ||
839 | gpio_free(MPU_GYRO_IRQ_GPIO); | ||
840 | return; | ||
841 | } | ||
842 | pr_info("*** MPU END *** mpuirq_init...\n"); | ||
843 | |||
844 | i2c_register_board_info(MPU_GYRO_BUS_NUM, inv_mpu_i2c2_board_info, | ||
845 | ARRAY_SIZE(inv_mpu_i2c2_board_info)); | ||
846 | } | ||
847 | |||
848 | static struct i2c_board_info cardhu_i2c2_isl_board_info[] = { | ||
849 | { | ||
850 | I2C_BOARD_INFO("isl29028", 0x44), | ||
851 | } | ||
852 | }; | ||
853 | |||
854 | static struct i2c_board_info cardhu_i2c2_ltr_board_info[] = { | ||
855 | { | ||
856 | I2C_BOARD_INFO("LTR_558ALS", 0x23), | ||
857 | } | ||
858 | }; | ||
859 | |||
860 | int __init cardhu_sensors_init(void) | ||
861 | { | ||
862 | int err; | ||
863 | |||
864 | tegra_get_board_info(&board_info); | ||
865 | |||
866 | //cardhu_camera_init(); | ||
867 | //cam_tca6416_init(); | ||
868 | |||
869 | //i2c_register_board_info(2, cardhu_i2c3_board_info, | ||
870 | // ARRAY_SIZE(cardhu_i2c3_board_info)); | ||
871 | |||
872 | //i2c_register_board_info(2, cardhu_i2c_board_info_tps61050, | ||
873 | // ARRAY_SIZE(cardhu_i2c_board_info_tps61050)); | ||
874 | |||
875 | #if 0 // DIFFERENT CAMERA INITIALIZATION ON CARMA BOARD | ||
876 | #ifdef CONFIG_VIDEO_OV14810 | ||
877 | /* This is disabled by default; To enable this change Kconfig; | ||
878 | * there should be some way to detect dynamically which board | ||
879 | * is connected (E1211/E1214), till that time sensor selection | ||
880 | * logic is static; | ||
881 | * e1214 corresponds to ov14810 sensor */ | ||
882 | i2c_register_board_info(2, cardhu_i2c_board_info_e1214, | ||
883 | ARRAY_SIZE(cardhu_i2c_board_info_e1214)); | ||
884 | #else | ||
885 | /* Left camera is on PCA954x's I2C BUS0, Right camera is on BUS1 & | ||
886 | * Front camera is on BUS2 */ | ||
887 | if (board_info.board_id != BOARD_PM269) { | ||
888 | i2c_register_board_info(PCA954x_I2C_BUS0, | ||
889 | cardhu_i2c6_board_info, | ||
890 | ARRAY_SIZE(cardhu_i2c6_board_info)); | ||
891 | |||
892 | i2c_register_board_info(PCA954x_I2C_BUS1, | ||
893 | cardhu_i2c7_board_info, | ||
894 | ARRAY_SIZE(cardhu_i2c7_board_info)); | ||
895 | } else { | ||
896 | i2c_register_board_info(PCA954x_I2C_BUS0, | ||
897 | pm269_i2c6_board_info, | ||
898 | ARRAY_SIZE(pm269_i2c6_board_info)); | ||
899 | |||
900 | i2c_register_board_info(PCA954x_I2C_BUS1, | ||
901 | pm269_i2c7_board_info, | ||
902 | ARRAY_SIZE(pm269_i2c7_board_info)); | ||
903 | } | ||
904 | i2c_register_board_info(PCA954x_I2C_BUS2, cardhu_i2c8_board_info, | ||
905 | ARRAY_SIZE(cardhu_i2c8_board_info)); | ||
906 | |||
907 | #endif | ||
908 | #endif | ||
909 | //pmu_tca6416_init(); | ||
910 | |||
911 | //if (board_info.board_id == BOARD_E1291) | ||
912 | // i2c_register_board_info(4, cardhu_i2c4_bq27510_board_info, | ||
913 | // ARRAY_SIZE(cardhu_i2c4_bq27510_board_info)); | ||
914 | |||
915 | //if (board_info.sku == BOARD_SKU_B11) | ||
916 | // i2c_register_board_info(2, cardhu_i2c2_ltr_board_info, | ||
917 | // ARRAY_SIZE(cardhu_i2c2_ltr_board_info)); | ||
918 | //else | ||
919 | // i2c_register_board_info(2, cardhu_i2c2_isl_board_info, | ||
920 | // ARRAY_SIZE(cardhu_i2c2_isl_board_info)); | ||
921 | |||
922 | err = cardhu_nct1008_init(); | ||
923 | if (err) | ||
924 | return err; | ||
925 | |||
926 | i2c_register_board_info(1, cardhu_i2c4_nct1008_board_info, | ||
927 | ARRAY_SIZE(cardhu_i2c4_nct1008_board_info)); | ||
928 | |||
929 | mpuirq_init(); | ||
930 | return 0; | ||
931 | } | ||
932 | |||
933 | #if defined(CONFIG_GPIO_PCA953X) | ||
934 | struct ov5650_gpios { | ||
935 | const char *name; | ||
936 | int gpio; | ||
937 | int enabled; | ||
938 | }; | ||
939 | |||
940 | #define OV5650_GPIO(_name, _gpio, _enabled) \ | ||
941 | { \ | ||
942 | .name = _name, \ | ||
943 | .gpio = _gpio, \ | ||
944 | .enabled = _enabled, \ | ||
945 | } | ||
946 | |||
947 | static struct ov5650_gpios ov5650_gpio_keys[] = { | ||
948 | [0] = OV5650_GPIO("cam1_pwdn", CAM1_PWR_DN_GPIO, 0), | ||
949 | [1] = OV5650_GPIO("cam1_rst_lo", CAM1_RST_L_GPIO, 1), | ||
950 | [2] = OV5650_GPIO("cam1_af_pwdn_lo", CAM1_AF_PWR_DN_L_GPIO, 0), | ||
951 | [3] = OV5650_GPIO("cam1_ldo_shdn_lo", CAM1_LDO_SHUTDN_L_GPIO, 1), | ||
952 | [4] = OV5650_GPIO("cam2_pwdn", CAM2_PWR_DN_GPIO, 0), | ||
953 | [5] = OV5650_GPIO("cam2_rst_lo", CAM2_RST_L_GPIO, 1), | ||
954 | [6] = OV5650_GPIO("cam2_af_pwdn_lo", CAM2_AF_PWR_DN_L_GPIO, 0), | ||
955 | [7] = OV5650_GPIO("cam2_ldo_shdn_lo", CAM2_LDO_SHUTDN_L_GPIO, 1), | ||
956 | [8] = OV5650_GPIO("cam3_pwdn", CAM_FRONT_PWR_DN_GPIO, 0), | ||
957 | [9] = OV5650_GPIO("cam3_rst_lo", CAM_FRONT_RST_L_GPIO, 1), | ||
958 | [10] = OV5650_GPIO("cam3_af_pwdn_lo", CAM_FRONT_AF_PWR_DN_L_GPIO, 0), | ||
959 | [11] = OV5650_GPIO("cam3_ldo_shdn_lo", CAM_FRONT_LDO_SHUTDN_L_GPIO, 1), | ||
960 | [12] = OV5650_GPIO("cam_led_exp", CAM_FRONT_LED_EXP, 1), | ||
961 | [13] = OV5650_GPIO("cam_led_rear_exp", CAM_SNN_LED_REAR_EXP, 1), | ||
962 | [14] = OV5650_GPIO("cam_i2c_mux_rst", CAM_I2C_MUX_RST_EXP, 1), | ||
963 | }; | ||
964 | |||
965 | int __init cardhu_ov5650_late_init(void) | ||
966 | { | ||
967 | int ret; | ||
968 | int i; | ||
969 | |||
970 | if (!machine_is_cardhu()) | ||
971 | return 0; | ||
972 | |||
973 | if ((board_info.board_id == BOARD_E1198) || | ||
974 | (board_info.board_id == BOARD_E1291)) | ||
975 | return 0; | ||
976 | |||
977 | printk("%s: \n", __func__); | ||
978 | for (i = 0; i < ARRAY_SIZE(ov5650_gpio_keys); i++) { | ||
979 | ret = gpio_request(ov5650_gpio_keys[i].gpio, | ||
980 | ov5650_gpio_keys[i].name); | ||
981 | if (ret < 0) { | ||
982 | printk("%s: gpio_request failed for gpio #%d\n", | ||
983 | __func__, i); | ||
984 | goto fail; | ||
985 | } | ||
986 | printk("%s: enable - %d\n", __func__, i); | ||
987 | gpio_direction_output(ov5650_gpio_keys[i].gpio, | ||
988 | ov5650_gpio_keys[i].enabled); | ||
989 | gpio_export(ov5650_gpio_keys[i].gpio, false); | ||
990 | } | ||
991 | |||
992 | return 0; | ||
993 | |||
994 | fail: | ||
995 | while (i--) | ||
996 | gpio_free(ov5650_gpio_keys[i].gpio); | ||
997 | return ret; | ||
998 | } | ||
999 | |||
1000 | late_initcall(cardhu_ov5650_late_init); | ||
1001 | #endif | ||