blob: e96284af9199d6ceed61553a16fc49aad2631ace [file] [log] [blame]
Chintan Pandya250c2e52012-01-19 17:15:49 +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/init.h>
14#include <linux/ioport.h>
15#include <linux/platform_device.h>
16#include <linux/bootmem.h>
17#include <linux/regulator/consumer.h>
18#include <asm/mach-types.h>
19#include <asm/io.h>
20#include <mach/msm_bus_board.h>
21#include <mach/msm_memtypes.h>
22#include <mach/board.h>
23#include <mach/gpio.h>
24#include <mach/gpiomux.h>
25#include <mach/socinfo.h>
26#include <mach/rpc_pmapp.h>
27#include "devices.h"
28#include "board-msm7627a.h"
29
30#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
Padmanabhan Komanduruede0a632012-01-25 12:01:28 +053031#define MSM_FB_SIZE 0x261000
Chintan Pandya250c2e52012-01-19 17:15:49 +053032#define MSM7x25A_MSM_FB_SIZE 0xE1000
33#else
Padmanabhan Komanduruede0a632012-01-25 12:01:28 +053034#define MSM_FB_SIZE 0x196000
Chintan Pandya250c2e52012-01-19 17:15:49 +053035#define MSM7x25A_MSM_FB_SIZE 0x96000
36#endif
37
Alhad Purnapatrec55856c2012-02-28 13:24:57 -080038/*
39 * Reserve enough v4l2 space for a double buffered full screen
40 * res image (864x480x1.5x2)
41 */
42#define MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE 1244160
43
Chintan Pandya250c2e52012-01-19 17:15:49 +053044static unsigned fb_size = MSM_FB_SIZE;
45static int __init fb_size_setup(char *p)
46{
47 fb_size = memparse(p, NULL);
48 return 0;
49}
50
51early_param("fb_size", fb_size_setup);
52
Jeevan Shriram901a15f2012-03-09 11:53:23 +053053static uint32_t lcdc_truly_gpio_initialized;
54static struct regulator_bulk_data regs_truly_lcdc[] = {
55 { .supply = "rfrx1", .min_uV = 1800000, .max_uV = 1800000 },
56};
57
58#define SKU3_LCDC_GPIO_DISPLAY_RESET 90
59#define SKU3_LCDC_GPIO_SPI_MOSI 19
60#define SKU3_LCDC_GPIO_SPI_CLK 20
61#define SKU3_LCDC_GPIO_SPI_CS0_N 21
62#define SKU3_LCDC_LCD_CAMERA_LDO_2V8 35 /*LCD_CAMERA_LDO_2V8*/
63#define SKU3_LCDC_LCD_CAMERA_LDO_1V8 34 /*LCD_CAMERA_LDO_1V8*/
64#define SKU3_1_LCDC_LCD_CAMERA_LDO_1V8 58 /*LCD_CAMERA_LDO_1V8*/
65
66static uint32_t lcdc_truly_gpio_table[] = {
67 19,
68 20,
69 21,
70 89,
71 90,
72};
73
74static char *lcdc_gpio_name_table[5] = {
75 "spi_mosi",
76 "spi_clk",
77 "spi_cs",
78 "gpio_bkl_en",
79 "gpio_disp_reset",
80};
81
82static int lcdc_truly_gpio_init(void)
83{
84 int i;
85 int rc = 0;
86
87 if (!lcdc_truly_gpio_initialized) {
88 for (i = 0; i < ARRAY_SIZE(lcdc_truly_gpio_table); i++) {
89 rc = gpio_request(lcdc_truly_gpio_table[i],
90 lcdc_gpio_name_table[i]);
91 if (rc < 0) {
92 pr_err("Error request gpio %s\n",
93 lcdc_gpio_name_table[i]);
94 goto truly_gpio_fail;
95 }
96 rc = gpio_tlmm_config(GPIO_CFG(lcdc_truly_gpio_table[i],
97 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
98 GPIO_CFG_2MA), GPIO_CFG_ENABLE);
99 if (rc < 0) {
100 pr_err("Error config lcdc gpio:%d\n",
101 lcdc_truly_gpio_table[i]);
102 goto truly_gpio_fail;
103 }
104 rc = gpio_direction_output(lcdc_truly_gpio_table[i], 0);
105 if (rc < 0) {
106 pr_err("Error direct lcdc gpio:%d\n",
107 lcdc_truly_gpio_table[i]);
108 goto truly_gpio_fail;
109 }
110 }
111
112 lcdc_truly_gpio_initialized = 1;
113 }
114
115 return rc;
116
117truly_gpio_fail:
118 for (; i >= 0; i--) {
119 pr_err("Freeing GPIO: %d", lcdc_truly_gpio_table[i]);
120 gpio_free(lcdc_truly_gpio_table[i]);
121 }
122
123 lcdc_truly_gpio_initialized = 0;
124 return rc;
125}
126
127
128void sku3_lcdc_lcd_camera_power_init(void)
129{
130 int rc = 0;
131 u32 socinfo = socinfo_get_platform_type();
132
133 /* LDO_EXT2V8 */
134 if (gpio_request(SKU3_LCDC_LCD_CAMERA_LDO_2V8, "lcd_camera_ldo_2v8")) {
135 pr_err("failed to request gpio lcd_camera_ldo_2v8\n");
136 return;
137 }
138
139 rc = gpio_tlmm_config(GPIO_CFG(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 0,
140 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
141 GPIO_CFG_ENABLE);
142
143 if (rc < 0) {
144 pr_err("%s:unable to enable lcd_camera_ldo_2v8!\n", __func__);
145 goto fail_gpio2;
146 }
147
148 /* LDO_EVT1V8 */
149 if (socinfo == 0x0B) {
150 if (gpio_request(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
151 "lcd_camera_ldo_1v8")) {
152 pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
153 goto fail_gpio1;
154 }
155
156 rc = gpio_tlmm_config(GPIO_CFG(SKU3_LCDC_LCD_CAMERA_LDO_1V8, 0,
157 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
158 GPIO_CFG_ENABLE);
159
160 if (rc < 0) {
161 pr_err("%s: unable to enable lcdc_camera_ldo_1v8!\n",
162 __func__);
163 goto fail_gpio1;
164 }
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530165 } else if (socinfo == 0x0F || machine_is_msm8625_qrd7()) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530166 if (gpio_request(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
167 "lcd_camera_ldo_1v8")) {
168 pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
169 goto fail_gpio1;
170 }
171
172 rc = gpio_tlmm_config(GPIO_CFG(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
173 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
174 GPIO_CFG_ENABLE);
175
176 if (rc < 0) {
177 pr_err("%s: unable to enable lcdc_camera_ldo_1v8!\n",
178 __func__);
179 goto fail_gpio1;
180 }
181 }
182
183 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_truly_lcdc),
184 regs_truly_lcdc);
185 if (rc)
186 pr_err("%s: could not get regulators: %d\n", __func__, rc);
187
188 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_truly_lcdc),
189 regs_truly_lcdc);
190 if (rc)
191 pr_err("%s: could not set voltages: %d\n", __func__, rc);
192
193 return;
194
195fail_gpio1:
196 if (socinfo == 0x0B)
197 gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_1V8);
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530198 else if (socinfo == 0x0F || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530199 gpio_free(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8);
200fail_gpio2:
201 gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_2V8);
202 return;
203}
204
205int sku3_lcdc_lcd_camera_power_onoff(int on)
206{
207 int rc = 0;
208 u32 socinfo = socinfo_get_platform_type();
209
210 if (on) {
211 if (socinfo == 0x0B)
212 gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
213 1);
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530214 else if (socinfo == 0x0F || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530215 gpio_set_value_cansleep(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
216 1);
217
218 gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 1);
219
220 rc = regulator_bulk_enable(ARRAY_SIZE(regs_truly_lcdc),
221 regs_truly_lcdc);
222 if (rc)
223 pr_err("%s: could not enable regulators: %d\n",
224 __func__, rc);
225 } else {
226 if (socinfo == 0x0B)
227 gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
228 0);
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530229 else if (socinfo == 0x0F || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530230 gpio_set_value_cansleep(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
231 0);
232
233 gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 0);
234
235 rc = regulator_bulk_disable(ARRAY_SIZE(regs_truly_lcdc),
236 regs_truly_lcdc);
237 if (rc)
238 pr_err("%s: could not disable regulators: %d\n",
239 __func__, rc);
240 }
241
242 return rc;
243}
244
245static int sku3_lcdc_power_save(int on)
246{
247 int rc = 0;
248
249 if (on) {
250 sku3_lcdc_lcd_camera_power_onoff(1);
251 rc = lcdc_truly_gpio_init();
252 if (rc < 0) {
253 pr_err("%s(): Truly GPIO initializations failed",
254 __func__);
255 return rc;
256 }
257
258 if (lcdc_truly_gpio_initialized) {
259 /*LCD reset*/
260 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 1);
261 msleep(20);
262 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 0);
263 msleep(20);
264 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 1);
265 msleep(20);
266 }
267 } else {
268 /* pull down LCD IO to avoid current leakage */
269 gpio_set_value(SKU3_LCDC_GPIO_SPI_MOSI, 0);
270 gpio_set_value(SKU3_LCDC_GPIO_SPI_CLK, 0);
271 gpio_set_value(SKU3_LCDC_GPIO_SPI_CS0_N, 0);
272 gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 0);
273
274 sku3_lcdc_lcd_camera_power_onoff(0);
275 }
276 return rc;
277}
278
279static struct msm_panel_common_pdata lcdc_truly_panel_data = {
280 .panel_config_gpio = NULL,
281 .gpio_num = lcdc_truly_gpio_table,
282};
283
284static struct platform_device lcdc_truly_panel_device = {
285 .name = "lcdc_truly_hvga_ips3p2335_pt",
286 .id = 0,
287 .dev = {
288 .platform_data = &lcdc_truly_panel_data,
289 }
290};
291
Chintan Pandya250c2e52012-01-19 17:15:49 +0530292static struct regulator_bulk_data regs_lcdc[] = {
293 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
294 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
295};
296static uint32_t lcdc_gpio_initialized;
297
298static void lcdc_toshiba_gpio_init(void)
299{
300 int rc = 0;
301 if (!lcdc_gpio_initialized) {
302 if (gpio_request(GPIO_SPI_CLK, "spi_clk")) {
303 pr_err("failed to request gpio spi_clk\n");
304 return;
305 }
306 if (gpio_request(GPIO_SPI_CS0_N, "spi_cs")) {
307 pr_err("failed to request gpio spi_cs0_N\n");
308 goto fail_gpio6;
309 }
310 if (gpio_request(GPIO_SPI_MOSI, "spi_mosi")) {
311 pr_err("failed to request gpio spi_mosi\n");
312 goto fail_gpio5;
313 }
314 if (gpio_request(GPIO_SPI_MISO, "spi_miso")) {
315 pr_err("failed to request gpio spi_miso\n");
316 goto fail_gpio4;
317 }
318 if (gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr")) {
319 pr_err("failed to request gpio_disp_pwr\n");
320 goto fail_gpio3;
321 }
322 if (gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en")) {
323 pr_err("failed to request gpio_bkl_en\n");
324 goto fail_gpio2;
325 }
326 pmapp_disp_backlight_init();
327
328 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_lcdc),
329 regs_lcdc);
330 if (rc) {
331 pr_err("%s: could not get regulators: %d\n",
332 __func__, rc);
333 goto fail_gpio1;
334 }
335
336 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_lcdc),
337 regs_lcdc);
338 if (rc) {
339 pr_err("%s: could not set voltages: %d\n",
340 __func__, rc);
341 goto fail_vreg;
342 }
343 lcdc_gpio_initialized = 1;
344 }
345 return;
346fail_vreg:
347 regulator_bulk_free(ARRAY_SIZE(regs_lcdc), regs_lcdc);
348fail_gpio1:
349 gpio_free(GPIO_BACKLIGHT_EN);
350fail_gpio2:
351 gpio_free(GPIO_DISPLAY_PWR_EN);
352fail_gpio3:
353 gpio_free(GPIO_SPI_MISO);
354fail_gpio4:
355 gpio_free(GPIO_SPI_MOSI);
356fail_gpio5:
357 gpio_free(GPIO_SPI_CS0_N);
358fail_gpio6:
359 gpio_free(GPIO_SPI_CLK);
360 lcdc_gpio_initialized = 0;
361}
362
363static uint32_t lcdc_gpio_table[] = {
364 GPIO_SPI_CLK,
365 GPIO_SPI_CS0_N,
366 GPIO_SPI_MOSI,
367 GPIO_DISPLAY_PWR_EN,
368 GPIO_BACKLIGHT_EN,
369 GPIO_SPI_MISO,
370};
371
372static void config_lcdc_gpio_table(uint32_t *table, int len, unsigned enable)
373{
374 int n;
375
376 if (lcdc_gpio_initialized) {
377 /* All are IO Expander GPIOs */
378 for (n = 0; n < (len - 1); n++)
379 gpio_direction_output(table[n], 1);
380 }
381}
382
383static void lcdc_toshiba_config_gpios(int enable)
384{
385 config_lcdc_gpio_table(lcdc_gpio_table,
386 ARRAY_SIZE(lcdc_gpio_table), enable);
387}
388
389static int msm_fb_lcdc_power_save(int on)
390{
391 int rc = 0;
392 /* Doing the init of the LCDC GPIOs very late as they are from
393 an I2C-controlled IO Expander */
394 lcdc_toshiba_gpio_init();
395
396 if (lcdc_gpio_initialized) {
397 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
398 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
399
400 rc = on ? regulator_bulk_enable(
401 ARRAY_SIZE(regs_lcdc), regs_lcdc) :
402 regulator_bulk_disable(
403 ARRAY_SIZE(regs_lcdc), regs_lcdc);
404
405 if (rc)
406 pr_err("%s: could not %sable regulators: %d\n",
407 __func__, on ? "en" : "dis", rc);
408 }
409
410 return rc;
411}
412
413static int lcdc_toshiba_set_bl(int level)
414{
415 int ret;
416
417 ret = pmapp_disp_backlight_set_brightness(level);
418 if (ret)
419 pr_err("%s: can't set lcd backlight!\n", __func__);
420
421 return ret;
422}
423
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530424
425static int msm_lcdc_power_save(int on)
426{
427 int rc = 0;
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530428 if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530429 rc = sku3_lcdc_power_save(on);
430 else
431 rc = msm_fb_lcdc_power_save(on);
432
433 return rc;
434}
435
Chintan Pandya250c2e52012-01-19 17:15:49 +0530436static struct lcdc_platform_data lcdc_pdata = {
437 .lcdc_gpio_config = NULL,
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530438 .lcdc_power_save = msm_lcdc_power_save,
Chintan Pandya250c2e52012-01-19 17:15:49 +0530439};
440
441static int lcd_panel_spi_gpio_num[] = {
442 GPIO_SPI_MOSI, /* spi_sdi */
443 GPIO_SPI_MISO, /* spi_sdoi */
444 GPIO_SPI_CLK, /* spi_clk */
445 GPIO_SPI_CS0_N, /* spi_cs */
446};
447
448static struct msm_panel_common_pdata lcdc_toshiba_panel_data = {
449 .panel_config_gpio = lcdc_toshiba_config_gpios,
450 .pmic_backlight = lcdc_toshiba_set_bl,
451 .gpio_num = lcd_panel_spi_gpio_num,
452};
453
454static struct platform_device lcdc_toshiba_panel_device = {
455 .name = "lcdc_toshiba_fwvga_pt",
456 .id = 0,
457 .dev = {
458 .platform_data = &lcdc_toshiba_panel_data,
459 }
460};
461
462static struct resource msm_fb_resources[] = {
463 {
464 .flags = IORESOURCE_DMA,
465 }
466};
467
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800468#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
469static struct resource msm_v4l2_video_overlay_resources[] = {
470 {
471 .flags = IORESOURCE_DMA,
472 }
473};
474#endif
475
Chintan Pandya250c2e52012-01-19 17:15:49 +0530476#define LCDC_TOSHIBA_FWVGA_PANEL_NAME "lcdc_toshiba_fwvga_pt"
477#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
478
479static int msm_fb_detect_panel(const char *name)
480{
481 int ret = -ENODEV;
482
Taniya Dase3027e22012-02-27 16:32:27 +0530483 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
484 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530485 if (!strncmp(name, "lcdc_toshiba_fwvga_pt", 21) ||
486 !strncmp(name, "mipi_cmd_renesas_fwvga", 22))
487 ret = 0;
488 } else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()) {
489 if (!strncmp(name, "mipi_cmd_renesas_fwvga", 22))
490 ret = 0;
491 } else if (machine_is_msm7627a_qrd1()) {
492 if (!strncmp(name, "mipi_video_truly_wvga", 21))
493 ret = 0;
Jeevan Shriram045cdc72012-03-27 07:04:15 +0530494 } else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530495 if (!strncmp(name, "lcdc_truly_hvga_ips3p2335_pt", 28))
496 ret = 0;
Chintan Pandyaf4ad4002012-02-28 19:49:03 +0530497 } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530498 if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
499 ret = 0;
Chintan Pandya250c2e52012-01-19 17:15:49 +0530500 }
501
502#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
503 !defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
504 !defined(CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT)
505 if (machine_is_msm7x27a_surf() ||
Taniya Dase3027e22012-02-27 16:32:27 +0530506 machine_is_msm7625a_surf() ||
507 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530508 if (!strncmp(name, LCDC_TOSHIBA_FWVGA_PANEL_NAME,
509 strnlen(LCDC_TOSHIBA_FWVGA_PANEL_NAME,
510 PANEL_NAME_MAX_LEN)))
511 return 0;
512 }
513#endif
514
515 return ret;
516}
517
518static int mipi_truly_set_bl(int on)
519{
520 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
521
522 return 1;
523}
524
525static struct msm_fb_platform_data msm_fb_pdata = {
526 .detect_client = msm_fb_detect_panel,
527};
528
529static struct platform_device msm_fb_device = {
530 .name = "msm_fb",
531 .id = 0,
532 .num_resources = ARRAY_SIZE(msm_fb_resources),
533 .resource = msm_fb_resources,
534 .dev = {
535 .platform_data = &msm_fb_pdata,
536 }
537};
538
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800539#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
540static struct platform_device msm_v4l2_video_overlay_device = {
541 .name = "msm_v4l2_overlay_pd",
542 .id = 0,
543 .num_resources = ARRAY_SIZE(msm_v4l2_video_overlay_resources),
544 .resource = msm_v4l2_video_overlay_resources,
545 };
546#endif
547
548
Chintan Pandya250c2e52012-01-19 17:15:49 +0530549#ifdef CONFIG_FB_MSM_MIPI_DSI
550static int mipi_renesas_set_bl(int level)
551{
552 int ret;
553
554 ret = pmapp_disp_backlight_set_brightness(level);
555
556 if (ret)
557 pr_err("%s: can't set lcd backlight!\n", __func__);
558
559 return ret;
560}
561
562static struct msm_panel_common_pdata mipi_renesas_pdata = {
563 .pmic_backlight = mipi_renesas_set_bl,
564};
565
566
567static struct platform_device mipi_dsi_renesas_panel_device = {
568 .name = "mipi_renesas",
569 .id = 0,
570 .dev = {
571 .platform_data = &mipi_renesas_pdata,
572 }
573};
574#endif
575
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530576static int evb_backlight_control(int level)
577{
578
579 int i = 0;
580 int remainder;
581 /* device address byte = 0x72 */
582 gpio_set_value_cansleep(96, 0);
583 udelay(67);
584 gpio_set_value_cansleep(96, 1);
585 udelay(33);
586 gpio_set_value_cansleep(96, 0);
587 udelay(33);
588 gpio_set_value_cansleep(96, 1);
589 udelay(67);
590 gpio_set_value_cansleep(96, 0);
591 udelay(33);
592 gpio_set_value_cansleep(96, 1);
593 udelay(67);
594 gpio_set_value_cansleep(96, 0);
595 udelay(33);
596 gpio_set_value_cansleep(96, 1);
597 udelay(67);
598 gpio_set_value_cansleep(96, 0);
599 udelay(67);
600 gpio_set_value_cansleep(96, 1);
601 udelay(33);
602 gpio_set_value_cansleep(96, 0);
603 udelay(67);
604 gpio_set_value_cansleep(96, 1);
605 udelay(33);
606 gpio_set_value_cansleep(96, 0);
607 udelay(33);
608 gpio_set_value_cansleep(96, 1);
609 udelay(67);
610 gpio_set_value_cansleep(96, 0);
611 udelay(67);
612 gpio_set_value_cansleep(96, 1);
613 udelay(33);
614
615 /* t-EOS and t-start */
616 gpio_set_value_cansleep(96, 0);
617 ndelay(4200);
618 gpio_set_value_cansleep(96, 1);
619 ndelay(9000);
620
621 /* data byte */
622 /* RFA = 0 */
623 gpio_set_value_cansleep(96, 0);
624 udelay(67);
625 gpio_set_value_cansleep(96, 1);
626 udelay(33);
627
628 /* Address bits */
629 gpio_set_value_cansleep(96, 0);
630 udelay(67);
631 gpio_set_value_cansleep(96, 1);
632 udelay(33);
633 gpio_set_value_cansleep(96, 0);
634 udelay(67);
635 gpio_set_value_cansleep(96, 1);
636 udelay(33);
637
638 /* Data bits */
639 for (i = 0; i < 5; i++) {
640 remainder = (level) & (16);
641 if (remainder) {
642 gpio_set_value_cansleep(96, 0);
643 udelay(33);
644 gpio_set_value_cansleep(96, 1);
645 udelay(67);
646 } else {
647 gpio_set_value_cansleep(96, 0);
648 udelay(67);
649 gpio_set_value_cansleep(96, 1);
650 udelay(33);
651 }
652 level = level << 1;
653 }
654
655 /* t-EOS */
656 gpio_set_value_cansleep(96, 0);
657 ndelay(12000);
658 gpio_set_value_cansleep(96, 1);
659 return 0;
660}
661
662
Chintan Pandya250c2e52012-01-19 17:15:49 +0530663static struct msm_panel_common_pdata mipi_truly_pdata = {
664 .pmic_backlight = mipi_truly_set_bl,
665};
666
667static struct platform_device mipi_dsi_truly_panel_device = {
668 .name = "mipi_truly",
669 .id = 0,
670 .dev = {
671 .platform_data = &mipi_truly_pdata,
672 }
673};
674
Jeevan Shrirame941df42012-01-23 12:40:21 +0530675static struct msm_panel_common_pdata mipi_NT35510_pdata = {
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +0530676 .pmic_backlight = evb_backlight_control,
Jeevan Shrirame941df42012-01-23 12:40:21 +0530677};
678
679static struct platform_device mipi_dsi_NT35510_panel_device = {
680 .name = "mipi_NT35510",
681 .id = 0,
682 .dev = {
683 .platform_data = &mipi_NT35510_pdata,
684 }
685};
686
Chintan Pandya250c2e52012-01-19 17:15:49 +0530687static struct platform_device *msm_fb_devices[] __initdata = {
688 &msm_fb_device,
689 &lcdc_toshiba_panel_device,
690#ifdef CONFIG_FB_MSM_MIPI_DSI
691 &mipi_dsi_renesas_panel_device,
692#endif
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800693#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
694 &msm_v4l2_video_overlay_device,
695#endif
Chintan Pandya250c2e52012-01-19 17:15:49 +0530696};
697
698static struct platform_device *qrd_fb_devices[] __initdata = {
699 &msm_fb_device,
700 &mipi_dsi_truly_panel_device,
701};
702
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530703static struct platform_device *qrd3_fb_devices[] __initdata = {
704 &msm_fb_device,
705 &lcdc_truly_panel_device,
706};
707
Taniya Dasc868a2e2012-01-03 10:18:47 +0530708static struct platform_device *evb_fb_devices[] __initdata = {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530709 &msm_fb_device,
710 &mipi_dsi_NT35510_panel_device,
Taniya Dasc868a2e2012-01-03 10:18:47 +0530711};
712
Chintan Pandya250c2e52012-01-19 17:15:49 +0530713void __init msm_msm7627a_allocate_memory_regions(void)
714{
715 void *addr;
716 unsigned long fb_size;
717
718 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
719 fb_size = MSM7x25A_MSM_FB_SIZE;
720 else
721 fb_size = MSM_FB_SIZE;
722 addr = alloc_bootmem_align(fb_size, 0x1000);
723 msm_fb_resources[0].start = __pa(addr);
724 msm_fb_resources[0].end = msm_fb_resources[0].start + fb_size - 1;
725 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n", fb_size,
726 addr, __pa(addr));
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800727
728#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
729 fb_size = MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE;
730 addr = alloc_bootmem_align(fb_size, 0x1000);
731 msm_v4l2_video_overlay_resources[0].start = __pa(addr);
732 msm_v4l2_video_overlay_resources[0].end =
733 msm_v4l2_video_overlay_resources[0].start + fb_size - 1;
734 pr_debug("allocating %lu bytes at %p (%lx physical) for v4l2\n",
735 fb_size, addr, __pa(addr));
736#endif
737
Chintan Pandya250c2e52012-01-19 17:15:49 +0530738}
739
740static struct msm_panel_common_pdata mdp_pdata = {
741 .gpio = 97,
742 .mdp_rev = MDP_REV_303,
743};
744
745#define GPIO_LCDC_BRDG_PD 128
746#define GPIO_LCDC_BRDG_RESET_N 129
747#define GPIO_LCD_DSI_SEL 125
748#define LCDC_RESET_PHYS 0x90008014
749
750static void __iomem *lcdc_reset_ptr;
751
752static unsigned mipi_dsi_gpio[] = {
753 GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
754 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
755 GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT,
756 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_PD */
757};
758
759static unsigned lcd_dsi_sel_gpio[] = {
760 GPIO_CFG(GPIO_LCD_DSI_SEL, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
761 GPIO_CFG_2MA),
762};
763
764enum {
765 DSI_SINGLE_LANE = 1,
766 DSI_TWO_LANES,
767};
768
769static int msm_fb_get_lane_config(void)
770{
771 /* For MSM7627A SURF/FFA and QRD */
772 int rc = DSI_TWO_LANES;
773 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
774 rc = DSI_SINGLE_LANE;
775 pr_info("DSI_SINGLE_LANES\n");
776 } else {
777 pr_info("DSI_TWO_LANES\n");
778 }
779 return rc;
780}
781
782static int msm_fb_dsi_client_msm_reset(void)
783{
784 int rc = 0;
785
786 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
787 if (rc < 0) {
788 pr_err("failed to request lcd brdg reset_n\n");
789 return rc;
790 }
791
792 rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
793 if (rc < 0) {
794 pr_err("failed to request lcd brdg pd\n");
795 return rc;
796 }
797
798 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
799 if (rc) {
800 pr_err("Failed to enable LCDC Bridge reset enable\n");
801 goto gpio_error;
802 }
803
804 rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
805 if (rc) {
806 pr_err("Failed to enable LCDC Bridge pd enable\n");
807 goto gpio_error2;
808 }
809
810 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
811 rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
812 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
813
814 if (!rc) {
Taniya Dase3027e22012-02-27 16:32:27 +0530815 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
816 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530817 lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
818 sizeof(uint32_t));
819
820 if (!lcdc_reset_ptr)
821 return 0;
822 }
823 return rc;
824 } else {
825 goto gpio_error;
826 }
827
828gpio_error2:
829 pr_err("Failed GPIO bridge pd\n");
830 gpio_free(GPIO_LCDC_BRDG_PD);
831
832gpio_error:
833 pr_err("Failed GPIO bridge reset\n");
834 gpio_free(GPIO_LCDC_BRDG_RESET_N);
835 return rc;
836}
837
838static int mipi_truly_sel_mode(int video_mode)
839{
840 int rc = 0;
841
842 rc = gpio_request(GPIO_LCD_DSI_SEL, "lcd_dsi_sel");
843 if (rc < 0)
844 goto gpio_error;
845
846 rc = gpio_tlmm_config(lcd_dsi_sel_gpio[0], GPIO_CFG_ENABLE);
847 if (rc)
848 goto gpio_error;
849
850 rc = gpio_direction_output(GPIO_LCD_DSI_SEL, 1);
851 if (!rc) {
852 gpio_set_value_cansleep(GPIO_LCD_DSI_SEL, video_mode);
853 return rc;
854 } else {
855 goto gpio_error;
856 }
857
858gpio_error:
859 pr_err("mipi_truly_sel_mode failed\n");
860 gpio_free(GPIO_LCD_DSI_SEL);
861 return rc;
862}
863
864static int msm_fb_dsi_client_qrd1_reset(void)
865{
866 int rc = 0;
867
868 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
869 if (rc < 0) {
870 pr_err("failed to request lcd brdg reset_n\n");
871 return rc;
872 }
873
874 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
875 if (rc < 0) {
876 pr_err("Failed to enable LCDC Bridge reset enable\n");
877 return rc;
878 }
879
880 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
881 if (rc < 0) {
882 pr_err("Failed GPIO bridge pd\n");
883 gpio_free(GPIO_LCDC_BRDG_RESET_N);
884 return rc;
885 }
886
887 mipi_truly_sel_mode(1);
888
889 return rc;
890}
891
Jeevan Shrirame941df42012-01-23 12:40:21 +0530892#define GPIO_QRD3_LCD_BRDG_RESET_N 85
893#define GPIO_QRD3_LCD_BACKLIGHT_EN 96
894#define GPIO_QRD3_LCD_EXT_2V85_EN 35
895#define GPIO_QRD3_LCD_EXT_1V8_EN 40
896
897static unsigned qrd3_mipi_dsi_gpio[] = {
898 GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
899 GPIO_CFG_NO_PULL,
900 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BRDG_RESET_N */
901 GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
902 GPIO_CFG_NO_PULL,
903 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BACKLIGHT_EN */
904 GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0, GPIO_CFG_OUTPUT,
905 GPIO_CFG_NO_PULL,
906 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_2V85_EN */
907 GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0, GPIO_CFG_OUTPUT,
908 GPIO_CFG_NO_PULL,
909 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_1V8_EN */
910};
911
912static int msm_fb_dsi_client_qrd3_reset(void)
913{
914 int rc = 0;
915
916 rc = gpio_request(GPIO_QRD3_LCD_BRDG_RESET_N, "qrd3_lcd_brdg_reset_n");
917 if (rc < 0) {
918 pr_err("failed to request qrd3 lcd brdg reset_n\n");
919 return rc;
920 }
921
Jeevan Shrirame941df42012-01-23 12:40:21 +0530922 return rc;
923}
924
Chintan Pandya250c2e52012-01-19 17:15:49 +0530925static int msm_fb_dsi_client_reset(void)
926{
927 int rc = 0;
928
929 if (machine_is_msm7627a_qrd1())
930 rc = msm_fb_dsi_client_qrd1_reset();
Chintan Pandyaf4ad4002012-02-28 19:49:03 +0530931 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
Jeevan Shrirame941df42012-01-23 12:40:21 +0530932 rc = msm_fb_dsi_client_qrd3_reset();
Chintan Pandya250c2e52012-01-19 17:15:49 +0530933 else
934 rc = msm_fb_dsi_client_msm_reset();
935
936 return rc;
937
938}
939
940static struct regulator_bulk_data regs_dsi[] = {
941 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
942 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
943};
944
945static int dsi_gpio_initialized;
946
947static int mipi_dsi_panel_msm_power(int on)
948{
949 int rc = 0;
950 uint32_t lcdc_reset_cfg;
951
952 /* I2C-controlled GPIO Expander -init of the GPIOs very late */
953 if (unlikely(!dsi_gpio_initialized)) {
954 pmapp_disp_backlight_init();
955
956 rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
957 if (rc < 0) {
958 pr_err("failed to request gpio_disp_pwr\n");
959 return rc;
960 }
961
Taniya Dase3027e22012-02-27 16:32:27 +0530962 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
963 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530964 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
965 if (rc < 0) {
966 pr_err("failed to enable display pwr\n");
967 goto fail_gpio1;
968 }
969
970 rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
971 if (rc < 0) {
972 pr_err("failed to request gpio_bkl_en\n");
973 goto fail_gpio1;
974 }
975
976 rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
977 if (rc < 0) {
978 pr_err("failed to enable backlight\n");
979 goto fail_gpio2;
980 }
981 }
982
983 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
984 if (rc) {
985 pr_err("%s: could not get regulators: %d\n",
986 __func__, rc);
987 goto fail_gpio2;
988 }
989
990 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi),
991 regs_dsi);
992 if (rc) {
993 pr_err("%s: could not set voltages: %d\n",
994 __func__, rc);
995 goto fail_vreg;
996 }
997 if (pmapp_disp_backlight_set_brightness(100))
998 pr_err("backlight set brightness failed\n");
999
1000 dsi_gpio_initialized = 1;
1001 }
Taniya Dase3027e22012-02-27 16:32:27 +05301002 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
1003 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301004 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
1005 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
1006 } else if (machine_is_msm7x27a_ffa() ||
1007 machine_is_msm7625a_ffa()) {
1008 if (on) {
1009 /* This line drives an active low pin on FFA */
1010 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
1011 if (rc < 0)
1012 pr_err("failed to set direction for "
1013 "display pwr\n");
1014 } else {
1015 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
1016 rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
1017 if (rc < 0)
1018 pr_err("failed to set direction for "
1019 "display pwr\n");
1020 }
1021 }
1022
1023 if (on) {
1024 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
1025
1026 if (machine_is_msm7x27a_surf() ||
Taniya Dase3027e22012-02-27 16:32:27 +05301027 machine_is_msm7625a_surf() ||
1028 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301029 lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
1030 rmb();
1031 lcdc_reset_cfg &= ~1;
1032
1033 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
1034 msleep(20);
1035 wmb();
1036 lcdc_reset_cfg |= 1;
1037 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
1038 } else {
1039 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
1040 msleep(20);
1041 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1042 }
1043 } else {
1044 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301045 }
1046
1047 rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
1048 regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
1049
1050 if (rc)
1051 pr_err("%s: could not %sable regulators: %d\n",
1052 __func__, on ? "en" : "dis", rc);
1053
1054 return rc;
1055fail_vreg:
1056 regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
1057fail_gpio2:
1058 gpio_free(GPIO_BACKLIGHT_EN);
1059fail_gpio1:
1060 gpio_free(GPIO_DISPLAY_PWR_EN);
1061 dsi_gpio_initialized = 0;
1062 return rc;
1063}
1064
1065static int mipi_dsi_panel_qrd1_power(int on)
1066{
1067 int rc = 0;
1068
1069 if (!dsi_gpio_initialized) {
1070 rc = gpio_request(QRD_GPIO_BACKLIGHT_EN, "gpio_bkl_en");
1071 if (rc < 0)
1072 return rc;
1073
1074 rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_BACKLIGHT_EN, 0,
1075 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1076 GPIO_CFG_ENABLE);
1077 if (rc < 0) {
1078 pr_err("failed GPIO_BACKLIGHT_EN tlmm config\n");
1079 return rc;
1080 }
1081
1082 rc = gpio_direction_output(QRD_GPIO_BACKLIGHT_EN, 1);
1083 if (rc < 0) {
1084 pr_err("failed to enable backlight\n");
1085 gpio_free(QRD_GPIO_BACKLIGHT_EN);
1086 return rc;
1087 }
1088 dsi_gpio_initialized = 1;
1089 }
1090
1091 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
1092
Jeevan Shrirame941df42012-01-23 12:40:21 +05301093 if (on) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301094 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1095 msleep(20);
1096 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
1097 msleep(20);
1098 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1099
1100 }
1101
1102 return rc;
1103}
1104
Jeevan Shrirame941df42012-01-23 12:40:21 +05301105static int qrd3_dsi_gpio_initialized;
1106
1107static int mipi_dsi_panel_qrd3_power(int on)
1108{
1109 int rc = 0;
1110
1111 if (!qrd3_dsi_gpio_initialized) {
1112 rc = gpio_request(GPIO_QRD3_LCD_BACKLIGHT_EN,
1113 "qrd3_gpio_bkl_en");
1114 if (rc < 0)
1115 return rc;
1116
1117 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301118 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
Jeevan Shrirame941df42012-01-23 12:40:21 +05301119 GPIO_CFG_ENABLE);
1120 if (rc < 0) {
1121 pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
1122 return rc;
1123 }
1124 rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1125 if (rc < 0) {
1126 pr_err("failed to enable backlight\n");
1127 gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
1128 return rc;
1129 }
1130
1131 rc = gpio_request(GPIO_QRD3_LCD_EXT_2V85_EN,
1132 "qrd3_gpio_ext_2v85_en");
1133 if (rc < 0)
1134 return rc;
1135
1136 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0,
1137 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1138 GPIO_CFG_ENABLE);
1139 if (rc < 0) {
1140 pr_err("failed QRD3 GPIO_QRD3_LCD_EXT_2V85_EN tlmm config\n");
1141 return rc;
1142 }
1143
1144 rc = gpio_direction_output(GPIO_QRD3_LCD_EXT_2V85_EN, 1);
1145 if (rc < 0) {
1146 pr_err("failed to enable external 2V85\n");
1147 gpio_free(GPIO_QRD3_LCD_EXT_2V85_EN);
1148 return rc;
1149 }
1150
1151 rc = gpio_request(GPIO_QRD3_LCD_EXT_1V8_EN,
1152 "qrd3_gpio_ext_1v8_en");
1153 if (rc < 0)
1154 return rc;
1155
1156 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0,
1157 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1158 GPIO_CFG_ENABLE);
1159 if (rc < 0) {
1160 pr_err("failed QRD3 GPIO_QRD3_LCD_EXT_1V8_EN tlmm config\n");
1161 return rc;
1162 }
1163
1164 rc = gpio_direction_output(GPIO_QRD3_LCD_EXT_1V8_EN, 1);
1165 if (rc < 0) {
1166 pr_err("failed to enable external 1v8\n");
1167 gpio_free(GPIO_QRD3_LCD_EXT_1V8_EN);
1168 return rc;
1169 }
1170
1171 qrd3_dsi_gpio_initialized = 1;
1172 }
1173
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301174 if (on) {
1175 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1176 udelay(190);
1177 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 0);
1178 udelay(286);
1179 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1180 /* 1 wire mode starts from this low to high transition */
1181 udelay(50);
1182 } else
1183 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, !!on);
1184
Jeevan Shrirame941df42012-01-23 12:40:21 +05301185 gpio_set_value_cansleep(GPIO_QRD3_LCD_EXT_2V85_EN, !!on);
1186 gpio_set_value_cansleep(GPIO_QRD3_LCD_EXT_1V8_EN, !!on);
1187
1188 if (on) {
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301189 rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
1190
1191 if (rc < 0) {
1192 pr_err("Failed to enable LCD Bridge reset enable\n");
1193 return rc;
1194 }
1195
1196 rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
1197
1198 if (rc < 0) {
1199 pr_err("Failed GPIO bridge Reset\n");
1200 gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
1201 return rc;
1202 }
1203
Jeevan Shrirame941df42012-01-23 12:40:21 +05301204 msleep(20);
1205 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 0);
1206 msleep(20);
1207 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
1208 msleep(20);
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301209 } else {
1210 gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0,
1211 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1212 GPIO_CFG_DISABLE);
Jeevan Shrirame941df42012-01-23 12:40:21 +05301213 }
1214
1215 return rc;
1216}
1217
Chintan Pandya250c2e52012-01-19 17:15:49 +05301218static int mipi_dsi_panel_power(int on)
1219{
1220 int rc = 0;
1221
1222 if (machine_is_msm7627a_qrd1())
1223 rc = mipi_dsi_panel_qrd1_power(on);
Chintan Pandyaf4ad4002012-02-28 19:49:03 +05301224 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
Jeevan Shrirame941df42012-01-23 12:40:21 +05301225 rc = mipi_dsi_panel_qrd3_power(on);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301226 else
1227 rc = mipi_dsi_panel_msm_power(on);
1228 return rc;
1229}
1230
1231#define MDP_303_VSYNC_GPIO 97
1232
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301233#ifdef CONFIG_FB_MSM_MIPI_DSI
Chintan Pandya250c2e52012-01-19 17:15:49 +05301234static struct mipi_dsi_platform_data mipi_dsi_pdata = {
1235 .vsync_gpio = MDP_303_VSYNC_GPIO,
1236 .dsi_power_save = mipi_dsi_panel_power,
1237 .dsi_client_reset = msm_fb_dsi_client_reset,
1238 .get_lane_config = msm_fb_get_lane_config,
1239};
1240#endif
1241
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301242static char prim_panel_name[PANEL_NAME_MAX_LEN];
1243static int __init prim_display_setup(char *param)
1244{
1245 if (strnlen(param, PANEL_NAME_MAX_LEN))
1246 strlcpy(prim_panel_name, param, PANEL_NAME_MAX_LEN);
1247 return 0;
1248}
1249early_param("prim_display", prim_display_setup);
1250
1251void msm7x27a_set_display_params(char *prim_panel)
1252{
1253 if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
1254 strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
1255 PANEL_NAME_MAX_LEN);
1256 pr_debug("msm_fb_pdata.prim_panel_name %s\n",
1257 msm_fb_pdata.prim_panel_name);
1258 }
1259}
1260
Chintan Pandya250c2e52012-01-19 17:15:49 +05301261void __init msm_fb_add_devices(void)
1262{
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301263 msm7x27a_set_display_params(prim_panel_name);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301264 if (machine_is_msm7627a_qrd1())
1265 platform_add_devices(qrd_fb_devices,
1266 ARRAY_SIZE(qrd_fb_devices));
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301267 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
1268 mipi_NT35510_pdata.bl_lock = 1;
Taniya Dasc868a2e2012-01-03 10:18:47 +05301269 platform_add_devices(evb_fb_devices,
1270 ARRAY_SIZE(evb_fb_devices));
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301271 } else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301272 sku3_lcdc_lcd_camera_power_init();
1273 platform_add_devices(qrd3_fb_devices,
1274 ARRAY_SIZE(qrd3_fb_devices));
1275 } else
Chintan Pandya250c2e52012-01-19 17:15:49 +05301276 platform_add_devices(msm_fb_devices,
1277 ARRAY_SIZE(msm_fb_devices));
1278
1279 msm_fb_register_device("mdp", &mdp_pdata);
Taniya Dase3027e22012-02-27 16:32:27 +05301280 if (machine_is_msm7625a_surf() || machine_is_msm7x27a_surf() ||
Jeevan Shriram045cdc72012-03-27 07:04:15 +05301281 machine_is_msm8625_surf() || machine_is_msm7627a_qrd3()
1282 || machine_is_msm8625_qrd7())
Chintan Pandya250c2e52012-01-19 17:15:49 +05301283 msm_fb_register_device("lcdc", &lcdc_pdata);
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301284#ifdef CONFIG_FB_MSM_MIPI_DSI
Chintan Pandya250c2e52012-01-19 17:15:49 +05301285 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
1286#endif
1287}