tizen 2.3.1 release
[platform/kernel/u-boot.git] / drivers / video / s6e39a0x.c
1 /* linux/drivers/video/s6e39a0x.c
2  *
3  * MIPI-DSI based s6e39a0x AMOLED lcd panel driver.
4  *
5  * Donghwa Lee, <dh09.lee@samsung.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10 */
11
12 #include <common.h>
13 #include <linux/types.h>
14 #include <asm/io.h>
15 #include <asm/arch/cpu.h>
16 #include <asm/arch/gpio.h>
17 #include <asm/arch/mipi_dsim.h>
18 #include <spi.h>
19
20 #define MIN_BRIGHTNESS  0
21 #define MAX_BRIGHTNESS  10
22 #define IRQ_HANDLED     1
23
24 static struct mipi_ddi_platform_data *ddi_pd;
25
26 /* This is only used Goni Rev0.4 */
27 extern int s5p_dsim_register_lcd_driver(struct mipi_lcd_driver *lcd_drv);
28
29 struct s6e39a0x {
30         struct device   *dev;
31         unsigned int    power;
32         unsigned int    current_brightness;
33 };
34
35 static void s6e39a0x_etc_cond(void)
36 {
37         unsigned char data_to_send[3] = {
38                 0xf0, 0x5a, 0x5a
39         };
40
41         ddi_pd->cmd_write((void *)ddi_pd->dsim_data, DCS_LONG_WR,
42                 (unsigned int) data_to_send, sizeof(data_to_send));
43 }
44
45 static void s6e39a0x_gamma_cond(void)
46 {
47         unsigned char data_to_send[26] = {
48                 0xfa, 0x02, 0x18, 0x08, 0x24, 0xe0, 0xd9, 0xd5, 0xc8,
49                 0xcf, 0xc0, 0xd3, 0xd9, 0xcc, 0xa9, 0xb2, 0x9d, 0xbb,
50                 0xc1, 0xb3, 0x00, 0x9e, 0x00, 0x9a, 0x00, 0xd3
51         };
52
53         ddi_pd->cmd_write((void *)ddi_pd->dsim_data, DCS_LONG_WR,
54                 (unsigned int) data_to_send, sizeof(data_to_send));
55 }
56
57 static void s6e39a0x_gamma_update(void)
58 {
59         ddi_pd->cmd_write((void *)ddi_pd->dsim_data, DCS_WR_1_PARA, 0xfa, 0x03);
60 }
61
62 static void s6e39a0x_panel_cond(void)
63 {
64         unsigned char data_to_send[14] = {
65                 0xf8, 0x28, 0x28, 0x08, 0x08, 0x40, 0xb0,
66                 0x50, 0x90, 0x10, 0x30, 0x10, 0x00, 0x00
67         };
68
69         ddi_pd->cmd_write((void *)ddi_pd->dsim_data, DCS_LONG_WR,
70                 (unsigned int) data_to_send, sizeof(data_to_send));
71 }
72 static void s6e39a0x_new1_cond(void)
73 {
74         unsigned char data_to_send[4] = {
75                 0xf6, 0x00, 0x84, 0x09
76         };
77
78         ddi_pd->cmd_write((void *)ddi_pd->dsim_data, DCS_LONG_WR,
79                 (unsigned int) data_to_send, sizeof(data_to_send));
80 }
81 static void s6e39a0x_etc_cond2(void)
82 {
83         ddi_pd->cmd_write((void *)ddi_pd->dsim_data, DCS_WR_1_PARA, 0xb0, 0x01);
84 }
85
86 static void s6e39a0x_etc_cond3(void)
87 {
88         unsigned char data_to_send[3] = {
89                 0xc0, 0x00, 0x00
90         };
91
92         ddi_pd->cmd_write((void *)ddi_pd->dsim_data, DCS_LONG_WR,
93                 (unsigned int) data_to_send, sizeof(data_to_send));
94 }
95
96 static void s6e39a0x_etc_cond4(void)
97 {
98         unsigned char data_to_send[5] = {
99                 0x2a, 0x00, 0x00, 0x02, 0x57
100         };
101
102         ddi_pd->cmd_write((void *)ddi_pd->dsim_data, DCS_LONG_WR,
103                 (unsigned int) data_to_send, sizeof(data_to_send));
104 }
105
106 static void s6e39a0x_etc_cond5(void)
107 {
108         unsigned char data_to_send[5] = {
109                 0x2b, 0x00, 0x00, 0x03, 0xff
110         };
111
112         ddi_pd->cmd_write((void *)ddi_pd->dsim_data, DCS_LONG_WR,
113                 (unsigned int) data_to_send, sizeof(data_to_send));
114 }
115
116 static void s6e39a0x_etc_cond6(void)
117 {
118         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
119                 DCS_WR_1_PARA, 0xb0, 0x09);
120 }
121
122 static void s6e39a0x_etc_cond7(void)
123 {
124         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
125                 DCS_WR_1_PARA, 0xd5, 0x64);
126 }
127
128 static void s6e39a0x_etc_cond8(void)
129 {
130         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
131                 DCS_WR_1_PARA, 0xb0, 0x0b);
132 }
133
134 static void s6e39a0x_etc_cond9(void)
135 {
136         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
137                 DCS_WR_1_PARA, 0xd5, 0xa4);
138 }
139
140 static void s6e39a0x_etc_cond10(void)
141 {
142         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
143                 DCS_WR_1_PARA, 0xb0, 0x0c);
144 }
145
146 static void s6e39a0x_etc_cond11(void)
147 {
148         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
149                 DCS_WR_1_PARA, 0xd5, 0x7e);
150 }
151
152 static void s6e39a0x_etc_cond12(void)
153 {
154         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
155                 DCS_WR_1_PARA, 0xf7, 0x03);
156 }
157
158 static void s6e39a0x_etc_cond13(void)
159 {
160         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
161                 DCS_WR_1_PARA, 0xb0, 0x02);
162 }
163
164 static void s6e39a0x_etc_cond14(void)
165 {
166         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
167                 DCS_WR_1_PARA, 0xb3, 0xc3);
168 }
169
170 static void s6e39a0x_sleep_in(void)
171 {
172         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
173                 DCS_WR_NO_PARA, 0x10, 0x00);
174 }
175
176 static void s6e39a0x_sleep_out(void)
177 {
178         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
179                 DCS_WR_NO_PARA, 0x11, 0x00);
180 }
181
182 void s6e39a0x_display_on(void)
183 {
184         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
185                 DCS_WR_NO_PARA, 0x29, 0x00);
186 }
187
188 static void s6e39a0x_display_off(void)
189 {
190         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
191                 DCS_WR_NO_PARA, 0x28, 0x00);
192 }
193
194 static void s6e39a0x_te_on(void)
195 {
196         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
197                 DCS_WR_NO_PARA, 0x35, 0x00);
198 }
199
200 static void s6e39a0x_global(void)
201 {
202         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
203                 DCS_WR_1_PARA, 0xb0, 0x01);
204 }
205
206 static void s6e39a0x_dispctl(void)
207 {
208         ddi_pd->cmd_write((void *)ddi_pd->dsim_data,
209                 DCS_WR_1_PARA, 0xf2, 0x01);
210 }
211
212 int s6e39a0x_panel_init(void)
213 {
214         /* 
215          * in case of setting gamma and panel condition at first,
216          * it shuold be setting like below.
217          * set_gamma() -> set_panel_condition()
218          */
219         udelay(10000);
220         s6e39a0x_etc_cond();
221         s6e39a0x_gamma_cond();
222         s6e39a0x_gamma_update();
223         s6e39a0x_panel_cond();
224         s6e39a0x_new1_cond();
225         s6e39a0x_etc_cond2();
226         s6e39a0x_etc_cond3();
227         s6e39a0x_etc_cond4();
228         s6e39a0x_etc_cond5();
229         s6e39a0x_etc_cond6();
230         s6e39a0x_etc_cond7();
231         s6e39a0x_etc_cond8();
232         s6e39a0x_etc_cond9();
233         s6e39a0x_etc_cond10();
234         s6e39a0x_etc_cond11();
235         s6e39a0x_etc_cond12();
236         s6e39a0x_etc_cond13();
237         s6e39a0x_etc_cond14();
238         s6e39a0x_global();
239         s6e39a0x_dispctl();
240         s6e39a0x_te_on();
241         s6e39a0x_sleep_out();
242         udelay(120000);
243
244         return 0;
245 }
246
247 int s6e39a0x_set_link(struct mipi_ddi_platform_data *pd)
248 {
249         if (pd == NULL) {
250                 printf("mipi_ddi_platform_data pointer is NULL.\n");
251                 return -1;
252         }
253
254         /* check callback functions. */
255         if (pd->cmd_write == NULL) {
256                 printf("cmd_write function is null.\n");
257                 return -1;
258         }
259
260         if (pd->get_dsim_frame_done == NULL) {
261                 printf("dsim_frame_done function is null.\n");
262                 return -1;
263         }
264
265         if (pd->clear_dsim_frame_done == NULL) {
266                 printf("clear_dsim_frame_done function is null.\n");
267                 return -1;
268         }
269
270         if (pd->change_dsim_transfer_mode == NULL)
271                 printf("change_dsim_transfer_mode is null.\n");
272
273         if (pd->get_fb_frame_done == NULL)
274                 printf("change_dsim_transfer_mode is null.\n");
275
276         if (pd->trigger == NULL)
277                 printf("trigger is null.\n");
278
279         ddi_pd = pd;
280         return 0;
281 }
282
283 /* this function would be called at universal.c */
284 void s6e39a0x_set_platform_data(struct mipi_ddi_platform_data *pd)
285 {
286         if (pd == NULL) {
287                 printf("pd is NULL.\n");
288                 return;
289         }
290
291         ddi_pd = pd;
292 }
293
294 static struct mipi_lcd_driver s6e39a0x_mipi_driver = {
295         .name = "s6e39a0x",
296
297         .init = s6e39a0x_panel_init,
298         .display_on = s6e39a0x_display_on,
299         .set_link = s6e39a0x_set_link,
300 };
301
302 int s6e39a0x_init(void)
303 {
304         s5p_dsim_register_lcd_driver(&s6e39a0x_mipi_driver);
305
306         return 0;
307 }