blob: e827b2bf445d594bdee9324ab51409da78b214ae [file] [log] [blame]
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -08001/* Copyright (c) 2011, 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
14#include <linux/i2c.h>
15#include <linux/i2c/sx150x.h>
16#include <asm/mach-types.h>
17#include <mach/board.h>
18#include <mach/msm_bus_board.h>
19#include <mach/gpio.h>
20#include <mach/gpiomux.h>
21#include "devices.h"
Stepan Moskovchenko5a83dba2011-12-05 17:30:17 -080022#include "board-8960.h"
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -080023
24#if (defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)) && \
25 defined(CONFIG_I2C)
26
27static struct i2c_board_info cam_expander_i2c_info[] = {
28 {
29 I2C_BOARD_INFO("sx1508q", 0x22),
30 .platform_data = &msm8960_sx150x_data[SX150X_CAM]
31 },
32};
33
34static struct msm_cam_expander_info cam_expander_info[] = {
35 {
36 cam_expander_i2c_info,
37 MSM_8960_GSBI4_QUP_I2C_BUS_ID,
38 },
39};
40#endif
41
42static struct gpiomux_setting cam_settings[] = {
43 {
44 .func = GPIOMUX_FUNC_GPIO, /*suspend*/
45 .drv = GPIOMUX_DRV_2MA,
46 .pull = GPIOMUX_PULL_DOWN,
47 },
48
49 {
50 .func = GPIOMUX_FUNC_1, /*active 1*/
51 .drv = GPIOMUX_DRV_2MA,
52 .pull = GPIOMUX_PULL_NONE,
53 },
54
55 {
56 .func = GPIOMUX_FUNC_GPIO, /*active 2*/
57 .drv = GPIOMUX_DRV_2MA,
58 .pull = GPIOMUX_PULL_NONE,
59 },
60
61 {
62 .func = GPIOMUX_FUNC_1, /*active 3*/
63 .drv = GPIOMUX_DRV_8MA,
64 .pull = GPIOMUX_PULL_NONE,
65 },
66
67 {
68 .func = GPIOMUX_FUNC_5, /*active 4*/
69 .drv = GPIOMUX_DRV_8MA,
70 .pull = GPIOMUX_PULL_UP,
71 },
72
73 {
74 .func = GPIOMUX_FUNC_6, /*active 5*/
75 .drv = GPIOMUX_DRV_8MA,
76 .pull = GPIOMUX_PULL_UP,
77 },
78
79 {
80 .func = GPIOMUX_FUNC_2, /*active 6*/
81 .drv = GPIOMUX_DRV_2MA,
82 .pull = GPIOMUX_PULL_UP,
83 },
84
85 {
86 .func = GPIOMUX_FUNC_3, /*active 7*/
87 .drv = GPIOMUX_DRV_8MA,
88 .pull = GPIOMUX_PULL_UP,
89 },
90
91 {
92 .func = GPIOMUX_FUNC_GPIO, /*i2c suspend*/
93 .drv = GPIOMUX_DRV_2MA,
94 .pull = GPIOMUX_PULL_KEEPER,
95 },
96
97};
98
Kevin Chancfab2f72011-12-02 13:05:51 -080099static struct msm_gpiomux_config msm8960_cdp_flash_configs[] = {
100 {
101 .gpio = 3,
102 .settings = {
103 [GPIOMUX_ACTIVE] = &cam_settings[1],
104 [GPIOMUX_SUSPENDED] = &cam_settings[0],
105 },
106 },
107};
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -0800108
109static struct msm_gpiomux_config msm8960_cam_common_configs[] = {
110 {
111 .gpio = 2,
112 .settings = {
113 [GPIOMUX_ACTIVE] = &cam_settings[2],
114 [GPIOMUX_SUSPENDED] = &cam_settings[0],
115 },
116 },
117 {
118 .gpio = 3,
119 .settings = {
Kevin Chancfab2f72011-12-02 13:05:51 -0800120 [GPIOMUX_ACTIVE] = &cam_settings[2],
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -0800121 [GPIOMUX_SUSPENDED] = &cam_settings[0],
122 },
123 },
124 {
125 .gpio = 4,
126 .settings = {
127 [GPIOMUX_ACTIVE] = &cam_settings[1],
128 [GPIOMUX_SUSPENDED] = &cam_settings[0],
129 },
130 },
131 {
132 .gpio = 5,
133 .settings = {
134 [GPIOMUX_ACTIVE] = &cam_settings[1],
135 [GPIOMUX_SUSPENDED] = &cam_settings[0],
136 },
137 },
138 {
139 .gpio = 76,
140 .settings = {
141 [GPIOMUX_ACTIVE] = &cam_settings[2],
142 [GPIOMUX_SUSPENDED] = &cam_settings[0],
143 },
144 },
145 {
146 .gpio = 107,
147 .settings = {
148 [GPIOMUX_ACTIVE] = &cam_settings[2],
149 [GPIOMUX_SUSPENDED] = &cam_settings[0],
150 },
151 },
152};
153
154static struct msm_gpiomux_config msm8960_cam_2d_configs[] = {
155 {
156 .gpio = 18,
157 .settings = {
158 [GPIOMUX_ACTIVE] = &cam_settings[3],
159 [GPIOMUX_SUSPENDED] = &cam_settings[8],
160 },
161 },
162 {
163 .gpio = 19,
164 .settings = {
165 [GPIOMUX_ACTIVE] = &cam_settings[3],
166 [GPIOMUX_SUSPENDED] = &cam_settings[8],
167 },
168 },
169 {
170 .gpio = 20,
171 .settings = {
172 [GPIOMUX_ACTIVE] = &cam_settings[3],
173 [GPIOMUX_SUSPENDED] = &cam_settings[8],
174 },
175 },
176 {
177 .gpio = 21,
178 .settings = {
179 [GPIOMUX_ACTIVE] = &cam_settings[3],
180 [GPIOMUX_SUSPENDED] = &cam_settings[8],
181 },
182 },
183};
184
185#ifdef CONFIG_MSM_CAMERA
186
187static uint16_t msm_cam_gpio_2d_tbl[] = {
188 5, /*CAMIF_MCLK*/
189 20, /*CAMIF_I2C_DATA*/
190 21, /*CAMIF_I2C_CLK*/
191};
192
193static struct msm_camera_gpio_conf gpio_conf = {
194 .cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
195 .cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
196 .cam_gpio_tbl = msm_cam_gpio_2d_tbl,
197 .cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
198};
199
200#define VFE_CAMIF_TIMER1_GPIO 2
201#define VFE_CAMIF_TIMER2_GPIO 3
202#define VFE_CAMIF_TIMER3_GPIO_INT 4
Stepan Moskovchenkofc70d902011-11-30 12:39:36 -0800203static struct msm_camera_sensor_strobe_flash_data strobe_flash_xenon = {
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -0800204 .flash_trigger = VFE_CAMIF_TIMER2_GPIO,
205 .flash_charge = VFE_CAMIF_TIMER1_GPIO,
206 .flash_charge_done = VFE_CAMIF_TIMER3_GPIO_INT,
207 .flash_recharge_duration = 50000,
208 .irq = MSM_GPIO_TO_INT(VFE_CAMIF_TIMER3_GPIO_INT),
209};
210
211#ifdef CONFIG_MSM_CAMERA_FLASH
212static struct msm_camera_sensor_flash_src msm_flash_src = {
213 .flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
Kevin Chancfab2f72011-12-02 13:05:51 -0800214 ._fsrc.ext_driver_src.led_en = VFE_CAMIF_TIMER1_GPIO,
215 ._fsrc.ext_driver_src.led_flash_en = VFE_CAMIF_TIMER2_GPIO,
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -0800216};
217#endif
218
219static struct msm_bus_vectors cam_init_vectors[] = {
220 {
221 .src = MSM_BUS_MASTER_VFE,
222 .dst = MSM_BUS_SLAVE_EBI_CH0,
223 .ab = 0,
224 .ib = 0,
225 },
226 {
227 .src = MSM_BUS_MASTER_VPE,
228 .dst = MSM_BUS_SLAVE_EBI_CH0,
229 .ab = 0,
230 .ib = 0,
231 },
232 {
233 .src = MSM_BUS_MASTER_JPEG_ENC,
234 .dst = MSM_BUS_SLAVE_EBI_CH0,
235 .ab = 0,
236 .ib = 0,
237 },
238};
239
240static struct msm_bus_vectors cam_preview_vectors[] = {
241 {
242 .src = MSM_BUS_MASTER_VFE,
243 .dst = MSM_BUS_SLAVE_EBI_CH0,
244 .ab = 27648000,
245 .ib = 110592000,
246 },
247 {
248 .src = MSM_BUS_MASTER_VPE,
249 .dst = MSM_BUS_SLAVE_EBI_CH0,
250 .ab = 0,
251 .ib = 0,
252 },
253 {
254 .src = MSM_BUS_MASTER_JPEG_ENC,
255 .dst = MSM_BUS_SLAVE_EBI_CH0,
256 .ab = 0,
257 .ib = 0,
258 },
259};
260
261static struct msm_bus_vectors cam_video_vectors[] = {
262 {
263 .src = MSM_BUS_MASTER_VFE,
264 .dst = MSM_BUS_SLAVE_EBI_CH0,
265 .ab = 140451840,
266 .ib = 561807360,
267 },
268 {
269 .src = MSM_BUS_MASTER_VPE,
270 .dst = MSM_BUS_SLAVE_EBI_CH0,
271 .ab = 206807040,
272 .ib = 488816640,
273 },
274 {
275 .src = MSM_BUS_MASTER_JPEG_ENC,
276 .dst = MSM_BUS_SLAVE_EBI_CH0,
277 .ab = 0,
278 .ib = 0,
279 },
280};
281
282static struct msm_bus_vectors cam_snapshot_vectors[] = {
283 {
284 .src = MSM_BUS_MASTER_VFE,
285 .dst = MSM_BUS_SLAVE_EBI_CH0,
286 .ab = 274423680,
287 .ib = 1097694720,
288 },
289 {
290 .src = MSM_BUS_MASTER_VPE,
291 .dst = MSM_BUS_SLAVE_EBI_CH0,
292 .ab = 0,
293 .ib = 0,
294 },
295 {
296 .src = MSM_BUS_MASTER_JPEG_ENC,
297 .dst = MSM_BUS_SLAVE_EBI_CH0,
298 .ab = 540000000,
299 .ib = 1350000000,
300 },
301};
302
303static struct msm_bus_vectors cam_zsl_vectors[] = {
304 {
305 .src = MSM_BUS_MASTER_VFE,
306 .dst = MSM_BUS_SLAVE_EBI_CH0,
307 .ab = 302071680,
308 .ib = 1208286720,
309 },
310 {
311 .src = MSM_BUS_MASTER_VPE,
312 .dst = MSM_BUS_SLAVE_EBI_CH0,
313 .ab = 0,
314 .ib = 0,
315 },
316 {
317 .src = MSM_BUS_MASTER_JPEG_ENC,
318 .dst = MSM_BUS_SLAVE_EBI_CH0,
319 .ab = 540000000,
320 .ib = 1350000000,
321 },
322};
323
324static struct msm_bus_paths cam_bus_client_config[] = {
325 {
326 ARRAY_SIZE(cam_init_vectors),
327 cam_init_vectors,
328 },
329 {
330 ARRAY_SIZE(cam_preview_vectors),
331 cam_preview_vectors,
332 },
333 {
334 ARRAY_SIZE(cam_video_vectors),
335 cam_video_vectors,
336 },
337 {
338 ARRAY_SIZE(cam_snapshot_vectors),
339 cam_snapshot_vectors,
340 },
341 {
342 ARRAY_SIZE(cam_zsl_vectors),
343 cam_zsl_vectors,
344 },
345};
346
347static struct msm_bus_scale_pdata cam_bus_client_pdata = {
348 cam_bus_client_config,
349 ARRAY_SIZE(cam_bus_client_config),
350 .name = "msm_camera",
351};
352
Stepan Moskovchenkofc70d902011-11-30 12:39:36 -0800353static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -0800354 {
355 .ioclk.mclk_clk_rate = 24000000,
356 .ioclk.vfe_clk_rate = 228570000,
357 .csid_core = 0,
358 .cam_bus_scale_table = &cam_bus_client_pdata,
359 },
360 {
361 .ioclk.mclk_clk_rate = 24000000,
362 .ioclk.vfe_clk_rate = 228570000,
363 .csid_core = 1,
364 .cam_bus_scale_table = &cam_bus_client_pdata,
365 },
366};
367
368#ifdef CONFIG_IMX074_ACT
369static struct i2c_board_info imx074_actuator_i2c_info = {
370 I2C_BOARD_INFO("imx074_act", 0x11),
371};
372
373static struct msm_actuator_info imx074_actuator_info = {
374 .board_info = &imx074_actuator_i2c_info,
375 .bus_id = MSM_8960_GSBI4_QUP_I2C_BUS_ID,
376 .vcm_pwd = 0,
377 .vcm_enable = 1,
378};
379#endif
380
381#ifdef CONFIG_IMX074
382static struct msm_camera_sensor_flash_data flash_imx074 = {
383 .flash_type = MSM_CAMERA_FLASH_LED,
384#ifdef CONFIG_MSM_CAMERA_FLASH
385 .flash_src = &msm_flash_src
386#endif
387};
388
389static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
390 .mount_angle = 90,
391 .sensor_reset = 107,
392 .sensor_pwd = 85,
393 .vcm_pwd = 0,
394 .vcm_enable = 1,
395};
396
397static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
398 .sensor_name = "imx074",
399 .pdata = &msm_camera_csi_device_data[0],
400 .flash_data = &flash_imx074,
401 .strobe_flash_data = &strobe_flash_xenon,
402 .sensor_platform_info = &sensor_board_info_imx074,
403 .gpio_conf = &gpio_conf,
404 .csi_if = 1,
405 .camera_type = BACK_CAMERA_2D,
406#ifdef CONFIG_IMX074_ACT
407 .actuator_info = &imx074_actuator_info
408#endif
409};
410
Stepan Moskovchenkofc70d902011-11-30 12:39:36 -0800411static struct platform_device msm8960_camera_sensor_imx074 = {
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -0800412 .name = "msm_camera_imx074",
413 .dev = {
414 .platform_data = &msm_camera_sensor_imx074_data,
415 },
416};
417#endif
418#ifdef CONFIG_OV2720
419static struct msm_camera_sensor_flash_data flash_ov2720 = {
420 .flash_type = MSM_CAMERA_FLASH_NONE,
421};
422
423static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
424 .mount_angle = 0,
425 .sensor_reset = 76,
426 .sensor_pwd = 85,
427 .vcm_pwd = 0,
428 .vcm_enable = 1,
429};
430
431static struct msm_camera_sensor_info msm_camera_sensor_ov2720_data = {
432 .sensor_name = "ov2720",
433 .pdata = &msm_camera_csi_device_data[1],
434 .flash_data = &flash_ov2720,
435 .sensor_platform_info = &sensor_board_info_ov2720,
436 .gpio_conf = &gpio_conf,
437 .csi_if = 1,
438 .camera_type = FRONT_CAMERA_2D,
439};
440
Stepan Moskovchenkofc70d902011-11-30 12:39:36 -0800441static struct platform_device msm8960_camera_sensor_ov2720 = {
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -0800442 .name = "msm_camera_ov2720",
443 .dev = {
444 .platform_data = &msm_camera_sensor_ov2720_data,
445 },
446};
447#endif
448
449static struct msm8960_privacy_light_cfg privacy_light_info = {
450 .mpp = PM8921_MPP_PM_TO_SYS(12),
451};
452
453void __init msm8960_init_cam(void)
454{
455 int i;
456 struct platform_device *cam_dev[] = {
457 &msm8960_camera_sensor_imx074,
458 &msm8960_camera_sensor_ov2720,
459 };
460
461 msm_gpiomux_install(msm8960_cam_common_configs,
462 ARRAY_SIZE(msm8960_cam_common_configs));
463
Kevin Chancfab2f72011-12-02 13:05:51 -0800464 if (machine_is_msm8960_cdp()) {
465 msm_gpiomux_install(msm8960_cdp_flash_configs,
466 ARRAY_SIZE(msm8960_cdp_flash_configs));
467 msm_flash_src._fsrc.ext_driver_src.led_en =
468 GPIO_CAM_GP_LED_EN1;
469 msm_flash_src._fsrc.ext_driver_src.led_flash_en =
470 GPIO_CAM_GP_LED_EN2;
471 #if defined(CONFIG_I2C) && (defined(CONFIG_GPIO_SX150X) || \
472 defined(CONFIG_GPIO_SX150X_MODULE))
473 msm_flash_src._fsrc.ext_driver_src.expander_info =
474 cam_expander_info;
475 #endif
476 }
477
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -0800478 if (machine_is_msm8960_liquid()) {
479 struct msm_camera_sensor_info *s_info;
480 s_info = msm8960_camera_sensor_imx074.dev.platform_data;
481 s_info->sensor_platform_info->mount_angle = 180;
482 s_info = msm8960_camera_sensor_ov2720.dev.platform_data;
483 s_info->sensor_platform_info->privacy_light = 1;
484 s_info->sensor_platform_info->privacy_light_info =
485 &privacy_light_info;
486 }
487
488 for (i = 0; i < ARRAY_SIZE(cam_dev); i++) {
489 struct msm_camera_sensor_info *s_info;
490 s_info = cam_dev[i]->dev.platform_data;
491 msm_get_cam_resources(s_info);
492 platform_device_register(cam_dev[i]);
493 }
494
495 platform_device_register(&msm8960_device_csiphy0);
496 platform_device_register(&msm8960_device_csiphy1);
497 platform_device_register(&msm8960_device_csid0);
498 platform_device_register(&msm8960_device_csid1);
499 platform_device_register(&msm8960_device_ispif);
500 platform_device_register(&msm8960_device_vfe);
501 platform_device_register(&msm8960_device_vpe);
502}
503#endif