tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / drivers / video / lcd_s6d04h0.c
1 /*
2  * Copyright (C) 2012 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include <common.h>
15
16 #include <asm/arch/sc8810_lcd.h>
17 #define mdelay(a) udelay(a * 1000)
18 #define LCD_DelayMS mdelay
19
20 #define  LCD_DEBUG
21 #ifdef LCD_DEBUG
22 #define LCD_PRINT printf
23 #else
24 #define LCD_PRINT(...)
25 #endif
26
27 static int32_t s6d04h0_init(struct lcd_spec *self)
28 {
29         Send_data send_cmd = self->info.mcu->ops->send_cmd;
30         Send_data send_data = self->info.mcu->ops->send_data;
31
32         LCD_PRINT("s6d04h0_init\n");
33
34         send_cmd(0xF0);
35         send_data(0x5A);
36         send_data(0x5A);
37
38         send_cmd(0xF4);
39         send_data(0x09);
40         send_data(0x00);
41         send_data(0x00);
42         send_data(0x00);
43         send_data(0x77);
44         send_data(0x77);
45         send_data(0x07);
46         send_data(0x02);
47         send_data(0x2E);
48         send_data(0x47);
49         send_data(0x05);
50
51         send_cmd(0xF5);
52         send_data(0x00);
53         send_data(0x24);
54         send_data(0x5E);
55         send_data(0x00);
56         send_data(0x00);
57         send_data(0x0B);
58
59         send_cmd(0xF6);
60         send_data(0x00);
61         send_data(0x01);
62         send_data(0x07);
63         send_data(0x00);
64         send_data(0x01);
65         send_data(0x0C);
66         send_data(0x01);
67         send_data(0x0C);
68         send_data(0x07);
69
70         send_cmd(0x35);
71         send_data(0x00);
72
73         send_cmd(0x36);
74         send_data(0x98);
75
76         send_cmd(0x3A);
77         send_data(0x05);
78
79         send_cmd(0xF7);
80         send_data(0x00);
81         send_data(0x00);
82
83         send_cmd(0xF2);
84         send_data(0x28);
85         send_data(0x67);
86         send_data(0x03);
87         send_data(0x02);
88         send_data(0x02);
89         send_data(0x00);
90         send_data(0x00);
91         send_data(0x1D);
92         send_data(0x48);
93         send_data(0x00);
94         send_data(0x07);
95         send_data(0x01);
96
97         send_cmd(0xF9);
98         send_data(0x04);
99
100         send_cmd(0xFA);         // (PDISPCTRL_WRCTL)
101         send_data(0x00);
102         send_data(0x00);
103         send_data(0x10);
104         send_data(0x17);
105         send_data(0x25);
106         send_data(0x31);
107         send_data(0x21);
108         send_data(0x31);
109         send_data(0x2B);
110         send_data(0x28);
111         send_data(0x2B);
112         send_data(0x00);
113         send_data(0x00);
114         send_data(0x00);
115         send_data(0x00);
116         send_data(0x00);
117
118         send_cmd(0xFB);         // (PDISPCTRL_WRCTL)
119         send_data(0x00);
120         send_data(0x00);
121         send_data(0x30);
122         send_data(0x32);
123         send_data(0x33);
124         send_data(0x32);
125         send_data(0x23);
126         send_data(0x2B);
127         send_data(0x23);
128         send_data(0x1C);
129         send_data(0x12);
130         send_data(0x00);
131         send_data(0x00);
132         send_data(0x00);
133         send_data(0x00);
134         send_data(0x00);
135
136         send_cmd(0xF9);
137         send_data(0x02);
138
139         send_cmd(0xFA);         // (PDISPCTRL_WRCTL)
140         send_data(0x00);
141         send_data(0x00);
142         send_data(0x10);
143         send_data(0x17);
144         send_data(0x25);
145         send_data(0x31);
146         send_data(0x21);
147         send_data(0x31);
148         send_data(0x2B);
149         send_data(0x28);
150         send_data(0x2B);
151         send_data(0x00);
152         send_data(0x00);
153         send_data(0x00);
154         send_data(0x00);
155         send_data(0x00);
156
157         send_cmd(0xFB);         // (PDISPCTRL_WRCTL)
158         send_data(0x00);
159         send_data(0x00);
160         send_data(0x30);
161         send_data(0x32);
162         send_data(0x33);
163         send_data(0x32);
164         send_data(0x23);
165         send_data(0x2B);
166         send_data(0x23);
167         send_data(0x1C);
168         send_data(0x12);
169         send_data(0x00);
170         send_data(0x00);
171         send_data(0x00);
172         send_data(0x00);
173         send_data(0x00);
174
175         send_cmd(0xF9);
176         send_data(0x01);
177
178         send_cmd(0xFA);         // (PDISPCTRL_WRCTL)
179         send_data(0x00);
180         send_data(0x00);
181         send_data(0x10);
182         send_data(0x17);
183         send_data(0x25);
184         send_data(0x31);
185         send_data(0x21);
186         send_data(0x31);
187         send_data(0x2B);
188         send_data(0x28);
189         send_data(0x2B);
190         send_data(0x00);
191         send_data(0x00);
192         send_data(0x00);
193         send_data(0x00);
194         send_data(0x00);
195
196         send_cmd(0xFB);         // (PDISPCTRL_WRCTL)
197         send_data(0x00);
198         send_data(0x00);
199         send_data(0x30);
200         send_data(0x32);
201         send_data(0x33);
202         send_data(0x32);
203         send_data(0x23);
204         send_data(0x2B);
205         send_data(0x23);
206         send_data(0x1C);
207         send_data(0x12);
208         send_data(0x00);
209         send_data(0x00);
210         send_data(0x00);
211         send_data(0x00);
212         send_data(0x00);
213
214         send_cmd(0xF0);
215         send_data(0xA5);
216         send_data(0xA5);
217
218         send_cmd(0x11);         // (SLPOUT)
219
220         LCD_DelayMS(130);       // 120ms
221
222         send_cmd(0x29);         // (DISPON)
223
224         LCD_DelayMS(40);        // 40ms
225
226         return 0;
227 }
228
229 static int32_t s6d04h0_off(struct lcd_spec *self)
230 {
231         Send_data send_cmd = self->info.mcu->ops->send_cmd;
232         Send_data send_data = self->info.mcu->ops->send_data;
233
234         send_cmd(0x10);         // (SLPIN)
235         LCD_DelayMS(120);
236
237         return 0;
238 }
239
240 static int32_t s6d04h0_set_window(struct lcd_spec *self,
241                                   uint16_t left, uint16_t top, uint16_t right,
242                                   uint16_t bottom)
243 {
244         Send_data send_cmd = self->info.mcu->ops->send_cmd;
245         Send_data send_data = self->info.mcu->ops->send_data;
246
247         LCD_PRINT("s6d04h0_set_window:%d, %d, %d, %d\n", left, top, right,
248                   bottom);
249
250         send_cmd(0x2A);         // col
251         send_data((left >> 8));
252         send_data((left & 0xFF));
253         send_data((right >> 8));
254         send_data((right & 0xFF));
255
256         send_cmd(0x2B);         // row
257         send_data((top >> 8));
258         send_data((top & 0xFF));
259         send_data((bottom >> 8));
260         send_data((bottom & 0xFF));
261
262         send_cmd(0x2C);
263
264         return 0;
265 }
266
267 static int32_t s6d04h0_invalidate(struct lcd_spec *self)
268 {
269
270         return self->ops->lcd_set_window(self, 0, 0,
271                                            self->width - 1, self->height - 1);
272
273 }
274
275 static int32_t s6d04h0_invalidate_rect(struct lcd_spec *self,
276                                        uint16_t left, uint16_t top,
277                                        uint16_t right, uint16_t bottom)
278 {
279
280         LCD_PRINT("s6d04h0_invalidate_rect\n");
281
282         return self->ops->lcd_set_window(self, left, top, right, bottom);
283 }
284
285 static int32_t s6d04h0_set_direction(struct lcd_spec *self,
286                                      uint16_t direction)
287 {
288
289         LCD_PRINT("s6d04h0_set_direction\n");
290         return 0;
291 }
292
293 static int32_t s6d04h0_enter_sleep(struct lcd_spec *self, uint8_t is_sleep)
294 {
295         if (is_sleep) {
296                 LCD_PRINT("[LCD] s6d04h0_enter_sleep\n");
297                 self->ops->lcd_close(self);
298         } else {
299                 LCD_PRINT("[LCD] s6d04h0_enter_wakeup\n");
300                 self->ops->lcd_init(self);
301         }
302         return 0;
303 }
304
305 static uint32_t s6d04h0_read_id(struct lcd_spec *self)
306 {
307         uint32_t read_value = 0;
308         Send_data send_cmd = self->info.mcu->ops->send_cmd;
309         Read_data read_data = self->info.mcu->ops->read_data;
310
311         send_cmd(0x04);
312
313         read_data();
314         read_value += read_data() << 16;
315         read_value += read_data() << 8;
316         read_value += read_data();
317
318         LCD_PRINT("s6d04h0_read_id=%#x=====\n", read_value);
319
320         return read_value;
321 }
322
323 static struct lcd_operations lcd_s6d04h0_operations = {
324         .lcd_init = s6d04h0_init,
325         .lcd_close = s6d04h0_off,
326         .lcd_set_window = s6d04h0_set_window,
327         .lcd_invalidate = s6d04h0_invalidate,
328         .lcd_invalidate_rect = s6d04h0_invalidate_rect,
329         .lcd_set_direction = s6d04h0_set_direction,
330         .lcd_enter_sleep = s6d04h0_enter_sleep,
331         .lcd_readid = s6d04h0_read_id,
332 };
333
334 static struct timing_mcu lcd_s6d04h0_timing[] = {
335         [LCD_REGISTER_TIMING] = {
336                                  .rcss = 25,
337                                  .rlpw = 45,
338                                  .rhpw = 90,
339                                  .wcss = 30,
340                                  .wlpw = 15,
341                                  .whpw = 15,
342                                  },
343         [LCD_GRAM_TIMING] = {
344                              .rcss = 25,
345                              .rlpw = 45,
346                              .rhpw = 90,
347                              .wcss = 30,
348                              .wlpw = 15,
349                              .whpw = 15,
350                              }
351 };
352
353 static struct info_mcu lcd_s6d04h0_info = {
354         .bus_mode = LCD_BUS_8080,
355         .bus_width = 16,
356         .timing = lcd_s6d04h0_timing,
357         .ops = NULL,
358 };
359
360 struct lcd_spec lcd_s6d04h0_spec = {
361         .width = 240,
362         .height = 320,
363         .mode = LCD_MODE_MCU,
364         .direction = LCD_DIRECT_NORMAL,
365         .info = {
366                  .mcu = &lcd_s6d04h0_info},
367         .ops = &lcd_s6d04h0_operations,
368 };
369
370 #if 0
371 struct lcd_cfg lcd_s6d04h0 = {
372         .lcd_cs = -1,
373         .lcd_id = 0xC0,         /* RDID3:LCD module ID */
374         .lcd_name = "lcd_s6d04h0",
375         .panel = &lcd_s6d04h0_spec,
376 };
377
378 static int lcd_regulator(void)
379 {
380         int err;
381         struct regulator *lcd_regulator = NULL;
382         struct regulator *lcdio_regulator = NULL;
383         lcd_regulator = regulator_get(NULL, REGU_NAME_LCD);
384         if (IS_ERR(lcd_regulator)) {
385                 pr_err("LCD s6d04h0:could not get lcd regulator\n");
386                 return -1;
387         }
388         err = regulator_enable(lcd_regulator);
389         if (err) {
390                 pr_err("LCD s6d04h0:could not enable lcd regulator\n");
391                 return -1;
392         }
393         err = regulator_set_voltage(lcd_regulator, 3000000, 3000000);
394         if (err)
395                 pr_err("LCD s6d04h0:could not set lcd to 3000mv.\n");
396         lcdio_regulator = regulator_get(NULL, REGU_NAME_LCDIO);
397         if (IS_ERR(lcdio_regulator)) {
398                 pr_err("LCD s6d04h0:could not get lcdio regulator\n");
399                 return -1;
400         }
401         err = regulator_enable(lcdio_regulator);
402         if (err) {
403                 pr_err("LCD s6d04h0:could not enable lcdio regulator\n");
404                 return -1;
405         }
406         err = regulator_set_voltage(lcdio_regulator, 2800000, 2800000);
407         if (err)
408                 pr_err("LCD s6d04h0:could not set lcdio to 1800mv.\n");
409         return 0;
410 }
411
412 static int __init lcd_s6d04h0_init(void)
413 {
414         lcd_regulator();
415         return sprd_register_panel(&lcd_s6d04h0);
416 }
417 #endif
418
419 subsys_initcall(lcd_s6d04h0_init);