Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[pandora-kernel.git] / drivers / staging / msm / lcdc_gordon.c
1 /* Copyright (c) 2009, 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  * 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
15  * 02110-1301, USA.
16  */
17
18 #include <linux/delay.h>
19 #include <mach/gpio.h>
20 #include "msm_fb.h"
21
22 /* registers */
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
83
84 static int lcdc_gordon_panel_off(struct platform_device *pdev);
85
86 static int spi_cs;
87 static int spi_sclk;
88 static int spi_sdo;
89 static int spi_sdi;
90 static int spi_dac;
91 static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
92         (1 << 6),
93         (1 << 5),
94         (1 << 4),
95         (1 << 3),
96         (1 << 2),
97         (1 << 1),
98         (1 << 0)                               /* LSB */
99 };
100
101 struct gordon_state_type{
102         boolean disp_initialized;
103         boolean display_on;
104         boolean disp_powered_up;
105 };
106
107 static struct gordon_state_type gordon_state = { 0 };
108 static struct msm_panel_common_pdata *lcdc_gordon_pdata;
109
110 static void serigo(uint16 reg, uint8 data)
111 {
112         unsigned int tx_val = ((0x00FF & reg) << 8) | data;
113         unsigned char i, val = 0;
114
115         /* Enable the Chip Select */
116         gpio_set_value(spi_cs, 1);
117         udelay(33);
118
119         /* Transmit it in two parts, Higher Byte first, then Lower Byte */
120         val = (unsigned char)((tx_val & 0xFF00) >> 8);
121
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);
127                 else
128                         gpio_set_value(spi_sdi, 0);
129
130                 /* #2: Drive the Clk High and then Low */
131                 udelay(33);
132                 gpio_set_value(spi_sclk, 1);
133                 udelay(33);
134                 gpio_set_value(spi_sclk, 0);
135         }
136
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 ! */
142
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);
147                 else
148                         gpio_set_value(spi_sdi, 0);
149
150                 /* #2: Drive the Clk High and then Low */
151                 udelay(33);
152
153                 gpio_set_value(spi_sclk, 1);
154                 udelay(33);
155                 gpio_set_value(spi_sclk, 0);
156         }
157
158         /* Idle state of SDO (MOSI) is Low */
159         gpio_set_value(spi_sdi, 0);
160
161         /* Now Disable the Chip Select */
162         udelay(33);
163         gpio_set_value(spi_cs, 0);
164 }
165
166 static void spi_init(void)
167 {
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);
173
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);
177
178         /* Set the Chip Select De-asserted */
179         gpio_set_value(spi_cs, 0);
180
181 }
182
183 static void gordon_disp_powerup(void)
184 {
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;
189         }
190 }
191
192 static void gordon_init(void)
193 {
194         /* Image interface settings */
195         serigo(GORDON_REG_IMGCTL2, 0x00);
196         serigo(GORDON_REG_IMGSET1, 0x00);
197
198         /* Exchange the RGB signal for J510(Softbank mobile) */
199         serigo(GORDON_REG_IMGSET2, 0x12);
200         serigo(GORDON_REG_LCDIFSET1, 0x00);
201
202         /* Pre-charge settings */
203         serigo(GORDON_REG_PCCTL, 0x09);
204         serigo(GORDON_REG_LCDIFCTL2, 0x7B);
205
206         mdelay(1);
207 }
208
209 static void gordon_disp_on(void)
210 {
211         if (gordon_state.disp_powered_up && !gordon_state.display_on) {
212                 gordon_init();
213                 mdelay(20);
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);
237
238                 /* QVGA settings */
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);
256
257                 /* VGA settings */
258                 serigo(GORDON_REG_IVBP1, 0x02);
259                 serigo(GORDON_REG_IHBP1, 0x90);
260                 serigo(GORDON_REG_IVNUM1, 0xA0);
261                 serigo(GORDON_REG_IHNUM1, 0x78);
262
263                 /* QVGA settings */
264                 serigo(GORDON_REG_IVBP2, 0x02);
265                 serigo(GORDON_REG_IHBP2, 0x48);
266                 serigo(GORDON_REG_IVNUM2, 0x50);
267                 serigo(GORDON_REG_IHNUM2, 0x3C);
268
269                 /* Gordon Charge pump settings and ON */
270                 serigo(GORDON_REG_POWCTL, 0x03);
271                 mdelay(15);
272                 serigo(GORDON_REG_POWCTL, 0x07);
273                 mdelay(15);
274
275                 serigo(GORDON_REG_POWCTL, 0x0F);
276                 mdelay(15);
277
278                 serigo(GORDON_REG_AVCTL, 0x03);
279                 mdelay(15);
280
281                 serigo(GORDON_REG_POWCTL, 0x1F);
282                 mdelay(15);
283
284                 serigo(GORDON_REG_POWCTL, 0x5F);
285                 mdelay(15);
286
287                 serigo(GORDON_REG_POWCTL, 0x7F);
288                 mdelay(15);
289
290                 serigo(GORDON_REG_LCDIFCTL1, 0x02);
291                 mdelay(15);
292
293                 serigo(GORDON_REG_IMGCTL1, 0x00);
294                 mdelay(15);
295
296                 serigo(GORDON_REG_LCDIFCTL3, 0x00);
297                 mdelay(15);
298
299                 serigo(GORDON_REG_VALTRAN, 0x01);
300                 mdelay(15);
301
302                 serigo(GORDON_REG_LCDIFCTL1, 0x03);
303                 mdelay(1);
304                 gordon_state.display_on = TRUE;
305         }
306 }
307
308 static int lcdc_gordon_panel_on(struct platform_device *pdev)
309 {
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);
315                 udelay(15);
316                 gpio_set_value(spi_dac, 1);
317                 spi_init();     /* LCD needs SPI */
318                 gordon_disp_powerup();
319                 gordon_disp_on();
320                 gordon_state.disp_initialized = TRUE;
321         }
322         return 0;
323 }
324
325 static int lcdc_gordon_panel_off(struct platform_device *pdev)
326 {
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);
332                 mdelay(20);
333                 serigo(GORDON_REG_VALTRAN, 0x01);
334                 serigo(GORDON_REG_IMGCTL1, 0x01);
335                 serigo(GORDON_REG_LCDIFCTL1, 0x00);
336                 mdelay(20);
337
338                 serigo(GORDON_REG_POWCTL, 0x1F);
339                 mdelay(40);
340
341                 serigo(GORDON_REG_POWCTL, 0x07);
342                 mdelay(40);
343
344                 serigo(GORDON_REG_POWCTL, 0x03);
345                 mdelay(40);
346
347                 serigo(GORDON_REG_POWCTL, 0x00);
348                 mdelay(40);
349                 lcdc_gordon_pdata->panel_config_gpio(0);
350                 gordon_state.display_on = FALSE;
351                 gordon_state.disp_initialized = FALSE;
352         }
353         return 0;
354 }
355
356 static void lcdc_gordon_set_backlight(struct msm_fb_data_type *mfd)
357 {
358                 int bl_level = mfd->bl_level;
359
360                 if (bl_level <= 1) {
361                         /* keep back light OFF */
362                         serigo(GORDON_REG_LCDIFCTL2, 0x0B);
363                         udelay(15);
364                         serigo(GORDON_REG_VALTRAN, 0x01);
365                 } else {
366                         /* keep back light ON */
367                         serigo(GORDON_REG_LCDIFCTL2, 0x7B);
368                         udelay(15);
369                         serigo(GORDON_REG_VALTRAN, 0x01);
370                 }
371 }
372
373 static int __init gordon_probe(struct platform_device *pdev)
374 {
375         if (pdev->id == 0) {
376                 lcdc_gordon_pdata = pdev->dev.platform_data;
377                 return 0;
378         }
379         msm_fb_add_device(pdev);
380         return 0;
381 }
382
383 static struct platform_driver this_driver = {
384         .probe  = gordon_probe,
385         .driver = {
386                 .name   = "lcdc_gordon_vga",
387         },
388 };
389
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,
394 };
395
396 static struct platform_device this_device = {
397         .name   = "lcdc_gordon_vga",
398         .id     = 1,
399         .dev    = {
400                 .platform_data = &gordon_panel_data,
401         }
402 };
403
404 static int __init lcdc_gordon_panel_init(void)
405 {
406         int ret;
407         struct msm_panel_info *pinfo;
408
409 #ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
410         if (msm_fb_detect_client("lcdc_gordon_vga"))
411                 return 0;
412 #endif
413         ret = platform_driver_register(&this_driver);
414         if (ret)
415                 return ret;
416
417         pinfo = &gordon_panel_data.panel_info;
418         pinfo->xres = 480;
419         pinfo->yres = 640;
420         pinfo->type = LCDC_PANEL;
421         pinfo->pdest = DISPLAY_1;
422         pinfo->wait_cycle = 0;
423         pinfo->bpp = 24;
424         pinfo->fb_num = 2;
425         pinfo->clk_rate = 24500000;
426         pinfo->bl_max = 4;
427         pinfo->bl_min = 1;
428
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;
438
439         ret = platform_device_register(&this_device);
440         if (ret)
441                 platform_driver_unregister(&this_driver);
442
443         return ret;
444 }
445
446 module_init(lcdc_gordon_panel_init);