blob: e2076f8d6d1e855d0141e6ed1e66f3af6ba30ff8 [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
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +053031#define MSM_FB_SIZE 0x2FD000
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
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530687static struct msm_panel_common_pdata mipi_NT35516_pdata = {
688 .pmic_backlight = NULL,
689};
690
691static struct platform_device mipi_dsi_NT35516_panel_device = {
692 .name = "mipi_truly_tft540960_1_e",
693 .id = 0,
694 .dev = {
695 .platform_data = &mipi_NT35516_pdata,
696 }
697};
698
Chintan Pandya250c2e52012-01-19 17:15:49 +0530699static struct platform_device *msm_fb_devices[] __initdata = {
700 &msm_fb_device,
701 &lcdc_toshiba_panel_device,
702#ifdef CONFIG_FB_MSM_MIPI_DSI
703 &mipi_dsi_renesas_panel_device,
704#endif
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800705#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
706 &msm_v4l2_video_overlay_device,
707#endif
Chintan Pandya250c2e52012-01-19 17:15:49 +0530708};
709
710static struct platform_device *qrd_fb_devices[] __initdata = {
711 &msm_fb_device,
712 &mipi_dsi_truly_panel_device,
713};
714
Jeevan Shriram901a15f2012-03-09 11:53:23 +0530715static struct platform_device *qrd3_fb_devices[] __initdata = {
716 &msm_fb_device,
717 &lcdc_truly_panel_device,
718};
719
Taniya Dasc868a2e2012-01-03 10:18:47 +0530720static struct platform_device *evb_fb_devices[] __initdata = {
Jeevan Shrirame941df42012-01-23 12:40:21 +0530721 &msm_fb_device,
722 &mipi_dsi_NT35510_panel_device,
Pradeep Jilagam1b0a5df2012-02-23 08:00:24 +0530723 &mipi_dsi_NT35516_panel_device,
Taniya Dasc868a2e2012-01-03 10:18:47 +0530724};
725
Chintan Pandya250c2e52012-01-19 17:15:49 +0530726void __init msm_msm7627a_allocate_memory_regions(void)
727{
728 void *addr;
729 unsigned long fb_size;
730
731 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
732 fb_size = MSM7x25A_MSM_FB_SIZE;
733 else
734 fb_size = MSM_FB_SIZE;
735 addr = alloc_bootmem_align(fb_size, 0x1000);
736 msm_fb_resources[0].start = __pa(addr);
737 msm_fb_resources[0].end = msm_fb_resources[0].start + fb_size - 1;
738 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n", fb_size,
739 addr, __pa(addr));
Alhad Purnapatrec55856c2012-02-28 13:24:57 -0800740
741#ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE
742 fb_size = MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE;
743 addr = alloc_bootmem_align(fb_size, 0x1000);
744 msm_v4l2_video_overlay_resources[0].start = __pa(addr);
745 msm_v4l2_video_overlay_resources[0].end =
746 msm_v4l2_video_overlay_resources[0].start + fb_size - 1;
747 pr_debug("allocating %lu bytes at %p (%lx physical) for v4l2\n",
748 fb_size, addr, __pa(addr));
749#endif
750
Chintan Pandya250c2e52012-01-19 17:15:49 +0530751}
752
753static struct msm_panel_common_pdata mdp_pdata = {
754 .gpio = 97,
755 .mdp_rev = MDP_REV_303,
756};
757
758#define GPIO_LCDC_BRDG_PD 128
759#define GPIO_LCDC_BRDG_RESET_N 129
760#define GPIO_LCD_DSI_SEL 125
761#define LCDC_RESET_PHYS 0x90008014
762
763static void __iomem *lcdc_reset_ptr;
764
765static unsigned mipi_dsi_gpio[] = {
766 GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
767 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
768 GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT,
769 GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* LCDC_BRDG_PD */
770};
771
772static unsigned lcd_dsi_sel_gpio[] = {
773 GPIO_CFG(GPIO_LCD_DSI_SEL, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
774 GPIO_CFG_2MA),
775};
776
777enum {
778 DSI_SINGLE_LANE = 1,
779 DSI_TWO_LANES,
780};
781
782static int msm_fb_get_lane_config(void)
783{
784 /* For MSM7627A SURF/FFA and QRD */
785 int rc = DSI_TWO_LANES;
786 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
787 rc = DSI_SINGLE_LANE;
788 pr_info("DSI_SINGLE_LANES\n");
789 } else {
790 pr_info("DSI_TWO_LANES\n");
791 }
792 return rc;
793}
794
795static int msm_fb_dsi_client_msm_reset(void)
796{
797 int rc = 0;
798
799 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
800 if (rc < 0) {
801 pr_err("failed to request lcd brdg reset_n\n");
802 return rc;
803 }
804
805 rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
806 if (rc < 0) {
807 pr_err("failed to request lcd brdg pd\n");
808 return rc;
809 }
810
811 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
812 if (rc) {
813 pr_err("Failed to enable LCDC Bridge reset enable\n");
814 goto gpio_error;
815 }
816
817 rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
818 if (rc) {
819 pr_err("Failed to enable LCDC Bridge pd enable\n");
820 goto gpio_error2;
821 }
822
823 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
824 rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
825 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
826
827 if (!rc) {
Taniya Dase3027e22012-02-27 16:32:27 +0530828 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
829 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530830 lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
831 sizeof(uint32_t));
832
833 if (!lcdc_reset_ptr)
834 return 0;
835 }
836 return rc;
837 } else {
838 goto gpio_error;
839 }
840
841gpio_error2:
842 pr_err("Failed GPIO bridge pd\n");
843 gpio_free(GPIO_LCDC_BRDG_PD);
844
845gpio_error:
846 pr_err("Failed GPIO bridge reset\n");
847 gpio_free(GPIO_LCDC_BRDG_RESET_N);
848 return rc;
849}
850
851static int mipi_truly_sel_mode(int video_mode)
852{
853 int rc = 0;
854
855 rc = gpio_request(GPIO_LCD_DSI_SEL, "lcd_dsi_sel");
856 if (rc < 0)
857 goto gpio_error;
858
859 rc = gpio_tlmm_config(lcd_dsi_sel_gpio[0], GPIO_CFG_ENABLE);
860 if (rc)
861 goto gpio_error;
862
863 rc = gpio_direction_output(GPIO_LCD_DSI_SEL, 1);
864 if (!rc) {
865 gpio_set_value_cansleep(GPIO_LCD_DSI_SEL, video_mode);
866 return rc;
867 } else {
868 goto gpio_error;
869 }
870
871gpio_error:
872 pr_err("mipi_truly_sel_mode failed\n");
873 gpio_free(GPIO_LCD_DSI_SEL);
874 return rc;
875}
876
877static int msm_fb_dsi_client_qrd1_reset(void)
878{
879 int rc = 0;
880
881 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
882 if (rc < 0) {
883 pr_err("failed to request lcd brdg reset_n\n");
884 return rc;
885 }
886
887 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
888 if (rc < 0) {
889 pr_err("Failed to enable LCDC Bridge reset enable\n");
890 return rc;
891 }
892
893 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
894 if (rc < 0) {
895 pr_err("Failed GPIO bridge pd\n");
896 gpio_free(GPIO_LCDC_BRDG_RESET_N);
897 return rc;
898 }
899
900 mipi_truly_sel_mode(1);
901
902 return rc;
903}
904
Jeevan Shrirame941df42012-01-23 12:40:21 +0530905#define GPIO_QRD3_LCD_BRDG_RESET_N 85
906#define GPIO_QRD3_LCD_BACKLIGHT_EN 96
907#define GPIO_QRD3_LCD_EXT_2V85_EN 35
908#define GPIO_QRD3_LCD_EXT_1V8_EN 40
909
910static unsigned qrd3_mipi_dsi_gpio[] = {
911 GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
912 GPIO_CFG_NO_PULL,
913 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BRDG_RESET_N */
914 GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
915 GPIO_CFG_NO_PULL,
916 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BACKLIGHT_EN */
917 GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0, GPIO_CFG_OUTPUT,
918 GPIO_CFG_NO_PULL,
919 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_2V85_EN */
920 GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0, GPIO_CFG_OUTPUT,
921 GPIO_CFG_NO_PULL,
922 GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_1V8_EN */
923};
924
925static int msm_fb_dsi_client_qrd3_reset(void)
926{
927 int rc = 0;
928
929 rc = gpio_request(GPIO_QRD3_LCD_BRDG_RESET_N, "qrd3_lcd_brdg_reset_n");
930 if (rc < 0) {
931 pr_err("failed to request qrd3 lcd brdg reset_n\n");
932 return rc;
933 }
934
Jeevan Shrirame941df42012-01-23 12:40:21 +0530935 return rc;
936}
937
Chintan Pandya250c2e52012-01-19 17:15:49 +0530938static int msm_fb_dsi_client_reset(void)
939{
940 int rc = 0;
941
942 if (machine_is_msm7627a_qrd1())
943 rc = msm_fb_dsi_client_qrd1_reset();
Chintan Pandyaf4ad4002012-02-28 19:49:03 +0530944 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
Jeevan Shrirame941df42012-01-23 12:40:21 +0530945 rc = msm_fb_dsi_client_qrd3_reset();
Chintan Pandya250c2e52012-01-19 17:15:49 +0530946 else
947 rc = msm_fb_dsi_client_msm_reset();
948
949 return rc;
950
951}
952
953static struct regulator_bulk_data regs_dsi[] = {
954 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
955 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
956};
957
958static int dsi_gpio_initialized;
959
960static int mipi_dsi_panel_msm_power(int on)
961{
962 int rc = 0;
963 uint32_t lcdc_reset_cfg;
964
965 /* I2C-controlled GPIO Expander -init of the GPIOs very late */
966 if (unlikely(!dsi_gpio_initialized)) {
967 pmapp_disp_backlight_init();
968
969 rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
970 if (rc < 0) {
971 pr_err("failed to request gpio_disp_pwr\n");
972 return rc;
973 }
974
Taniya Dase3027e22012-02-27 16:32:27 +0530975 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()
976 || machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +0530977 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
978 if (rc < 0) {
979 pr_err("failed to enable display pwr\n");
980 goto fail_gpio1;
981 }
982
983 rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
984 if (rc < 0) {
985 pr_err("failed to request gpio_bkl_en\n");
986 goto fail_gpio1;
987 }
988
989 rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
990 if (rc < 0) {
991 pr_err("failed to enable backlight\n");
992 goto fail_gpio2;
993 }
994 }
995
996 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
997 if (rc) {
998 pr_err("%s: could not get regulators: %d\n",
999 __func__, rc);
1000 goto fail_gpio2;
1001 }
1002
1003 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi),
1004 regs_dsi);
1005 if (rc) {
1006 pr_err("%s: could not set voltages: %d\n",
1007 __func__, rc);
1008 goto fail_vreg;
1009 }
1010 if (pmapp_disp_backlight_set_brightness(100))
1011 pr_err("backlight set brightness failed\n");
1012
1013 dsi_gpio_initialized = 1;
1014 }
Taniya Dase3027e22012-02-27 16:32:27 +05301015 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
1016 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301017 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
1018 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
1019 } else if (machine_is_msm7x27a_ffa() ||
1020 machine_is_msm7625a_ffa()) {
1021 if (on) {
1022 /* This line drives an active low pin on FFA */
1023 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
1024 if (rc < 0)
1025 pr_err("failed to set direction for "
1026 "display pwr\n");
1027 } else {
1028 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
1029 rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
1030 if (rc < 0)
1031 pr_err("failed to set direction for "
1032 "display pwr\n");
1033 }
1034 }
1035
1036 if (on) {
1037 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
1038
1039 if (machine_is_msm7x27a_surf() ||
Taniya Dase3027e22012-02-27 16:32:27 +05301040 machine_is_msm7625a_surf() ||
1041 machine_is_msm8625_surf()) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301042 lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
1043 rmb();
1044 lcdc_reset_cfg &= ~1;
1045
1046 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
1047 msleep(20);
1048 wmb();
1049 lcdc_reset_cfg |= 1;
1050 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
1051 } else {
1052 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
1053 msleep(20);
1054 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1055 }
1056 } else {
1057 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301058 }
1059
1060 rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
1061 regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
1062
1063 if (rc)
1064 pr_err("%s: could not %sable regulators: %d\n",
1065 __func__, on ? "en" : "dis", rc);
1066
1067 return rc;
1068fail_vreg:
1069 regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
1070fail_gpio2:
1071 gpio_free(GPIO_BACKLIGHT_EN);
1072fail_gpio1:
1073 gpio_free(GPIO_DISPLAY_PWR_EN);
1074 dsi_gpio_initialized = 0;
1075 return rc;
1076}
1077
1078static int mipi_dsi_panel_qrd1_power(int on)
1079{
1080 int rc = 0;
1081
1082 if (!dsi_gpio_initialized) {
1083 rc = gpio_request(QRD_GPIO_BACKLIGHT_EN, "gpio_bkl_en");
1084 if (rc < 0)
1085 return rc;
1086
1087 rc = gpio_tlmm_config(GPIO_CFG(QRD_GPIO_BACKLIGHT_EN, 0,
1088 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1089 GPIO_CFG_ENABLE);
1090 if (rc < 0) {
1091 pr_err("failed GPIO_BACKLIGHT_EN tlmm config\n");
1092 return rc;
1093 }
1094
1095 rc = gpio_direction_output(QRD_GPIO_BACKLIGHT_EN, 1);
1096 if (rc < 0) {
1097 pr_err("failed to enable backlight\n");
1098 gpio_free(QRD_GPIO_BACKLIGHT_EN);
1099 return rc;
1100 }
1101 dsi_gpio_initialized = 1;
1102 }
1103
1104 gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
1105
Jeevan Shrirame941df42012-01-23 12:40:21 +05301106 if (on) {
Chintan Pandya250c2e52012-01-19 17:15:49 +05301107 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1108 msleep(20);
1109 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
1110 msleep(20);
1111 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
1112
1113 }
1114
1115 return rc;
1116}
1117
Jeevan Shrirame941df42012-01-23 12:40:21 +05301118static int qrd3_dsi_gpio_initialized;
1119
1120static int mipi_dsi_panel_qrd3_power(int on)
1121{
1122 int rc = 0;
1123
1124 if (!qrd3_dsi_gpio_initialized) {
1125 rc = gpio_request(GPIO_QRD3_LCD_BACKLIGHT_EN,
1126 "qrd3_gpio_bkl_en");
1127 if (rc < 0)
1128 return rc;
1129
1130 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301131 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
Jeevan Shrirame941df42012-01-23 12:40:21 +05301132 GPIO_CFG_ENABLE);
1133 if (rc < 0) {
1134 pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
1135 return rc;
1136 }
1137 rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1138 if (rc < 0) {
1139 pr_err("failed to enable backlight\n");
1140 gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
1141 return rc;
1142 }
1143
1144 rc = gpio_request(GPIO_QRD3_LCD_EXT_2V85_EN,
1145 "qrd3_gpio_ext_2v85_en");
1146 if (rc < 0)
1147 return rc;
1148
1149 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0,
1150 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1151 GPIO_CFG_ENABLE);
1152 if (rc < 0) {
1153 pr_err("failed QRD3 GPIO_QRD3_LCD_EXT_2V85_EN tlmm config\n");
1154 return rc;
1155 }
1156
1157 rc = gpio_direction_output(GPIO_QRD3_LCD_EXT_2V85_EN, 1);
1158 if (rc < 0) {
1159 pr_err("failed to enable external 2V85\n");
1160 gpio_free(GPIO_QRD3_LCD_EXT_2V85_EN);
1161 return rc;
1162 }
1163
1164 rc = gpio_request(GPIO_QRD3_LCD_EXT_1V8_EN,
1165 "qrd3_gpio_ext_1v8_en");
1166 if (rc < 0)
1167 return rc;
1168
1169 rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0,
1170 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1171 GPIO_CFG_ENABLE);
1172 if (rc < 0) {
1173 pr_err("failed QRD3 GPIO_QRD3_LCD_EXT_1V8_EN tlmm config\n");
1174 return rc;
1175 }
1176
1177 rc = gpio_direction_output(GPIO_QRD3_LCD_EXT_1V8_EN, 1);
1178 if (rc < 0) {
1179 pr_err("failed to enable external 1v8\n");
1180 gpio_free(GPIO_QRD3_LCD_EXT_1V8_EN);
1181 return rc;
1182 }
1183
1184 qrd3_dsi_gpio_initialized = 1;
1185 }
1186
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301187 if (on) {
1188 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1189 udelay(190);
1190 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 0);
1191 udelay(286);
1192 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
1193 /* 1 wire mode starts from this low to high transition */
1194 udelay(50);
1195 } else
1196 gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, !!on);
1197
Jeevan Shrirame941df42012-01-23 12:40:21 +05301198 gpio_set_value_cansleep(GPIO_QRD3_LCD_EXT_2V85_EN, !!on);
1199 gpio_set_value_cansleep(GPIO_QRD3_LCD_EXT_1V8_EN, !!on);
1200
1201 if (on) {
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301202 rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
1203
1204 if (rc < 0) {
1205 pr_err("Failed to enable LCD Bridge reset enable\n");
1206 return rc;
1207 }
1208
1209 rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
1210
1211 if (rc < 0) {
1212 pr_err("Failed GPIO bridge Reset\n");
1213 gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
1214 return rc;
1215 }
1216
Jeevan Shrirame941df42012-01-23 12:40:21 +05301217 msleep(20);
1218 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 0);
1219 msleep(20);
1220 gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
1221 msleep(20);
Padmanabhan Komanduru599d3552012-02-21 16:53:05 +05301222 } else {
1223 gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0,
1224 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1225 GPIO_CFG_DISABLE);
Jeevan Shrirame941df42012-01-23 12:40:21 +05301226 }
1227
1228 return rc;
1229}
1230
Chintan Pandya250c2e52012-01-19 17:15:49 +05301231static int mipi_dsi_panel_power(int on)
1232{
1233 int rc = 0;
1234
1235 if (machine_is_msm7627a_qrd1())
1236 rc = mipi_dsi_panel_qrd1_power(on);
Chintan Pandyaf4ad4002012-02-28 19:49:03 +05301237 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
Jeevan Shrirame941df42012-01-23 12:40:21 +05301238 rc = mipi_dsi_panel_qrd3_power(on);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301239 else
1240 rc = mipi_dsi_panel_msm_power(on);
1241 return rc;
1242}
1243
1244#define MDP_303_VSYNC_GPIO 97
1245
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301246#ifdef CONFIG_FB_MSM_MIPI_DSI
Chintan Pandya250c2e52012-01-19 17:15:49 +05301247static struct mipi_dsi_platform_data mipi_dsi_pdata = {
1248 .vsync_gpio = MDP_303_VSYNC_GPIO,
1249 .dsi_power_save = mipi_dsi_panel_power,
1250 .dsi_client_reset = msm_fb_dsi_client_reset,
1251 .get_lane_config = msm_fb_get_lane_config,
1252};
1253#endif
1254
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301255static char prim_panel_name[PANEL_NAME_MAX_LEN];
1256static int __init prim_display_setup(char *param)
1257{
1258 if (strnlen(param, PANEL_NAME_MAX_LEN))
1259 strlcpy(prim_panel_name, param, PANEL_NAME_MAX_LEN);
1260 return 0;
1261}
1262early_param("prim_display", prim_display_setup);
1263
1264void msm7x27a_set_display_params(char *prim_panel)
1265{
1266 if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
1267 strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
1268 PANEL_NAME_MAX_LEN);
1269 pr_debug("msm_fb_pdata.prim_panel_name %s\n",
1270 msm_fb_pdata.prim_panel_name);
1271 }
1272}
1273
Chintan Pandya250c2e52012-01-19 17:15:49 +05301274void __init msm_fb_add_devices(void)
1275{
Padmanabhan Komanduru92f9a722012-04-04 19:28:02 +05301276 msm7x27a_set_display_params(prim_panel_name);
Chintan Pandya250c2e52012-01-19 17:15:49 +05301277 if (machine_is_msm7627a_qrd1())
1278 platform_add_devices(qrd_fb_devices,
1279 ARRAY_SIZE(qrd_fb_devices));
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301280 else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
1281 mipi_NT35510_pdata.bl_lock = 1;
Taniya Dasc868a2e2012-01-03 10:18:47 +05301282 platform_add_devices(evb_fb_devices,
1283 ARRAY_SIZE(evb_fb_devices));
Padmanabhan Komandurubea9c062012-04-09 10:33:48 +05301284 } else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301285 sku3_lcdc_lcd_camera_power_init();
1286 platform_add_devices(qrd3_fb_devices,
1287 ARRAY_SIZE(qrd3_fb_devices));
1288 } else
Chintan Pandya250c2e52012-01-19 17:15:49 +05301289 platform_add_devices(msm_fb_devices,
1290 ARRAY_SIZE(msm_fb_devices));
1291
1292 msm_fb_register_device("mdp", &mdp_pdata);
Taniya Dase3027e22012-02-27 16:32:27 +05301293 if (machine_is_msm7625a_surf() || machine_is_msm7x27a_surf() ||
Jeevan Shriram045cdc72012-03-27 07:04:15 +05301294 machine_is_msm8625_surf() || machine_is_msm7627a_qrd3()
1295 || machine_is_msm8625_qrd7())
Chintan Pandya250c2e52012-01-19 17:15:49 +05301296 msm_fb_register_device("lcdc", &lcdc_pdata);
Jeevan Shriram901a15f2012-03-09 11:53:23 +05301297#ifdef CONFIG_FB_MSM_MIPI_DSI
Chintan Pandya250c2e52012-01-19 17:15:49 +05301298 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
1299#endif
1300}