]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/staging/msm/lcdc_gordon.c
Merge branch 'waltop' into for-linus
[mirror_ubuntu-artful-kernel.git] / drivers / staging / msm / lcdc_gordon.c
CommitLineData
9d200153
SM
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
84static int lcdc_gordon_panel_off(struct platform_device *pdev);
85
86static int spi_cs;
87static int spi_sclk;
88static int spi_sdo;
89static int spi_sdi;
90static int spi_dac;
91static 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
101struct gordon_state_type{
102 boolean disp_initialized;
103 boolean display_on;
104 boolean disp_powered_up;
105};
106
107static struct gordon_state_type gordon_state = { 0 };
108static struct msm_panel_common_pdata *lcdc_gordon_pdata;
109
110static 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
166static 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
183static 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
192static 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
209static 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
308static 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
325static 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
356static 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
373static 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
383static struct platform_driver this_driver = {
384 .probe = gordon_probe,
385 .driver = {
386 .name = "lcdc_gordon_vga",
387 },
388};
389
390static 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
396static struct platform_device this_device = {
397 .name = "lcdc_gordon_vga",
398 .id = 1,
399 .dev = {
400 .platform_data = &gordon_panel_data,
401 }
402};
403
404static 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
446module_init(lcdc_gordon_panel_init);