blob: abf73020e312bbd4854b38d5826a5f7ae277eda4 [file] [log] [blame]
Chintan Pandya40762702011-12-06 13:47:06 +05301/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/i2c.h>
14#include <linux/i2c/sx150x.h>
15#include <linux/gpio.h>
16#include <linux/regulator/consumer.h>
17#include <linux/kernel.h>
18#include <linux/platform_device.h>
19#include <asm/mach-types.h>
20#include <mach/msm_iomap.h>
21#include <mach/board.h>
22#include <mach/irqs-7xxx.h>
23#include "devices-msm7x2xa.h"
24#include "board-msm7627a.h"
25
26static uint32_t camera_off_gpio_table[] = {
27 GPIO_CFG(15, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
28};
29
30static uint32_t camera_on_gpio_table[] = {
31 GPIO_CFG(15, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
32};
33
34#ifdef CONFIG_MSM_CAMERA_FLASH
35static struct msm_camera_sensor_flash_src msm_flash_src = {
36 .flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
37 ._fsrc.ext_driver_src.led_en = GPIO_CAM_GP_LED_EN1,
38 ._fsrc.ext_driver_src.led_flash_en = GPIO_CAM_GP_LED_EN2,
39};
40#endif
41
42static struct regulator_bulk_data regs_camera[] = {
43 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
44 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
45 { .supply = "usb2", .min_uV = 1800000, .max_uV = 1800000 },
46};
47
48static void qrd1_camera_gpio_cfg(void)
49{
50
51 int rc = 0;
52
53 rc = gpio_request(QRD_GPIO_CAM_5MP_SHDN_EN, "ov5640");
54 if (rc < 0)
55 pr_err("%s: gpio_request---GPIO_CAM_5MP_SHDN_EN failed!",
56 __func__);
57
58
59 rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_CAM_5MP_SHDN_EN, 0,
60 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
61 GPIO_CFG_2MA), GPIO_CFG_ENABLE);
62 if (rc < 0) {
63 pr_err("%s: unable to enable Power Down gpio for main"
64 "camera!\n", __func__);
65 gpio_free(QRD_GPIO_CAM_5MP_SHDN_EN);
66 }
67
68
69 rc = gpio_request(QRD_GPIO_CAM_5MP_RESET, "ov5640");
70 if (rc < 0) {
71 pr_err("%s: gpio_request---GPIO_CAM_5MP_RESET failed!",
72 __func__);
73 gpio_free(QRD_GPIO_CAM_5MP_SHDN_EN);
74 }
75
76
77 rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_CAM_5MP_RESET, 0,
78 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
79 GPIO_CFG_2MA), GPIO_CFG_ENABLE);
80 if (rc < 0) {
81 pr_err("%s: unable to enable reset gpio for main camera!\n",
82 __func__);
83 gpio_free(QRD_GPIO_CAM_5MP_RESET);
84 }
85
86 rc = gpio_request(QRD_GPIO_CAM_3MP_PWDN, "ov7692");
87 if (rc < 0)
88 pr_err("%s: gpio_request---GPIO_CAM_3MP_PWDN failed!",
89 __func__);
90
91 rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_CAM_3MP_PWDN, 0,
92 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
93 GPIO_CFG_2MA), GPIO_CFG_ENABLE);
94 if (rc < 0) {
95 pr_err("%s: unable to enable Power Down gpio for front"
96 "camera!\n", __func__);
97 gpio_free(QRD_GPIO_CAM_3MP_PWDN);
98 }
99
100 gpio_direction_output(QRD_GPIO_CAM_5MP_SHDN_EN, 1);
101 gpio_direction_output(QRD_GPIO_CAM_5MP_RESET, 1);
102 gpio_direction_output(QRD_GPIO_CAM_3MP_PWDN, 1);
103}
104
105static void msm_camera_vreg_config(int vreg_en)
106{
107 int rc = vreg_en ?
108 regulator_bulk_enable(ARRAY_SIZE(regs_camera), regs_camera) :
109 regulator_bulk_disable(ARRAY_SIZE(regs_camera), regs_camera);
110
111 if (rc)
112 pr_err("%s: could not %sable regulators: %d\n",
113 __func__, vreg_en ? "en" : "dis", rc);
114}
115
116static int config_gpio_table(uint32_t *table, int len)
117{
118 int rc = 0, i = 0;
119
120 for (i = 0; i < len; i++) {
121 rc = gpio_tlmm_config(table[i], GPIO_CFG_ENABLE);
122 if (rc) {
123 pr_err("%s not able to get gpio\n", __func__);
124 for (i--; i >= 0; i--)
125 gpio_tlmm_config(camera_off_gpio_table[i],
126 GPIO_CFG_ENABLE);
127 break;
128 }
129 }
130 return rc;
131}
132
133static int config_camera_on_gpios_rear(void)
134{
135 int rc = 0;
136
137 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
138 || machine_is_msm7627a_qrd1())
139 msm_camera_vreg_config(1);
140
141 rc = config_gpio_table(camera_on_gpio_table,
142 ARRAY_SIZE(camera_on_gpio_table));
143 if (rc < 0) {
144 pr_err("%s: CAMSENSOR gpio table request"
145 "failed\n", __func__);
146 return rc;
147 }
148
149 return rc;
150}
151
152static void config_camera_off_gpios_rear(void)
153{
154 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
155 || machine_is_msm7627a_qrd1())
156 msm_camera_vreg_config(0);
157
158 config_gpio_table(camera_off_gpio_table,
159 ARRAY_SIZE(camera_off_gpio_table));
160}
161
162static int config_camera_on_gpios_front(void)
163{
164 int rc = 0;
165
166 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
167 || machine_is_msm7627a_qrd1())
168 msm_camera_vreg_config(1);
169
170 rc = config_gpio_table(camera_on_gpio_table,
171 ARRAY_SIZE(camera_on_gpio_table));
172 if (rc < 0) {
173 pr_err("%s: CAMSENSOR gpio table request"
174 "failed\n", __func__);
175 return rc;
176 }
177
178 return rc;
179}
180
181static void config_camera_off_gpios_front(void)
182{
183 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
184 || machine_is_msm7627a_qrd1())
185 msm_camera_vreg_config(0);
186
187 config_gpio_table(camera_off_gpio_table,
188 ARRAY_SIZE(camera_off_gpio_table));
189}
190
191struct msm_camera_device_platform_data msm_camera_device_data_rear = {
192 .camera_gpio_on = config_camera_on_gpios_rear,
193 .camera_gpio_off = config_camera_off_gpios_rear,
194 .ioext.csiphy = 0xA1000000,
195 .ioext.csisz = 0x00100000,
196 .ioext.csiirq = INT_CSI_IRQ_1,
197 .ioclk.mclk_clk_rate = 24000000,
198 .ioclk.vfe_clk_rate = 192000000,
199 .ioext.appphy = MSM_CLK_CTL_PHYS,
200 .ioext.appsz = MSM_CLK_CTL_SIZE,
201};
202
203struct msm_camera_device_platform_data msm_camera_device_data_front = {
204 .camera_gpio_on = config_camera_on_gpios_front,
205 .camera_gpio_off = config_camera_off_gpios_front,
206 .ioext.csiphy = 0xA0F00000,
207 .ioext.csisz = 0x00100000,
208 .ioext.csiirq = INT_CSI_IRQ_0,
209 .ioclk.mclk_clk_rate = 24000000,
210 .ioclk.vfe_clk_rate = 192000000,
211 .ioext.appphy = MSM_CLK_CTL_PHYS,
212 .ioext.appsz = MSM_CLK_CTL_SIZE,
213};
214
215#ifdef CONFIG_S5K4E1
216static struct msm_camera_sensor_platform_info s5k4e1_sensor_7627a_info = {
217 .mount_angle = 90
218};
219
220static struct msm_camera_sensor_flash_data flash_s5k4e1 = {
221 .flash_type = MSM_CAMERA_FLASH_LED,
222 .flash_src = &msm_flash_src
223};
224
225static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data = {
226 .sensor_name = "s5k4e1",
227 .sensor_reset_enable = 1,
228 .sensor_reset = GPIO_CAM_GP_CAMIF_RESET_N,
229 .sensor_pwd = 85,
230 .vcm_pwd = GPIO_CAM_GP_CAM_PWDN,
231 .vcm_enable = 1,
232 .pdata = &msm_camera_device_data_rear,
233 .flash_data = &flash_s5k4e1,
234 .sensor_platform_info = &s5k4e1_sensor_7627a_info,
235 .csi_if = 1
236};
237
238static struct platform_device msm_camera_sensor_s5k4e1 = {
239 .name = "msm_camera_s5k4e1",
240 .dev = {
241 .platform_data = &msm_camera_sensor_s5k4e1_data,
242 },
243};
244#endif
245
246#ifdef CONFIG_IMX072
247static struct msm_camera_sensor_platform_info imx072_sensor_7627a_info = {
248 .mount_angle = 90
249};
250
251static struct msm_camera_sensor_flash_data flash_imx072 = {
252 .flash_type = MSM_CAMERA_FLASH_LED,
253 .flash_src = &msm_flash_src
254};
255
256static struct msm_camera_sensor_info msm_camera_sensor_imx072_data = {
257 .sensor_name = "imx072",
258 .sensor_reset_enable = 1,
259 .sensor_reset = GPIO_CAM_GP_CAMIF_RESET_N, /* TODO 106,*/
260 .sensor_pwd = 85,
261 .vcm_pwd = GPIO_CAM_GP_CAM_PWDN,
262 .vcm_enable = 1,
263 .pdata = &msm_camera_device_data_rear,
264 .flash_data = &flash_imx072,
265 .sensor_platform_info = &imx072_sensor_7627a_info,
266 .csi_if = 1
267};
268
269static struct platform_device msm_camera_sensor_imx072 = {
270 .name = "msm_camera_imx072",
271 .dev = {
272 .platform_data = &msm_camera_sensor_imx072_data,
273 },
274};
275#endif
276
277static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data;
278#ifdef CONFIG_WEBCAM_OV9726
279static struct msm_camera_sensor_platform_info ov9726_sensor_7627a_info = {
280 .mount_angle = 90
281};
282
283static struct msm_camera_sensor_flash_data flash_ov9726 = {
284 .flash_type = MSM_CAMERA_FLASH_NONE,
285 .flash_src = &msm_flash_src
286};
287
288static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data = {
289 .sensor_name = "ov9726",
290 .sensor_reset_enable = 0,
291 .sensor_reset = GPIO_CAM_GP_CAM1MP_XCLR,
292 .sensor_pwd = 85,
293 .vcm_pwd = 1,
294 .vcm_enable = 0,
295 .pdata = &msm_camera_device_data_front,
296 .flash_data = &flash_ov9726,
297 .sensor_platform_info = &ov9726_sensor_7627a_info,
298 .csi_if = 1
299};
300
301static struct platform_device msm_camera_sensor_ov9726 = {
302 .name = "msm_camera_ov9726",
303 .dev = {
304 .platform_data = &msm_camera_sensor_ov9726_data,
305 },
306};
307#else
308static inline void msm_camera_vreg_init(void) { }
309#endif
310
311#ifdef CONFIG_MT9E013
312static struct msm_camera_sensor_platform_info mt9e013_sensor_7627a_info = {
313 .mount_angle = 90
314};
315
316static struct msm_camera_sensor_flash_data flash_mt9e013 = {
317 .flash_type = MSM_CAMERA_FLASH_LED,
318 .flash_src = &msm_flash_src
319};
320
321static struct msm_camera_sensor_info msm_camera_sensor_mt9e013_data = {
322 .sensor_name = "mt9e013",
323 .sensor_reset = 0,
324 .sensor_reset_enable = 1,
325 .sensor_pwd = 85,
326 .vcm_pwd = 1,
327 .vcm_enable = 0,
328 .pdata = &msm_camera_device_data_rear,
329 .flash_data = &flash_mt9e013,
330 .sensor_platform_info = &mt9e013_sensor_7627a_info,
331 .csi_if = 1
332};
333
334static struct platform_device msm_camera_sensor_mt9e013 = {
335 .name = "msm_camera_mt9e013",
336 .dev = {
337 .platform_data = &msm_camera_sensor_mt9e013_data,
338 },
339};
340#endif
341
342#ifdef CONFIG_OV5640
343static struct msm_camera_sensor_platform_info ov5640_sensor_info = {
344 .mount_angle = 90
345};
346
347static struct msm_camera_sensor_flash_src msm_flash_src_ov5640 = {
348 .flash_sr_type = MSM_CAMERA_FLASH_SRC_LED,
349 ._fsrc.led_src.led_name = "flashlight",
350 ._fsrc.led_src.led_name_len = 10,
351};
352
353static struct msm_camera_sensor_flash_data flash_ov5640 = {
354 .flash_type = MSM_CAMERA_FLASH_LED,
355 .flash_src = &msm_flash_src_ov5640,
356};
357
358static struct msm_camera_sensor_info msm_camera_sensor_ov5640_data = {
359 .sensor_name = "ov5640",
360 .sensor_reset_enable = 1,
361 .sensor_reset = QRD_GPIO_CAM_5MP_RESET,
362 .sensor_pwd = QRD_GPIO_CAM_5MP_SHDN_EN,
363 .vcm_pwd = 0,
364 .vcm_enable = 0,
365 .pdata = &msm_camera_device_data_rear,
366 .flash_data = &flash_ov5640,
367 .sensor_platform_info = &ov5640_sensor_info,
368 .csi_if = 1,
369};
370
371static struct platform_device msm_camera_sensor_ov5640 = {
372 .name = "msm_camera_ov5640",
373 .dev = {
374 .platform_data = &msm_camera_sensor_ov5640_data,
375 },
376};
377#endif
378
379#ifdef CONFIG_WEBCAM_OV7692_QRD
380static struct msm_camera_sensor_platform_info ov7692_sensor_7627a_info = {
381 .mount_angle = 90
382};
383
384static struct msm_camera_sensor_flash_data flash_ov7692 = {
385 .flash_type = MSM_CAMERA_FLASH_NONE,
386};
387
388static struct msm_camera_sensor_info msm_camera_sensor_ov7692_data = {
389 .sensor_name = "ov7692",
390 .sensor_reset_enable = 0,
391 .sensor_reset = 0,
392 .sensor_pwd = QRD_GPIO_CAM_3MP_PWDN,
393 .vcm_pwd = 0,
394 .vcm_enable = 0,
395 .pdata = &msm_camera_device_data_front,
396 .flash_data = &flash_ov7692,
397 .sensor_platform_info = &ov7692_sensor_7627a_info,
398 .csi_if = 1,
399};
400
401static struct platform_device msm_camera_sensor_ov7692 = {
402 .name = "msm_camera_ov7692",
403 .dev = {
404 .platform_data = &msm_camera_sensor_ov7692_data,
405 },
406};
407#endif
408
409enum {
410 SX150X_CAM,
411};
412
413static struct sx150x_platform_data sx150x_data[] __initdata = {
414 [SX150X_CAM] = {
415 .gpio_base = GPIO_CAM_EXPANDER_BASE,
416 .oscio_is_gpo = false,
417 .io_pullup_ena = 0,
418 .io_pulldn_ena = 0,
419 .io_open_drain_ena = 0x23,
420 .irq_summary = -1,
421 },
422};
423
424static struct i2c_board_info cam_exp_i2c_info[] __initdata = {
425 {
426 I2C_BOARD_INFO("sx1508q", 0x22),
427 .platform_data = &sx150x_data[SX150X_CAM],
428 },
429};
430
431static struct i2c_board_info i2c_camera_devices[] = {
432 #ifdef CONFIG_S5K4E1
433 {
434 I2C_BOARD_INFO("s5k4e1", 0x36),
435 },
436 {
437 I2C_BOARD_INFO("s5k4e1_af", 0x8c >> 1),
438 },
439 #endif
440 #ifdef CONFIG_WEBCAM_OV9726
441 {
442 I2C_BOARD_INFO("ov9726", 0x10),
443 },
444 #endif
445 #ifdef CONFIG_IMX072
446 {
447 I2C_BOARD_INFO("imx072", 0x34),
448 },
449 #endif
450 #ifdef CONFIG_MT9E013
451 {
452 I2C_BOARD_INFO("mt9e013", 0x6C >> 2),
453 },
454 #endif
455 {
456 I2C_BOARD_INFO("sc628a", 0x6E),
457 },
458};
459
460static struct i2c_board_info i2c_camera_devices_qrd[] = {
461 #ifdef CONFIG_OV5640
462 {
463 I2C_BOARD_INFO("ov5640", 0x78 >> 1),
464 },
465 #endif
466 #ifdef CONFIG_WEBCAM_OV7692_QRD
467 {
468 I2C_BOARD_INFO("ov7692", 0x78),
469 },
470 #endif
471};
472
473static struct platform_device *camera_devices_msm[] __initdata = {
474#ifdef CONFIG_S5K4E1
475 &msm_camera_sensor_s5k4e1,
476#endif
477#ifdef CONFIG_IMX072
478 &msm_camera_sensor_imx072,
479#endif
480#ifdef CONFIG_WEBCAM_OV9726
481 &msm_camera_sensor_ov9726,
482#endif
483#ifdef CONFIG_MT9E013
484 &msm_camera_sensor_mt9e013,
485#endif
486};
487
488static struct platform_device *camera_devices_qrd[] __initdata = {
489#ifdef CONFIG_OV5640
490 &msm_camera_sensor_ov5640,
491#endif
492#ifdef CONFIG_WEBCAM_OV7692_QRD
493 &msm_camera_sensor_ov7692,
494#endif
495};
496
497static void __init register_i2c_devices(void)
498{
499 i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
500 cam_exp_i2c_info,
501 ARRAY_SIZE(cam_exp_i2c_info));
502}
503
504void __init msm7627a_camera_init(void)
505{
506 int rc;
507
508 if (machine_is_msm7627a_qrd1()) {
509 qrd1_camera_gpio_cfg();
510 platform_add_devices(camera_devices_qrd,
511 ARRAY_SIZE(camera_devices_qrd));
Taniya Dasc868a2e2012-01-03 10:18:47 +0530512 } else if (machine_is_msm7627a_evb())
513 return;
514 else
Chintan Pandya40762702011-12-06 13:47:06 +0530515 platform_add_devices(camera_devices_msm,
516 ARRAY_SIZE(camera_devices_msm));
517
518 if (!machine_is_msm7627a_qrd1())
519 register_i2c_devices();
520
521 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_camera), regs_camera);
522
523 if (rc) {
524 pr_err("%s: could not get regulators: %d\n", __func__, rc);
525 return;
526 }
527
528 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_camera), regs_camera);
529
530 if (rc) {
531 pr_err("%s: could not set voltages: %d\n", __func__, rc);
532 return;
533 }
534
535 if (machine_is_msm7627a_qrd1())
536 i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
537 i2c_camera_devices_qrd,
538 ARRAY_SIZE(i2c_camera_devices_qrd));
539 else
540 i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
541 i2c_camera_devices,
542 ARRAY_SIZE(i2c_camera_devices));
543}