tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / video / sprdfb / lcd / lcd_s6d77a1_pikeA_mipi.c
1 /* drivers/video/sprdfb/lcd_s6d77a1_mipi.c\r
2  *\r
3  * Support for s6d77a1 mipi LCD device\r
4  *\r
5  * Copyright (C) 2010 Spreadtrum\r
6  */\r
7 \r
8 #include <asm/arch/sprd_lcd.h>\r
9 #include "../sprdfb.h"\r
10 #define printk printf\r
11 \r
12 #define  LCD_DEBUG\r
13 #ifdef LCD_DEBUG\r
14 #define LCD_PRINT printk\r
15 #else\r
16 #define LCD_PRINT(...)\r
17 #endif\r
18 \r
19 #define MAX_DATA   150\r
20 \r
21 typedef struct LCM_Init_Code_tag {\r
22         unsigned int tag;\r
23         unsigned char data[MAX_DATA];\r
24 }LCM_Init_Code;\r
25 \r
26 typedef struct LCM_force_cmd_code_tag{\r
27         unsigned int datatype;\r
28         LCM_Init_Code real_cmd_code;\r
29 }LCM_Force_Cmd_Code;\r
30 \r
31 #define LCM_TAG_SHIFT 24\r
32 #define LCM_TAG_MASK  ((1 << 24) -1)\r
33 #define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)\r
34 #define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)\r
35 //#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))\r
36 \r
37 #define LCM_TAG_SEND  (1<< 0)\r
38 #define LCM_TAG_SLEEP (1 << 1)\r
39 \r
40 #define PIKEA_J1_NBW_PANEL\r
41 \r
42 \r
43 static LCM_Init_Code init_data[] = {\r
44 \r
45 #ifndef PIKEA_J1_NBW_PANEL\r
46 \r
47         {LCM_SEND(1),{0x11}},\r
48         {LCM_SEND(5),{3,0,0xF0,0x5A,0x5A}},\r
49         {LCM_SEND(5),{3,0,0xFC,0xA5,0xA5}},\r
50         {LCM_SEND(5),{3,0,0xF1,0x5A,0xA5}},\r
51 \r
52                 {LCM_SEND(2),{0xB3, 0x01}},\r
53                 {LCM_SEND(2),{0xB5, 0x10}},\r
54                 {LCM_SEND(6),{4,0,0xBC,0x01,0x29,0x51}}, /* 141006 Battery detect function disabled */\r
55 \r
56                 /* MIPI SETTING */\r
57                 {LCM_SEND(5),{3,0,0xE3,0x24,0x2C}},\r
58 \r
59                 /* Display Inversion Off */\r
60                 {LCM_SEND(1),{0x21}},\r
61 \r
62                 /* Display Control */\r
63                 {LCM_SEND(10), {8,0,0xF2,0x11,0x04,0x08,0x10,0x10,0x82,0x54}},\r
64 \r
65                 /* power control 1 */\r
66                 {LCM_SEND(8),{6,0,0xF3,0x91,0x00,0x00,0x00,0x10}},\r
67 \r
68                 /* power control 2 */\r
69                 {LCM_SEND(46),{44,0,0xF4,0x01,0x02,0x23,0x24,0x25,0x25,0x26,0x26,0x29,0x29,0x2C,0x2B,0x2C,0x07,0x08,0x05,0x04,0x04,0x01,0x01,0x22,0x0A,0x17,0x0F,0x11,0x23,0x0D,0x0A,0x0B,0x02,0x19,0x13,0x1E,0x1F,0x23,0x20,0x05,0x16,0x1A,0x16,0x1E,0x24,0x1E}},\r
70 \r
71                 /* power control 3 */\r
72                 {LCM_SEND(31),{29,0,0xF5,0x28,0x28,0xB9,0x21,0x35,0x55,0x36,0x0A,0x00,0x39,0x00,0x00,0x0B,0x4B,0xC4,0xCB,0x4B,0x12,0x12,0x1A,0x00,0x10,0xE0,0xE2,0x0E,0x34,0x34,0x03}},\r
73 \r
74                 /* 9.4 */\r
75                 {LCM_SEND(20),{18,0,0xFE,0x00,0x02,0x01,0x39,0x60,0x40,0x21,0x00,0x4B,0x00,0x80,0x00,0xF0,0x00,0x00,0x00,0x02}},\r
76 \r
77                 /* ASG EQ Control */\r
78                 {LCM_SEND(13),{11,0,0xEE,0x00,0xA8,0x00,0xA8,0x00,0x00,0x00,0x00,0x00,0x00}},\r
79 \r
80                 {LCM_SEND(24),{22,0,0xEF,0x23,0x01,0x00,0x00,0x2A,0x49,0x08,0x27,0x21,0x40,0x10,0x28,0x02,0x21,0x21,0x03,0x03,0x40,0x00,0x08,0x00}},\r
81 \r
82                 /* Panel Gate Control */\r
83                 {LCM_SEND(33),{31,0,0xF7,0x02,0x1B,0x0D,0x0D,0x09,0x09,0x0C,0x0C,0x08,0x08,0x04,0x06,0x1A,0x02,0x02,0x02,0x1B,0x0F,0x0F,0x0B,0x0B,0x0E,0x0E,0x0A,0x0A,0x05,0x07,0x1A,0x02,0x02}},\r
84 \r
85                 /* Source Control */\r
86                 {LCM_SEND(9),{7,0,0xF6,0x63,0x25,0x15,0x00,0x00,0x2A}},\r
87 \r
88                 /* Memory Data Access Control */\r
89                 {LCM_SEND(2),{0x36,0x10}},\r
90 \r
91                 /* Positive Gamma Control */\r
92                 {LCM_SEND(20),{18,0,0xFA,0x0C,0x36,0x11,0x17,0x0E,0x14,0x19,0x18,0x1A,0x21,0x23,0x22,0x22,0x21,0x22,0x22,0x29}},\r
93 \r
94                 /* Negative Gamma Control */\r
95                 {LCM_SEND(20),{18,0,0xFB,0x0C,0x36,0x12,0x17,0x0F,0x14,0x19,0x18,0x1A,0x21,0x24,0x22,0x23,0x21,0x22,0x22,0x29}},\r
96 \r
97                 /* display on */\r
98                 {LCM_SEND(1),{0x11}},\r
99                 {LCM_SLEEP(120)},\r
100 \r
101                 {LCM_SEND(1),{0x29}},\r
102                 {LCM_SLEEP(120)},\r
103 #else\r
104         \r
105         {LCM_SEND(5),           {3, 0x00, 0xF0, 0x5A, 0x5A} },  \r
106         {LCM_SEND(5),           {3, 0x00, 0xFC, 0xA5, 0xA5} },  \r
107         {LCM_SEND(2),           {0xB3, 0x01} },  \r
108         {LCM_SEND(2),           {0xB5, 0x10} },  \r
109         {LCM_SEND(6),           {4, 0x00, 0xBC, 0x00, 0x29, 0x51} },\r
110         {LCM_SEND(5),           {3, 0x00, 0xE3, 0x24, 0x2C} },\r
111         {LCM_SEND(1),           {0x21} },\r
112         {LCM_SEND(10),          {8, 0x00, 0xF2, 0x11, 0x04, 0x08, 0x10, 0x10, 0x82, 0x54} },\r
113         {LCM_SEND(8),           {6, 0x00, 0xF3, 0x91, 0x00, 0x00, 0x00, 0x10} },\r
114         {LCM_SEND(46),          {44, 0x00, 0xF4, 0x01, 0x02, 0x23, 0x24, 0x25, 0x25, 0x26, 0x26, 0x29, 0x29, 0x2C, 0x2B, 0x2C,\r
115                         0x07, 0x08, 0x05, 0x04, 0x04, 0x01, 0x01, 0x22, 0x0A, 0x17, 0x0F, 0x11, 0x23, 0x0D, 0x0A, 0x0B,\r
116                         0x02, 0x19, 0x13, 0x1E, 0x1F, 0x23, 0x20, 0x05, 0x16, 0x1A, 0x16, 0x1E, 0x24, 0x1E} },\r
117         {LCM_SEND(31),          {29, 0x00, 0xF5, 0x5A, 0x62, 0xB9, 0x21, 0x35, 0x55, 0x06, 0x08, 0x00, 0x39, 0x00, 0x00, 0x0B,\r
118                         0x4B, 0xC4, 0xCB, 0x4B, 0x12, 0x12, 0x1A, 0x00, 0x10, 0xE0, 0xE2, 0x0E, 0x34, 0x34, 0x03} },\r
119         {LCM_SEND(20),          {18, 0x00, 0xFE, 0x00, 0x02, 0x01, 0x39, 0x60, 0x40, 0x21, 0x00, 0x4B, 0x00, 0x80, 0x00, 0xF0,\r
120                         0x00, 0x00, 0x00, 0x02} },\r
121         {LCM_SEND(13),          {11, 0x00, 0xEE, 0x86, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },\r
122         {LCM_SEND(24),          {22, 0x00, 0xEF, 0x34, 0x12, 0x00, 0x00, 0x0A, 0x29, 0x08, 0x27, 0x21, 0x40, 0x10, 0x28, 0x02,\r
123                          0x21, 0x21, 0x03, 0x03, 0x40, 0x00, 0x00, 0x00} }, \r
124         {LCM_SEND(33),          {31, 0x00, 0xF7, 0x02, 0x1B, 0x1A, 0x00, 0x01, 0x0D, 0x0D, 0x09, 0x09, 0x0C, 0x0C, 0x08, 0x08,\r
125                         0x04, 0x06, 0x02, 0x1B, 0x1A, 0x00, 0x01, 0x0F, 0x0F, 0x0B, 0x0B, 0x0E, 0x0E, 0x0A, 0x0A, 0x05, 0x07} },\r
126         {LCM_SEND(9),           {7, 0x00, 0xF6, 0x63, 0x25, 0x15, 0x00, 0x00, 0x2E} },  \r
127         {LCM_SEND(2),           {0x36, 0x10} },\r
128         {LCM_SEND(20),          {18, 0x00, 0xFA, 0x00, 0x3F, 0x09, 0x10, 0x08, 0x0D, 0x12, 0x12, 0x12, 0x18, 0x1B, 0x1B, 0x1D, 0x1E, 0x21, 0x25, 0x2D} },\r
129         {LCM_SEND(20),          {18, 0x00, 0xFB, 0x00, 0x3F, 0x09, 0x11, 0x08, 0x0E, 0x13, 0x12, 0x13, 0x19, 0x1B, 0x1C, 0x1D, 0x1E, 0x21, 0x25, 0x2D} },\r
130         {LCM_SEND(10),          {8, 0x00, 0xFD, 0x00, 0x10, 0x11, 0x20, 0x21, 0x1F, 0xCC} },\r
131         {LCM_SEND(5),           {3, 0x00, 0xFC, 0x5A, 0x5A} },\r
132 /* display on */\r
133         {LCM_SEND(1),{0x11}},\r
134         {LCM_SLEEP(120)},\r
135         {LCM_SEND(1),{0x29}},\r
136         {LCM_SLEEP(120)},\r
137 #endif\r
138 \r
139 };\r
140 \r
141 static LCM_Init_Code disp_on =  {LCM_SEND(1), {0x29}};\r
142 \r
143 static LCM_Init_Code sleep_in[] =  {\r
144         {LCM_SEND(1), {0x28}},\r
145         {LCM_SLEEP(150)},       //>150ms\r
146         {LCM_SEND(1), {0x10}},\r
147         {LCM_SLEEP(150)},       //>150ms\r
148 };\r
149 \r
150 static LCM_Init_Code sleep_out[] =  {\r
151         {LCM_SEND(1), {0x11}},\r
152         {LCM_SLEEP(120)},//>120ms\r
153         {LCM_SEND(1), {0x29}},\r
154         {LCM_SLEEP(20)}, //>20ms\r
155 };\r
156 \r
157 extern void (*lcd_panel_cabc_pwm_bl)(int brightness);\r
158 extern void backlight_control(int brigtness);\r
159 static int32_t s6d77a1_mipi_init(struct panel_spec *self)\r
160 {\r
161         int32_t i = 0;\r
162         LCM_Init_Code *init = init_data;\r
163         unsigned int tag;\r
164 \r
165         lcd_panel_cabc_pwm_bl = backlight_control;\r
166 \r
167         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
168         mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;\r
169         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
170 \r
171         LCD_PRINT("lcd_s6d77a1_init\n");\r
172 \r
173         mipi_set_cmd_mode();\r
174         mipi_eotp_set(0,0);\r
175 \r
176         for(i = 0; i < ARRAY_SIZE(init_data); i++){\r
177                 tag = (init->tag >>24);\r
178                 if(tag & LCM_TAG_SEND){\r
179                         mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));\r
180                         udelay(20);\r
181                 }else if(tag & LCM_TAG_SLEEP){\r
182                         mdelay(init->tag & LCM_TAG_MASK);//udelay((init->tag & LCM_TAG_MASK) * 1000);\r
183                 }\r
184                 init++;\r
185         }\r
186         mipi_eotp_set(0,0);\r
187 \r
188         return 0;\r
189 }\r
190 \r
191 static uint32_t s6d77a1_readid(struct panel_spec *self)\r
192 {\r
193         uint32 j =0;\r
194         uint8_t read_data[4] = {0};\r
195         int32_t read_rtn = 0;\r
196         uint8_t param[2] = {0};\r
197         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
198         mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;\r
199         mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;\r
200         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
201 \r
202         LCD_PRINT("lcd_s6d77a1_mipi read id!\n");\r
203 \r
204         mipi_set_cmd_mode();\r
205         mipi_eotp_set(0,0);\r
206 \r
207         for(j = 0; j < 4; j++){\r
208                 param[0] = 0x03;\r
209                 param[1] = 0x00;\r
210                 mipi_force_write(0x37, param, 2);\r
211                 read_rtn = mipi_force_read(0x04, 3, read_data);\r
212                 LCD_PRINT("lcd_s6d77a1_mipi read id 0xda, 0xdb,0xdc is 0x%x,0x%x,0x%x!\n",\r
213                                 read_data[0], read_data[1], read_data[2]);\r
214                 if ((0x55 == read_data[0]) && (0xB8 == read_data[1])\r
215                                 && (0x10 == read_data[2])) {\r
216                         LCD_PRINT("lcd_s6d77a1_mipi read id success!\n");\r
217                         return 0x55b810;\r
218                 }\r
219         }\r
220 \r
221         mipi_eotp_set(0,0);\r
222 \r
223         LCD_PRINT("lcd_s6d77a1_mipi read id failed!\n");\r
224 //      return 0;\r
225         return 0x55b810; //to fix me\r
226 }\r
227 \r
228 static struct panel_operations lcd_s6d77a1_mipi_operations = {\r
229         .panel_init = s6d77a1_mipi_init,\r
230         .panel_readid = s6d77a1_readid,\r
231 };\r
232 \r
233 static struct timing_rgb lcd_s6d77a1_mipi_timing = {\r
234         .hfp = 84,  /* unit: pixel */\r
235         .hbp = 90,\r
236         .hsync = 40,\r
237         .vfp = 16, /* unit: line */\r
238         .vbp = 12,\r
239         .vsync = 4,\r
240 };\r
241 \r
242 \r
243 static struct info_mipi lcd_s6d77a1_mipi_info = {\r
244         .work_mode  = SPRDFB_MIPI_MODE_VIDEO,\r
245         .video_bus_width = 24, /*18,16*/\r
246         .lan_number =   2,\r
247         .phy_feq =481*1000,\r
248         .h_sync_pol = SPRDFB_POLARITY_POS,\r
249         .v_sync_pol = SPRDFB_POLARITY_POS,\r
250         .de_pol = SPRDFB_POLARITY_POS,\r
251         .te_pol = SPRDFB_POLARITY_POS,\r
252         .color_mode_pol = SPRDFB_POLARITY_NEG,\r
253         .shut_down_pol = SPRDFB_POLARITY_NEG,\r
254         .timing = &lcd_s6d77a1_mipi_timing,\r
255         .ops = NULL,\r
256 };\r
257 \r
258 struct panel_spec lcd_s6d77a1_mipi_spec = {\r
259         .width = 480,\r
260         .height = 800,\r
261         .fps = 60,\r
262         .type = LCD_MODE_DSI,\r
263         .direction = LCD_DIRECT_NORMAL,\r
264         .info = {\r
265                 .mipi = &lcd_s6d77a1_mipi_info\r
266         },\r
267         .ops = &lcd_s6d77a1_mipi_operations,\r
268 };\r