1 /* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
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.
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.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 #include <linux/delay.h>
19 #include <mach/gpio.h>
23 #define GORDON_REG_NOP 0x00
24 #define GORDON_REG_IMGCTL1 0x10
25 #define GORDON_REG_IMGCTL2 0x11
26 #define GORDON_REG_IMGSET1 0x12
27 #define GORDON_REG_IMGSET2 0x13
28 #define GORDON_REG_IVBP1 0x14
29 #define GORDON_REG_IHBP1 0x15
30 #define GORDON_REG_IVNUM1 0x16
31 #define GORDON_REG_IHNUM1 0x17
32 #define GORDON_REG_IVBP2 0x18
33 #define GORDON_REG_IHBP2 0x19
34 #define GORDON_REG_IVNUM2 0x1A
35 #define GORDON_REG_IHNUM2 0x1B
36 #define GORDON_REG_LCDIFCTL1 0x30
37 #define GORDON_REG_VALTRAN 0x31
38 #define GORDON_REG_AVCTL 0x33
39 #define GORDON_REG_LCDIFCTL2 0x34
40 #define GORDON_REG_LCDIFCTL3 0x35
41 #define GORDON_REG_LCDIFSET1 0x36
42 #define GORDON_REG_PCCTL 0x3C
43 #define GORDON_REG_TPARAM1 0x40
44 #define GORDON_REG_TLCDIF1 0x41
45 #define GORDON_REG_TSSPB_ST1 0x42
46 #define GORDON_REG_TSSPB_ED1 0x43
47 #define GORDON_REG_TSCK_ST1 0x44
48 #define GORDON_REG_TSCK_WD1 0x45
49 #define GORDON_REG_TGSPB_VST1 0x46
50 #define GORDON_REG_TGSPB_VED1 0x47
51 #define GORDON_REG_TGSPB_CH1 0x48
52 #define GORDON_REG_TGCK_ST1 0x49
53 #define GORDON_REG_TGCK_ED1 0x4A
54 #define GORDON_REG_TPCTL_ST1 0x4B
55 #define GORDON_REG_TPCTL_ED1 0x4C
56 #define GORDON_REG_TPCHG_ED1 0x4D
57 #define GORDON_REG_TCOM_CH1 0x4E
58 #define GORDON_REG_THBP1 0x4F
59 #define GORDON_REG_TPHCTL1 0x50
60 #define GORDON_REG_EVPH1 0x51
61 #define GORDON_REG_EVPL1 0x52
62 #define GORDON_REG_EVNH1 0x53
63 #define GORDON_REG_EVNL1 0x54
64 #define GORDON_REG_TBIAS1 0x55
65 #define GORDON_REG_TPARAM2 0x56
66 #define GORDON_REG_TLCDIF2 0x57
67 #define GORDON_REG_TSSPB_ST2 0x58
68 #define GORDON_REG_TSSPB_ED2 0x59
69 #define GORDON_REG_TSCK_ST2 0x5A
70 #define GORDON_REG_TSCK_WD2 0x5B
71 #define GORDON_REG_TGSPB_VST2 0x5C
72 #define GORDON_REG_TGSPB_VED2 0x5D
73 #define GORDON_REG_TGSPB_CH2 0x5E
74 #define GORDON_REG_TGCK_ST2 0x5F
75 #define GORDON_REG_TGCK_ED2 0x60
76 #define GORDON_REG_TPCTL_ST2 0x61
77 #define GORDON_REG_TPCTL_ED2 0x62
78 #define GORDON_REG_TPCHG_ED2 0x63
79 #define GORDON_REG_TCOM_CH2 0x64
80 #define GORDON_REG_THBP2 0x65
81 #define GORDON_REG_TPHCTL2 0x66
82 #define GORDON_REG_POWCTL 0x80
84 static int lcdc_gordon_panel_off(struct platform_device
*pdev
);
91 static unsigned char bit_shift
[8] = { (1 << 7), /* MSB */
101 struct gordon_state_type
{
102 boolean disp_initialized
;
104 boolean disp_powered_up
;
107 static struct gordon_state_type gordon_state
= { 0 };
108 static struct msm_panel_common_pdata
*lcdc_gordon_pdata
;
110 static void serigo(uint16 reg
, uint8 data
)
112 unsigned int tx_val
= ((0x00FF & reg
) << 8) | data
;
113 unsigned char i
, val
= 0;
115 /* Enable the Chip Select */
116 gpio_set_value(spi_cs
, 1);
119 /* Transmit it in two parts, Higher Byte first, then Lower Byte */
120 val
= (unsigned char)((tx_val
& 0xFF00) >> 8);
122 /* Clock should be Low before entering ! */
123 for (i
= 0; i
< 8; i
++) {
124 /* #1: Drive the Data (High or Low) */
125 if (val
& bit_shift
[i
])
126 gpio_set_value(spi_sdi
, 1);
128 gpio_set_value(spi_sdi
, 0);
130 /* #2: Drive the Clk High and then Low */
132 gpio_set_value(spi_sclk
, 1);
134 gpio_set_value(spi_sclk
, 0);
137 /* Idle state of SDO (MOSI) is Low */
138 gpio_set_value(spi_sdi
, 0);
139 /* ..then Lower Byte */
140 val
= (uint8
) (tx_val
& 0x00FF);
141 /* Before we enter here the Clock should be Low ! */
143 for (i
= 0; i
< 8; i
++) {
144 /* #1: Drive the Data (High or Low) */
145 if (val
& bit_shift
[i
])
146 gpio_set_value(spi_sdi
, 1);
148 gpio_set_value(spi_sdi
, 0);
150 /* #2: Drive the Clk High and then Low */
153 gpio_set_value(spi_sclk
, 1);
155 gpio_set_value(spi_sclk
, 0);
158 /* Idle state of SDO (MOSI) is Low */
159 gpio_set_value(spi_sdi
, 0);
161 /* Now Disable the Chip Select */
163 gpio_set_value(spi_cs
, 0);
166 static void spi_init(void)
168 /* Setting the Default GPIO's */
169 spi_sclk
= *(lcdc_gordon_pdata
->gpio_num
);
170 spi_cs
= *(lcdc_gordon_pdata
->gpio_num
+ 1);
171 spi_sdi
= *(lcdc_gordon_pdata
->gpio_num
+ 2);
172 spi_sdo
= *(lcdc_gordon_pdata
->gpio_num
+ 3);
174 /* Set the output so that we dont disturb the slave device */
175 gpio_set_value(spi_sclk
, 0);
176 gpio_set_value(spi_sdi
, 0);
178 /* Set the Chip Select De-asserted */
179 gpio_set_value(spi_cs
, 0);
183 static void gordon_disp_powerup(void)
185 if (!gordon_state
.disp_powered_up
&& !gordon_state
.display_on
) {
186 /* Reset the hardware first */
187 /* Include DAC power up implementation here */
188 gordon_state
.disp_powered_up
= TRUE
;
192 static void gordon_init(void)
194 /* Image interface settings */
195 serigo(GORDON_REG_IMGCTL2
, 0x00);
196 serigo(GORDON_REG_IMGSET1
, 0x00);
198 /* Exchange the RGB signal for J510(Softbank mobile) */
199 serigo(GORDON_REG_IMGSET2
, 0x12);
200 serigo(GORDON_REG_LCDIFSET1
, 0x00);
202 /* Pre-charge settings */
203 serigo(GORDON_REG_PCCTL
, 0x09);
204 serigo(GORDON_REG_LCDIFCTL2
, 0x7B);
209 static void gordon_disp_on(void)
211 if (gordon_state
.disp_powered_up
&& !gordon_state
.display_on
) {
214 /* gordon_dispmode setting */
215 serigo(GORDON_REG_TPARAM1
, 0x30);
216 serigo(GORDON_REG_TLCDIF1
, 0x00);
217 serigo(GORDON_REG_TSSPB_ST1
, 0x8B);
218 serigo(GORDON_REG_TSSPB_ED1
, 0x93);
219 serigo(GORDON_REG_TSCK_ST1
, 0x88);
220 serigo(GORDON_REG_TSCK_WD1
, 0x00);
221 serigo(GORDON_REG_TGSPB_VST1
, 0x01);
222 serigo(GORDON_REG_TGSPB_VED1
, 0x02);
223 serigo(GORDON_REG_TGSPB_CH1
, 0x5E);
224 serigo(GORDON_REG_TGCK_ST1
, 0x80);
225 serigo(GORDON_REG_TGCK_ED1
, 0x3C);
226 serigo(GORDON_REG_TPCTL_ST1
, 0x50);
227 serigo(GORDON_REG_TPCTL_ED1
, 0x74);
228 serigo(GORDON_REG_TPCHG_ED1
, 0x78);
229 serigo(GORDON_REG_TCOM_CH1
, 0x50);
230 serigo(GORDON_REG_THBP1
, 0x84);
231 serigo(GORDON_REG_TPHCTL1
, 0x00);
232 serigo(GORDON_REG_EVPH1
, 0x70);
233 serigo(GORDON_REG_EVPL1
, 0x64);
234 serigo(GORDON_REG_EVNH1
, 0x56);
235 serigo(GORDON_REG_EVNL1
, 0x48);
236 serigo(GORDON_REG_TBIAS1
, 0x88);
239 serigo(GORDON_REG_TPARAM2
, 0x28);
240 serigo(GORDON_REG_TLCDIF2
, 0x14);
241 serigo(GORDON_REG_TSSPB_ST2
, 0x49);
242 serigo(GORDON_REG_TSSPB_ED2
, 0x4B);
243 serigo(GORDON_REG_TSCK_ST2
, 0x4A);
244 serigo(GORDON_REG_TSCK_WD2
, 0x02);
245 serigo(GORDON_REG_TGSPB_VST2
, 0x02);
246 serigo(GORDON_REG_TGSPB_VED2
, 0x03);
247 serigo(GORDON_REG_TGSPB_CH2
, 0x2F);
248 serigo(GORDON_REG_TGCK_ST2
, 0x40);
249 serigo(GORDON_REG_TGCK_ED2
, 0x1E);
250 serigo(GORDON_REG_TPCTL_ST2
, 0x2C);
251 serigo(GORDON_REG_TPCTL_ED2
, 0x3A);
252 serigo(GORDON_REG_TPCHG_ED2
, 0x3C);
253 serigo(GORDON_REG_TCOM_CH2
, 0x28);
254 serigo(GORDON_REG_THBP2
, 0x4D);
255 serigo(GORDON_REG_TPHCTL2
, 0x1A);
258 serigo(GORDON_REG_IVBP1
, 0x02);
259 serigo(GORDON_REG_IHBP1
, 0x90);
260 serigo(GORDON_REG_IVNUM1
, 0xA0);
261 serigo(GORDON_REG_IHNUM1
, 0x78);
264 serigo(GORDON_REG_IVBP2
, 0x02);
265 serigo(GORDON_REG_IHBP2
, 0x48);
266 serigo(GORDON_REG_IVNUM2
, 0x50);
267 serigo(GORDON_REG_IHNUM2
, 0x3C);
269 /* Gordon Charge pump settings and ON */
270 serigo(GORDON_REG_POWCTL
, 0x03);
272 serigo(GORDON_REG_POWCTL
, 0x07);
275 serigo(GORDON_REG_POWCTL
, 0x0F);
278 serigo(GORDON_REG_AVCTL
, 0x03);
281 serigo(GORDON_REG_POWCTL
, 0x1F);
284 serigo(GORDON_REG_POWCTL
, 0x5F);
287 serigo(GORDON_REG_POWCTL
, 0x7F);
290 serigo(GORDON_REG_LCDIFCTL1
, 0x02);
293 serigo(GORDON_REG_IMGCTL1
, 0x00);
296 serigo(GORDON_REG_LCDIFCTL3
, 0x00);
299 serigo(GORDON_REG_VALTRAN
, 0x01);
302 serigo(GORDON_REG_LCDIFCTL1
, 0x03);
304 gordon_state
.display_on
= TRUE
;
308 static int lcdc_gordon_panel_on(struct platform_device
*pdev
)
310 if (!gordon_state
.disp_initialized
) {
311 /* Configure reset GPIO that drives DAC */
312 lcdc_gordon_pdata
->panel_config_gpio(1);
313 spi_dac
= *(lcdc_gordon_pdata
->gpio_num
+ 4);
314 gpio_set_value(spi_dac
, 0);
316 gpio_set_value(spi_dac
, 1);
317 spi_init(); /* LCD needs SPI */
318 gordon_disp_powerup();
320 gordon_state
.disp_initialized
= TRUE
;
325 static int lcdc_gordon_panel_off(struct platform_device
*pdev
)
327 if (gordon_state
.disp_powered_up
&& gordon_state
.display_on
) {
328 serigo(GORDON_REG_LCDIFCTL2
, 0x7B);
329 serigo(GORDON_REG_VALTRAN
, 0x01);
330 serigo(GORDON_REG_LCDIFCTL1
, 0x02);
331 serigo(GORDON_REG_LCDIFCTL3
, 0x01);
333 serigo(GORDON_REG_VALTRAN
, 0x01);
334 serigo(GORDON_REG_IMGCTL1
, 0x01);
335 serigo(GORDON_REG_LCDIFCTL1
, 0x00);
338 serigo(GORDON_REG_POWCTL
, 0x1F);
341 serigo(GORDON_REG_POWCTL
, 0x07);
344 serigo(GORDON_REG_POWCTL
, 0x03);
347 serigo(GORDON_REG_POWCTL
, 0x00);
349 lcdc_gordon_pdata
->panel_config_gpio(0);
350 gordon_state
.display_on
= FALSE
;
351 gordon_state
.disp_initialized
= FALSE
;
356 static void lcdc_gordon_set_backlight(struct msm_fb_data_type
*mfd
)
358 int bl_level
= mfd
->bl_level
;
361 /* keep back light OFF */
362 serigo(GORDON_REG_LCDIFCTL2
, 0x0B);
364 serigo(GORDON_REG_VALTRAN
, 0x01);
366 /* keep back light ON */
367 serigo(GORDON_REG_LCDIFCTL2
, 0x7B);
369 serigo(GORDON_REG_VALTRAN
, 0x01);
373 static int __init
gordon_probe(struct platform_device
*pdev
)
376 lcdc_gordon_pdata
= pdev
->dev
.platform_data
;
379 msm_fb_add_device(pdev
);
383 static struct platform_driver this_driver
= {
384 .probe
= gordon_probe
,
386 .name
= "lcdc_gordon_vga",
390 static struct msm_fb_panel_data gordon_panel_data
= {
391 .on
= lcdc_gordon_panel_on
,
392 .off
= lcdc_gordon_panel_off
,
393 .set_backlight
= lcdc_gordon_set_backlight
,
396 static struct platform_device this_device
= {
397 .name
= "lcdc_gordon_vga",
400 .platform_data
= &gordon_panel_data
,
404 static int __init
lcdc_gordon_panel_init(void)
407 struct msm_panel_info
*pinfo
;
409 #ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
410 if (msm_fb_detect_client("lcdc_gordon_vga"))
413 ret
= platform_driver_register(&this_driver
);
417 pinfo
= &gordon_panel_data
.panel_info
;
420 pinfo
->type
= LCDC_PANEL
;
421 pinfo
->pdest
= DISPLAY_1
;
422 pinfo
->wait_cycle
= 0;
425 pinfo
->clk_rate
= 24500000;
429 pinfo
->lcdc
.h_back_porch
= 84;
430 pinfo
->lcdc
.h_front_porch
= 33;
431 pinfo
->lcdc
.h_pulse_width
= 60;
432 pinfo
->lcdc
.v_back_porch
= 0;
433 pinfo
->lcdc
.v_front_porch
= 2;
434 pinfo
->lcdc
.v_pulse_width
= 2;
435 pinfo
->lcdc
.border_clr
= 0; /* blk */
436 pinfo
->lcdc
.underflow_clr
= 0xff; /* blue */
437 pinfo
->lcdc
.hsync_skew
= 0;
439 ret
= platform_device_register(&this_device
);
441 platform_driver_unregister(&this_driver
);
446 module_init(lcdc_gordon_panel_init
);