s5pc110: ld9040 lcd panel display reversed
[kernel/u-boot.git] / drivers / video / ld9040.c
1 /*
2  * LCD panel driver for Board based on S5PC100 and S5PC110. 
3  *
4  * Author: Donghwa Lee  <dh09.lee@samsung.com>
5  *
6  * Derived from drivers/video/omap/lcd-apollon.c
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2 of the License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  */
22
23 #include <common.h>
24 #include <linux/types.h>
25 #include <asm/io.h>
26 #include <asm/arch/cpu.h>
27 #include <asm/arch/gpio.h>
28 #include "s5p-spi.h"
29
30 /* these machine specific platform data would be setting at universal.c */
31 struct spi_platform_data *ld9040;
32
33 static const unsigned char SEQ_SWRESET[] = {
34         0x01, COMMAND_ONLY,
35 };
36
37 static const unsigned char SEQ_USER_SETTING[] = {
38         0xF0, 0x5A,
39
40         DATA_ONLY, 0x5A,
41 };
42
43 static const unsigned char SEQ_ELVSS[] = {
44         0xB1, 0x0B,
45
46         DATA_ONLY, 0x00,
47         DATA_ONLY, 0x16,
48 };
49
50 static const unsigned char SEQ_GTCON[] = {
51         0xF7, 0x09,
52
53         DATA_ONLY, 0x00,
54         DATA_ONLY, 0x00,
55 };
56
57 static const unsigned char SEQ_GAMMA_SET1[] = {
58         0xF9, 0x18,
59
60         DATA_ONLY, 0x9A,
61         DATA_ONLY, 0xB0,
62         DATA_ONLY, 0xAB,
63         DATA_ONLY, 0xC4,
64         DATA_ONLY, 0x00,
65         DATA_ONLY, 0xAA,
66         DATA_ONLY, 0x00,
67         DATA_ONLY, 0xA1,
68         DATA_ONLY, 0xB5,
69         DATA_ONLY, 0xB0,
70         DATA_ONLY, 0xC7,
71         DATA_ONLY, 0x00,
72         DATA_ONLY, 0xC5,
73         DATA_ONLY, 0x24,
74         DATA_ONLY, 0xA7,
75         DATA_ONLY, 0xAC,
76         DATA_ONLY, 0x9A,
77         DATA_ONLY, 0xB6,
78         DATA_ONLY, 0x00,
79         DATA_ONLY, 0xE5,
80 };
81
82 static const unsigned char SEQ_GAMMA_CTRL[] = {
83         0xFB, 0x00,
84
85         DATA_ONLY, 0x5A,
86 };
87
88 static const unsigned char SEQ_APON[] = {
89         0xF3, 0x00,
90
91         DATA_ONLY, 0x00,
92         DATA_ONLY, 0x00,
93         DATA_ONLY, 0x0A,
94         DATA_ONLY, 0x02,
95 };
96
97 static const unsigned char SEQ_DISPCTL[] = {
98         0xF2, 0x02,
99
100         DATA_ONLY, 0x03,
101         DATA_ONLY, 0x1C,
102         DATA_ONLY, 0x10,
103         DATA_ONLY, 0x10,
104 };
105
106 static const unsigned char SEQ_SLPOUT[] = {
107         0x11, COMMAND_ONLY,
108 };
109
110 static const unsigned char SEQ_SLPIN[] = {
111         0x10, COMMAND_ONLY,
112 };
113
114 static const unsigned char SEQ_DISPON[] = {
115         0x29, COMMAND_ONLY,
116 };
117
118 static const unsigned char SEQ_DISPOFF[] = {
119         0x28, COMMAND_ONLY,
120 };
121
122 static const unsigned char SEQ_VCI1_1ST_EN[] = {
123         0xF3, 0x10,
124
125         DATA_ONLY, 0x00,
126         DATA_ONLY, 0x00,
127         DATA_ONLY, 0x00,
128         DATA_ONLY, 0x02,
129 };
130
131 static const unsigned char SEQ_VL1_EN[] = {
132         0xF3, 0x11,
133
134         DATA_ONLY, 0x00,
135         DATA_ONLY, 0x00,
136         DATA_ONLY, 0x00,
137         DATA_ONLY, 0x02,
138 };
139
140 static const unsigned char SEQ_VL2_EN[] = {
141         0xF3, 0x13,
142
143         DATA_ONLY, 0x00,
144         DATA_ONLY, 0x00,
145         DATA_ONLY, 0x00,
146         DATA_ONLY, 0x02,
147 };
148
149 static const unsigned char SEQ_VCI1_2ND_EN[] = {
150         0xF3, 0x33,
151
152         DATA_ONLY, 0x00,
153         DATA_ONLY, 0x00,
154         DATA_ONLY, 0x00,
155         DATA_ONLY, 0x02,
156 };
157
158 static const unsigned char SEQ_VL3_EN[] = {
159         0xF3, 0x37,
160
161         DATA_ONLY, 0x00,
162         DATA_ONLY, 0x00,
163         DATA_ONLY, 0x00,
164         DATA_ONLY, 0x02,
165 };
166
167 static const unsigned char SEQ_VREG1_AMP_EN[] = {
168         0xF3, 0x37,
169
170         DATA_ONLY, 0x01,
171         DATA_ONLY, 0x00,
172         DATA_ONLY, 0x00,
173         DATA_ONLY, 0x02,
174 };
175
176 static const unsigned char SEQ_VGH_AMP_EN[] = {
177         0xF3, 0x37,
178
179         DATA_ONLY, 0x11,
180         DATA_ONLY, 0x00,
181         DATA_ONLY, 0x00,
182         DATA_ONLY, 0x02,
183 };
184
185 static const unsigned char SEQ_VGL_AMP_EN[] = {
186         0xF3, 0x37,
187
188         DATA_ONLY, 0x31,
189         DATA_ONLY, 0x00,
190         DATA_ONLY, 0x00,
191         DATA_ONLY, 0x02,
192 };
193
194 static const unsigned char SEQ_VMOS_AMP_EN[] = {
195         0xF3, 0x37,
196
197         DATA_ONLY, 0xB1,
198         DATA_ONLY, 0x00,
199         DATA_ONLY, 0x00,
200         DATA_ONLY, 0x03,
201 };
202
203 static const unsigned char SEQ_VINT_AMP_EN[] = {
204         0xF3, 0x37,
205
206         DATA_ONLY, 0xF1,
207         /* DATA_ONLY, 0x71,     VMOS/VBL/VBH not used */
208         DATA_ONLY, 0x00,
209         DATA_ONLY, 0x00,
210         DATA_ONLY, 0x03,
211         /* DATA_ONLY, 0x02,     VMOS/VBL/VBH not used */
212 };
213
214 static const unsigned char SEQ_VBH_AMP_EN[] = {
215         0xF3, 0x37,
216
217         DATA_ONLY, 0xF9,
218         DATA_ONLY, 0x00,
219         DATA_ONLY, 0x00,
220         DATA_ONLY, 0x03,
221 };
222
223 static const unsigned char SEQ_VBL_AMP_EN[] = {
224         0xF3, 0x37,
225
226         DATA_ONLY, 0xFD,
227         DATA_ONLY, 0x00,
228         DATA_ONLY, 0x00,
229         DATA_ONLY, 0x03,
230 };
231
232 static const unsigned char SEQ_GAM_AMP_EN[] = {
233         0xF3, 0x37,
234
235         DATA_ONLY, 0xFF,
236         /* DATA_ONLY, 0x73,     VMOS/VBL/VBH not used */
237         DATA_ONLY, 0x00,
238         DATA_ONLY, 0x00,
239         DATA_ONLY, 0x03,
240         /* DATA_ONLY, 0x02,     VMOS/VBL/VBH not used */
241 };
242
243 static const unsigned char SEQ_SD_AMP_EN[] = {
244         0xF3, 0x37,
245
246         DATA_ONLY, 0xFF,
247         /* DATA_ONLY, 0x73,     VMOS/VBL/VBH not used */
248         DATA_ONLY, 0x80,
249         DATA_ONLY, 0x00,
250         DATA_ONLY, 0x03,
251         /* DATA_ONLY, 0x02,     VMOS/VBL/VBH not used */
252 };
253
254 static const unsigned char SEQ_GLS_EN[] = {
255         0xF3, 0x37,
256
257         DATA_ONLY, 0xFF,
258         /* DATA_ONLY, 0x73,     VMOS/VBL/VBH not used */
259         DATA_ONLY, 0x81,
260         DATA_ONLY, 0x00,
261         DATA_ONLY, 0x03,
262         /* DATA_ONLY, 0x02,     VMOS/VBL/VBH not used */
263 };
264
265 static const unsigned char SEQ_ELS_EN[] = {
266         0xF3, 0x37,
267
268         DATA_ONLY, 0xFF,
269         /* DATA_ONLY, 0x73,     VMOS/VBL/VBH not used */
270         DATA_ONLY, 0x83,
271         DATA_ONLY, 0x00,
272         DATA_ONLY, 0x03,
273         /* DATA_ONLY, 0x02,     VMOS/VBL/VBH not used */
274 };
275
276 static const unsigned char SEQ_EL_ON[] = {
277         0xF3, 0x37,
278
279         DATA_ONLY, 0xFF,
280         /* DATA_ONLY, 0x73,     VMOS/VBL/VBH not used */
281         DATA_ONLY, 0x87,
282         DATA_ONLY, 0x00,
283         DATA_ONLY, 0x03,
284         /* DATA_ONLY, 0x02,     VMOS/VBL/VBH not used */
285 };
286
287 static void ld9040_spi_write(unsigned char address, unsigned char command)
288 {
289         if (address != DATA_ONLY)
290                 spi_write_byte(ld9040, 0x0, address);
291
292         if (command != COMMAND_ONLY)
293                 spi_write_byte(ld9040, 0x1, command);
294 }
295
296 static void ld9040_panel_send_sequence(const unsigned char *wbuf, unsigned int size_cmd)
297 {
298         int i = 0;
299         while (i < size_cmd) {
300                 ld9040_spi_write(wbuf[i], wbuf[i+1]);
301                 i += 2;
302         }
303 }
304
305 void ld9040_cfg_ldo(void)
306 {
307 #if 1
308         /* SMD power on sequence */
309         ld9040_panel_send_sequence(SEQ_USER_SETTING, ARRAY_SIZE(SEQ_USER_SETTING));
310         ld9040_panel_send_sequence(SEQ_ELVSS, ARRAY_SIZE(SEQ_ELVSS));
311         ld9040_panel_send_sequence(SEQ_GTCON, ARRAY_SIZE(SEQ_GTCON));
312         ld9040_panel_send_sequence(SEQ_GAMMA_SET1, ARRAY_SIZE(SEQ_GAMMA_SET1));
313         ld9040_panel_send_sequence(SEQ_GAMMA_CTRL, ARRAY_SIZE(SEQ_GAMMA_CTRL));
314         ld9040_panel_send_sequence(SEQ_SLPOUT, ARRAY_SIZE(SEQ_SLPOUT));
315         
316 #endif
317
318 #if 0
319         /* Auto power on sequence */
320         ld9040_panel_send_sequence(SEQ_USER_SETTING, ARRAY_SIZE(SEQ_USER_SETTING));
321         ld9040_panel_send_sequence(SEQ_ELVSS, ARRAY_SIZE(SEQ_ELVSS));
322         ld9040_panel_send_sequence(SEQ_SLPOUT, ARRAY_SIZE(SEQ_SLPOUT));
323 #endif
324
325 #if 0
326         /* Manual power on sequence */
327         ld9040_panel_send_sequence(SEQ_SWRESET, ARRAY_SIZE(SEQ_SWRESET));
328         ld9040_panel_send_sequence(SEQ_USER_SETTING, ARRAY_SIZE(SEQ_USER_SETTING));
329         ld9040_panel_send_sequence(SEQ_ELVSS, ARRAY_SIZE(SEQ_ELVSS));
330         ld9040_panel_send_sequence(SEQ_SLPOUT, ARRAY_SIZE(SEQ_SLPOUT));
331         ld9040_panel_send_sequence(SEQ_VCI1_1ST_EN, ARRAY_SIZE(SEQ_VCI1_1ST_EN));
332         udelay(6000);
333         ld9040_panel_send_sequence(SEQ_VL1_EN, ARRAY_SIZE(SEQ_VL1_EN));
334         udelay(6000);
335         ld9040_panel_send_sequence(SEQ_VL2_EN, ARRAY_SIZE(SEQ_VL2_EN));
336         udelay(6000);
337         ld9040_panel_send_sequence(SEQ_VCI1_2ND_EN, ARRAY_SIZE(SEQ_VCI1_2ND_EN));
338         udelay(6000);
339         ld9040_panel_send_sequence(SEQ_VL3_EN, ARRAY_SIZE(SEQ_VL3_EN));
340         udelay(6000);
341         ld9040_panel_send_sequence(SEQ_VREG1_AMP_EN, ARRAY_SIZE(SEQ_VREG1_AMP_EN));
342         udelay(6000);
343         ld9040_panel_send_sequence(SEQ_VGH_AMP_EN, ARRAY_SIZE(SEQ_VGH_AMP_EN));
344         udelay(6000);
345         ld9040_panel_send_sequence(SEQ_VGL_AMP_EN, ARRAY_SIZE(SEQ_VGL_AMP_EN));
346         udelay(6000);
347         ld9040_panel_send_sequence(SEQ_VMOS_AMP_EN, ARRAY_SIZE(SEQ_VMOS_AMP_EN));
348         udelay(6000);
349         ld9040_panel_send_sequence(SEQ_VINT_AMP_EN, ARRAY_SIZE(SEQ_VINT_AMP_EN));
350         udelay(6000);
351         ld9040_panel_send_sequence(SEQ_VBH_AMP_EN, ARRAY_SIZE(SEQ_VBH_AMP_EN));
352         udelay(6000);
353         ld9040_panel_send_sequence(SEQ_VBL_AMP_EN, ARRAY_SIZE(SEQ_VBL_AMP_EN));
354         udelay(6000);
355         ld9040_panel_send_sequence(SEQ_GAM_AMP_EN, ARRAY_SIZE(SEQ_GAM_AMP_EN));
356         udelay(6000);
357         ld9040_panel_send_sequence(SEQ_SD_AMP_EN, ARRAY_SIZE(SEQ_SD_AMP_EN));
358         udelay(6000);
359         ld9040_panel_send_sequence(SEQ_GLS_EN, ARRAY_SIZE(SEQ_GLS_EN));
360         udelay(6000);
361         ld9040_panel_send_sequence(SEQ_ELS_EN, ARRAY_SIZE(SEQ_ELS_EN));
362         udelay(6000);
363         ld9040_panel_send_sequence(SEQ_EL_ON, ARRAY_SIZE(SEQ_EL_ON));
364         udelay(6000);
365 #endif
366
367         udelay(10);
368 }
369
370 void ld9040_enable_ldo(unsigned int onoff)
371 {
372         if (onoff) {
373                 ld9040_panel_send_sequence(SEQ_DISPON, ARRAY_SIZE(SEQ_DISPON));
374         }
375 }
376
377 /* this function would be called at universal.c */
378 void ld9040_set_platform_data(struct spi_platform_data *pd)
379 {
380         if (pd == NULL) {
381                 printf("pd is NULL.\n");
382                 return;
383         }
384
385         ld9040 = pd;
386 }
387