blob: 53848880e2a9033e6c84c7e90b3142fe0d51fa33 [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"
22#include "board-msm8960.h"
23
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
99
100static struct msm_gpiomux_config msm8960_cam_common_configs[] = {
101 {
102 .gpio = 2,
103 .settings = {
104 [GPIOMUX_ACTIVE] = &cam_settings[2],
105 [GPIOMUX_SUSPENDED] = &cam_settings[0],
106 },
107 },
108 {
109 .gpio = 3,
110 .settings = {
111 [GPIOMUX_ACTIVE] = &cam_settings[1],
112 [GPIOMUX_SUSPENDED] = &cam_settings[0],
113 },
114 },
115 {
116 .gpio = 4,
117 .settings = {
118 [GPIOMUX_ACTIVE] = &cam_settings[1],
119 [GPIOMUX_SUSPENDED] = &cam_settings[0],
120 },
121 },
122 {
123 .gpio = 5,
124 .settings = {
125 [GPIOMUX_ACTIVE] = &cam_settings[1],
126 [GPIOMUX_SUSPENDED] = &cam_settings[0],
127 },
128 },
129 {
130 .gpio = 76,
131 .settings = {
132 [GPIOMUX_ACTIVE] = &cam_settings[2],
133 [GPIOMUX_SUSPENDED] = &cam_settings[0],
134 },
135 },
136 {
137 .gpio = 107,
138 .settings = {
139 [GPIOMUX_ACTIVE] = &cam_settings[2],
140 [GPIOMUX_SUSPENDED] = &cam_settings[0],
141 },
142 },
143};
144
145static struct msm_gpiomux_config msm8960_cam_2d_configs[] = {
146 {
147 .gpio = 18,
148 .settings = {
149 [GPIOMUX_ACTIVE] = &cam_settings[3],
150 [GPIOMUX_SUSPENDED] = &cam_settings[8],
151 },
152 },
153 {
154 .gpio = 19,
155 .settings = {
156 [GPIOMUX_ACTIVE] = &cam_settings[3],
157 [GPIOMUX_SUSPENDED] = &cam_settings[8],
158 },
159 },
160 {
161 .gpio = 20,
162 .settings = {
163 [GPIOMUX_ACTIVE] = &cam_settings[3],
164 [GPIOMUX_SUSPENDED] = &cam_settings[8],
165 },
166 },
167 {
168 .gpio = 21,
169 .settings = {
170 [GPIOMUX_ACTIVE] = &cam_settings[3],
171 [GPIOMUX_SUSPENDED] = &cam_settings[8],
172 },
173 },
174};
175
176#ifdef CONFIG_MSM_CAMERA
177
178static uint16_t msm_cam_gpio_2d_tbl[] = {
179 5, /*CAMIF_MCLK*/
180 20, /*CAMIF_I2C_DATA*/
181 21, /*CAMIF_I2C_CLK*/
182};
183
184static struct msm_camera_gpio_conf gpio_conf = {
185 .cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
186 .cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
187 .cam_gpio_tbl = msm_cam_gpio_2d_tbl,
188 .cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
189};
190
191#define VFE_CAMIF_TIMER1_GPIO 2
192#define VFE_CAMIF_TIMER2_GPIO 3
193#define VFE_CAMIF_TIMER3_GPIO_INT 4
Stepan Moskovchenkofc70d902011-11-30 12:39:36 -0800194static struct msm_camera_sensor_strobe_flash_data strobe_flash_xenon = {
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -0800195 .flash_trigger = VFE_CAMIF_TIMER2_GPIO,
196 .flash_charge = VFE_CAMIF_TIMER1_GPIO,
197 .flash_charge_done = VFE_CAMIF_TIMER3_GPIO_INT,
198 .flash_recharge_duration = 50000,
199 .irq = MSM_GPIO_TO_INT(VFE_CAMIF_TIMER3_GPIO_INT),
200};
201
202#ifdef CONFIG_MSM_CAMERA_FLASH
203static struct msm_camera_sensor_flash_src msm_flash_src = {
204 .flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
205 ._fsrc.ext_driver_src.led_en = GPIO_CAM_GP_LED_EN1,
206 ._fsrc.ext_driver_src.led_flash_en = GPIO_CAM_GP_LED_EN2,
207#if defined(CONFIG_I2C) && (defined(CONFIG_GPIO_SX150X) || \
208 defined(CONFIG_GPIO_SX150X_MODULE))
209 ._fsrc.ext_driver_src.expander_info = cam_expander_info,
210#endif
211};
212#endif
213
214static struct msm_bus_vectors cam_init_vectors[] = {
215 {
216 .src = MSM_BUS_MASTER_VFE,
217 .dst = MSM_BUS_SLAVE_EBI_CH0,
218 .ab = 0,
219 .ib = 0,
220 },
221 {
222 .src = MSM_BUS_MASTER_VPE,
223 .dst = MSM_BUS_SLAVE_EBI_CH0,
224 .ab = 0,
225 .ib = 0,
226 },
227 {
228 .src = MSM_BUS_MASTER_JPEG_ENC,
229 .dst = MSM_BUS_SLAVE_EBI_CH0,
230 .ab = 0,
231 .ib = 0,
232 },
233};
234
235static struct msm_bus_vectors cam_preview_vectors[] = {
236 {
237 .src = MSM_BUS_MASTER_VFE,
238 .dst = MSM_BUS_SLAVE_EBI_CH0,
239 .ab = 27648000,
240 .ib = 110592000,
241 },
242 {
243 .src = MSM_BUS_MASTER_VPE,
244 .dst = MSM_BUS_SLAVE_EBI_CH0,
245 .ab = 0,
246 .ib = 0,
247 },
248 {
249 .src = MSM_BUS_MASTER_JPEG_ENC,
250 .dst = MSM_BUS_SLAVE_EBI_CH0,
251 .ab = 0,
252 .ib = 0,
253 },
254};
255
256static struct msm_bus_vectors cam_video_vectors[] = {
257 {
258 .src = MSM_BUS_MASTER_VFE,
259 .dst = MSM_BUS_SLAVE_EBI_CH0,
260 .ab = 140451840,
261 .ib = 561807360,
262 },
263 {
264 .src = MSM_BUS_MASTER_VPE,
265 .dst = MSM_BUS_SLAVE_EBI_CH0,
266 .ab = 206807040,
267 .ib = 488816640,
268 },
269 {
270 .src = MSM_BUS_MASTER_JPEG_ENC,
271 .dst = MSM_BUS_SLAVE_EBI_CH0,
272 .ab = 0,
273 .ib = 0,
274 },
275};
276
277static struct msm_bus_vectors cam_snapshot_vectors[] = {
278 {
279 .src = MSM_BUS_MASTER_VFE,
280 .dst = MSM_BUS_SLAVE_EBI_CH0,
281 .ab = 274423680,
282 .ib = 1097694720,
283 },
284 {
285 .src = MSM_BUS_MASTER_VPE,
286 .dst = MSM_BUS_SLAVE_EBI_CH0,
287 .ab = 0,
288 .ib = 0,
289 },
290 {
291 .src = MSM_BUS_MASTER_JPEG_ENC,
292 .dst = MSM_BUS_SLAVE_EBI_CH0,
293 .ab = 540000000,
294 .ib = 1350000000,
295 },
296};
297
298static struct msm_bus_vectors cam_zsl_vectors[] = {
299 {
300 .src = MSM_BUS_MASTER_VFE,
301 .dst = MSM_BUS_SLAVE_EBI_CH0,
302 .ab = 302071680,
303 .ib = 1208286720,
304 },
305 {
306 .src = MSM_BUS_MASTER_VPE,
307 .dst = MSM_BUS_SLAVE_EBI_CH0,
308 .ab = 0,
309 .ib = 0,
310 },
311 {
312 .src = MSM_BUS_MASTER_JPEG_ENC,
313 .dst = MSM_BUS_SLAVE_EBI_CH0,
314 .ab = 540000000,
315 .ib = 1350000000,
316 },
317};
318
319static struct msm_bus_paths cam_bus_client_config[] = {
320 {
321 ARRAY_SIZE(cam_init_vectors),
322 cam_init_vectors,
323 },
324 {
325 ARRAY_SIZE(cam_preview_vectors),
326 cam_preview_vectors,
327 },
328 {
329 ARRAY_SIZE(cam_video_vectors),
330 cam_video_vectors,
331 },
332 {
333 ARRAY_SIZE(cam_snapshot_vectors),
334 cam_snapshot_vectors,
335 },
336 {
337 ARRAY_SIZE(cam_zsl_vectors),
338 cam_zsl_vectors,
339 },
340};
341
342static struct msm_bus_scale_pdata cam_bus_client_pdata = {
343 cam_bus_client_config,
344 ARRAY_SIZE(cam_bus_client_config),
345 .name = "msm_camera",
346};
347
Stepan Moskovchenkofc70d902011-11-30 12:39:36 -0800348static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -0800349 {
350 .ioclk.mclk_clk_rate = 24000000,
351 .ioclk.vfe_clk_rate = 228570000,
352 .csid_core = 0,
353 .cam_bus_scale_table = &cam_bus_client_pdata,
354 },
355 {
356 .ioclk.mclk_clk_rate = 24000000,
357 .ioclk.vfe_clk_rate = 228570000,
358 .csid_core = 1,
359 .cam_bus_scale_table = &cam_bus_client_pdata,
360 },
361};
362
363#ifdef CONFIG_IMX074_ACT
364static struct i2c_board_info imx074_actuator_i2c_info = {
365 I2C_BOARD_INFO("imx074_act", 0x11),
366};
367
368static struct msm_actuator_info imx074_actuator_info = {
369 .board_info = &imx074_actuator_i2c_info,
370 .bus_id = MSM_8960_GSBI4_QUP_I2C_BUS_ID,
371 .vcm_pwd = 0,
372 .vcm_enable = 1,
373};
374#endif
375
376#ifdef CONFIG_IMX074
377static struct msm_camera_sensor_flash_data flash_imx074 = {
378 .flash_type = MSM_CAMERA_FLASH_LED,
379#ifdef CONFIG_MSM_CAMERA_FLASH
380 .flash_src = &msm_flash_src
381#endif
382};
383
384static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
385 .mount_angle = 90,
386 .sensor_reset = 107,
387 .sensor_pwd = 85,
388 .vcm_pwd = 0,
389 .vcm_enable = 1,
390};
391
392static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
393 .sensor_name = "imx074",
394 .pdata = &msm_camera_csi_device_data[0],
395 .flash_data = &flash_imx074,
396 .strobe_flash_data = &strobe_flash_xenon,
397 .sensor_platform_info = &sensor_board_info_imx074,
398 .gpio_conf = &gpio_conf,
399 .csi_if = 1,
400 .camera_type = BACK_CAMERA_2D,
401#ifdef CONFIG_IMX074_ACT
402 .actuator_info = &imx074_actuator_info
403#endif
404};
405
Stepan Moskovchenkofc70d902011-11-30 12:39:36 -0800406static struct platform_device msm8960_camera_sensor_imx074 = {
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -0800407 .name = "msm_camera_imx074",
408 .dev = {
409 .platform_data = &msm_camera_sensor_imx074_data,
410 },
411};
412#endif
413#ifdef CONFIG_OV2720
414static struct msm_camera_sensor_flash_data flash_ov2720 = {
415 .flash_type = MSM_CAMERA_FLASH_NONE,
416};
417
418static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
419 .mount_angle = 0,
420 .sensor_reset = 76,
421 .sensor_pwd = 85,
422 .vcm_pwd = 0,
423 .vcm_enable = 1,
424};
425
426static struct msm_camera_sensor_info msm_camera_sensor_ov2720_data = {
427 .sensor_name = "ov2720",
428 .pdata = &msm_camera_csi_device_data[1],
429 .flash_data = &flash_ov2720,
430 .sensor_platform_info = &sensor_board_info_ov2720,
431 .gpio_conf = &gpio_conf,
432 .csi_if = 1,
433 .camera_type = FRONT_CAMERA_2D,
434};
435
Stepan Moskovchenkofc70d902011-11-30 12:39:36 -0800436static struct platform_device msm8960_camera_sensor_ov2720 = {
Stepan Moskovchenkoc6ada422011-11-28 19:31:16 -0800437 .name = "msm_camera_ov2720",
438 .dev = {
439 .platform_data = &msm_camera_sensor_ov2720_data,
440 },
441};
442#endif
443
444static struct msm8960_privacy_light_cfg privacy_light_info = {
445 .mpp = PM8921_MPP_PM_TO_SYS(12),
446};
447
448void __init msm8960_init_cam(void)
449{
450 int i;
451 struct platform_device *cam_dev[] = {
452 &msm8960_camera_sensor_imx074,
453 &msm8960_camera_sensor_ov2720,
454 };
455
456 msm_gpiomux_install(msm8960_cam_common_configs,
457 ARRAY_SIZE(msm8960_cam_common_configs));
458
459 if (machine_is_msm8960_liquid()) {
460 struct msm_camera_sensor_info *s_info;
461 s_info = msm8960_camera_sensor_imx074.dev.platform_data;
462 s_info->sensor_platform_info->mount_angle = 180;
463 s_info = msm8960_camera_sensor_ov2720.dev.platform_data;
464 s_info->sensor_platform_info->privacy_light = 1;
465 s_info->sensor_platform_info->privacy_light_info =
466 &privacy_light_info;
467 }
468
469 for (i = 0; i < ARRAY_SIZE(cam_dev); i++) {
470 struct msm_camera_sensor_info *s_info;
471 s_info = cam_dev[i]->dev.platform_data;
472 msm_get_cam_resources(s_info);
473 platform_device_register(cam_dev[i]);
474 }
475
476 platform_device_register(&msm8960_device_csiphy0);
477 platform_device_register(&msm8960_device_csiphy1);
478 platform_device_register(&msm8960_device_csid0);
479 platform_device_register(&msm8960_device_csid1);
480 platform_device_register(&msm8960_device_ispif);
481 platform_device_register(&msm8960_device_vfe);
482 platform_device_register(&msm8960_device_vpe);
483}
484#endif