tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / video / sprdfb / lcd / lcd_hx8369b_mipi_kiran3g.c
1 /* drivers/video/sprdfb/lcd_hx8369b_mipi.c\r
2  *\r
3  * Support for hx8369b 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 LCD_NEW_PANEL\r
41 \r
42 \r
43 static LCM_Init_Code init_data[] = {\r
44 \r
45 #ifndef LCD_NEW_PANEL\r
46         {LCM_SEND(6),{4,0,0xB9,0xFF,0x83,0x69}},\r
47         {LCM_SEND(13),{11,0,0xB1,0x0B,0x83,0x77,0x00,0x11,0x11,0x08,0x08,0x0C,0x12}},\r
48         {LCM_SEND(7),{5,0,0xC6,0x41,0xFF,0x7A,0xFF}},\r
49         {LCM_SEND(7),{5,0,0xE3,0x00,0x00,0x00,0x00}},\r
50         {LCM_SEND(9),{7,0,0xC0,0x73,0x50,0x00,0x34,0xC4,0x00}},\r
51         {LCM_SEND(18),{16,0,0xBA,0x31,0x00,0x16,0xCA,0xB0,0x0A,0x00,0x10,0x28,0x02,0x21,0x21,0x9A,0x1A,0x8F}},\r
52         {LCM_SEND(2),{0x3A,0x70}},\r
53         {LCM_SEND(10),{8,0,0xB3,0x83,0x00,0x31,0x03,0x01,0x13,0x06}},\r
54         {LCM_SEND(2),{0xB4,0x00}},\r
55         {LCM_SEND(2),{0xCC,0x0C}},\r
56         {LCM_SEND(2),{0xEA,0x72}},\r
57         {LCM_SEND(2),{0xB2,0x03}},\r
58 \r
59         //set GIP timing control\r
60         {LCM_SEND(95),{93, 0, 0xD5,\r
61                 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x12, 0x40, 0x00,\\r
62                 0x00, 0x00, 0x01, 0x60, 0x37, 0x00, 0x00, 0x0F, 0x01, 0x02,\\r
63                 0x47, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\\r
64                 0x00, 0x00, 0x03, 0x00, 0x00, 0x18, 0x00, 0x00, 0x89, 0x00,\\r
65                 0x11, 0x33, 0x55, 0x77, 0x31, 0x00, 0x00, 0x98, 0x00, 0x66,\\r
66                 0x44, 0x22, 0x00, 0x02, 0x00, 0x00, 0x89, 0x00, 0x00, 0x22,\\r
67                 0x44, 0x66, 0x20, 0x00, 0x00, 0x98, 0x00, 0x77, 0x55, 0x33,\\r
68                 0x11, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,\\r
69                 0x00, 0xCF, 0xFF, 0xFF, 0x03, 0x00, 0xCF, 0xFF, 0xFF, 0x20,\\r
70                 0x8C, 0x5A}},\r
71 \r
72         //gamma setting\r
73         {LCM_SEND(38),{36, 0, 0xE0,\r
74                 0x00, 0x00, 0x00, 0x0D, 0x0C, 0x3F, 0x18, 0x2C, 0x04, 0x0F,\\r
75                 0x0E, 0x14, 0x17, 0x15, 0x16, 0x10, 0x13, 0x00, 0x00, 0x00,\\r
76                 0x0C, 0x12, 0x3F, 0x17, 0x2C, 0x05, 0x08, 0x0E, 0x12, 0x16,\\r
77                 0x14, 0x15, 0x11, 0x13, 0x01}},\r
78         {LCM_SEND(130),{128, 0, 0xC1,\r
79                 0x01, 0x00, 0x08, 0x10, 0x18, 0x1F, 0x27, 0x2E, 0x34, 0x3E,\\r
80                 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78, 0x80, 0x88, 0x90,\\r
81                 0x98, 0xA0, 0xA8, 0xB0, 0xB8, 0xC0, 0xC8, 0xD0, 0xD8, 0xE0,\\r
82                 0xE8, 0xF0, 0xF7, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\\r
83                 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x18, 0x1F, 0x27, 0x2E,\\r
84                 0x34, 0x3E, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78, 0x80,\\r
85                 0x88, 0x90, 0x98, 0xA0, 0xA8, 0xB0, 0xB8, 0xC0, 0xC8, 0xD0,\\r
86                 0xD8, 0xE0, 0xE8, 0xF0, 0xF7, 0xFF, 0x00, 0x00, 0x00, 0x00,\\r
87                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x18, 0x1F,\\r
88                 0x27, 0x2E, 0x34, 0x3E, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70,\\r
89                 0x78, 0x80, 0x88, 0x90, 0x98, 0xA0, 0xA8, 0xB0, 0xB8, 0xC0,\\r
90                 0xC8, 0xD0, 0xD8, 0xE0, 0xE8, 0xF0, 0xF7, 0xFF, 0x00, 0x00,\\r
91                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},\r
92 \r
93         {LCM_SEND(1),{0x11}},\r
94         {LCM_SLEEP(120)},\r
95         {LCM_SEND(1),{0x29}},\r
96 #else\r
97         /* Password */\r
98         {LCM_SEND(5),{3,0,0xF0,0x5A,0x5A}},\r
99                 {LCM_SEND(5),{3,0,0xF1,0x5A,0x5A}},\r
100                 {LCM_SEND(5),{3,0,0xFC,0xA5,0xA5}},\r
101 \r
102                 /* Resolution Control */\r
103                 {LCM_SEND(2),{0xB3, 0x01}},\r
104                 {LCM_SEND(2),{0xB5, 0x10}},\r
105                 {LCM_SEND(6),{4,0,0xBC,0x00,0x29,0x51}}, /* 141006 Battery detect function disabled */\r
106 \r
107                 /* MIPI SETTING */\r
108                 {LCM_SEND(5),{3,0,0xE3,0x24,0x2C}},\r
109 \r
110                 /* Display Inversion Off */\r
111                 {LCM_SEND(1),{0x21}},\r
112 \r
113                 /* Display Control */\r
114                 {LCM_SEND(11), {9,0,0xF2,0x11,0x04,0x08,0x10,0x10,0x72,0x4A,0x0A}},\r
115 \r
116                 /* power control 1 */\r
117                 {LCM_SEND(8),{6,0,0xF3,0x91,0x00,0x00,0x00,0x10}},\r
118 \r
119                 /* power control 2 */\r
120                 {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
121 \r
122                 /* power control 3 */\r
123                 {LCM_SEND(31),{29,0,0xF5,0x14,0x14,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
124 \r
125                 /* 9.4 */\r
126                 {LCM_SEND(20),{18,0,0xFE,0x00,0x02,0x01,0x39,0x60,0x40,0x21,0x00,0x4B,0x00,0x80,0x00,0xF0,0x00,0x00,0x00,0x06}},\r
127 \r
128                 /* ASG EQ Control */\r
129                 {LCM_SEND(13),{11,0,0xEE,0x40,0xA0,0x40,0xA0,0x00,0x00,0x00,0x00,0x00,0x00}},\r
130 \r
131                 {LCM_SEND(23),{21,0,0xEF,0x23,0x01,0x00,0x00,0x2A,0x49,0x08,0x27,0x21,0x40,0x10,0x24,0x02,0x21,0x21,0x03,0x03,0x40,0x00,0x08}},\r
132 \r
133                 /* Panel Gate Control */\r
134                 {LCM_SEND(33),{31,0,0xF7,0x02,0x1B,0x1A,0x00,0x01,0x0E,0x0E,0x0A,0x0A,0x0F,0x0F,0x0B,0x0B,0x05,0x07,0x02,0x1B,0x1A,0x00,0x01,0x0C,0x0C,0x08,0x08,0x0D,0x0D,0x09,0x09,0x04,0x06}},\r
135 \r
136                 /* Source Control */\r
137                 {LCM_SEND(9),{7,0,0xF6,0x63,0x25,0x15,0x00,0x00,0x20}},\r
138 \r
139                 /* Memory Data Access Control */\r
140                 {LCM_SEND(2),{0x36,0x10}},\r
141 \r
142                 /* Positive Gamma Control */\r
143                 {LCM_SEND(20),{18,0,0xFA,0x0C,0x36,0x0B,0x10,0x07,0x0C,0x10,0x10,0x14,0x1D,0x1F,0x1F,0x20,0x21,0x22,0x25,0x2F}},\r
144 \r
145                 /* Negative Gamma Control */\r
146                 {LCM_SEND(20),{18,0,0xFB,0x0C,0x36,0x0B,0x10,0x07,0x0C,0x10,0x0E,0x0E,0x15,0x1B,0x1E,0x20,0x1F,0x20,0x25,0x2F}},\r
147 \r
148                 /* display on */\r
149                 {LCM_SEND(1),{0x11}},\r
150                 {LCM_SLEEP(120)},\r
151 \r
152                 {LCM_SEND(1),{0x29}},\r
153                 {LCM_SLEEP(120)},\r
154 #endif\r
155 \r
156 };\r
157 \r
158 static LCM_Init_Code disp_on =  {LCM_SEND(1), {0x29}};\r
159 \r
160 static LCM_Init_Code sleep_in[] =  {\r
161         {LCM_SEND(1), {0x28}},\r
162         {LCM_SLEEP(150)},       //>150ms\r
163         {LCM_SEND(1), {0x10}},\r
164         {LCM_SLEEP(150)},       //>150ms\r
165 };\r
166 \r
167 static LCM_Init_Code sleep_out[] =  {\r
168         {LCM_SEND(1), {0x11}},\r
169         {LCM_SLEEP(120)},//>120ms\r
170         {LCM_SEND(1), {0x29}},\r
171         {LCM_SLEEP(20)}, //>20ms\r
172 };\r
173 \r
174 extern void (*lcd_panel_cabc_pwm_bl)(int brightness);\r
175 extern void backlight_control(int brigtness);\r
176 static int32_t hx8369b_mipi_init(struct panel_spec *self)\r
177 {\r
178         int32_t i = 0;\r
179         LCM_Init_Code *init = init_data;\r
180         unsigned int tag;\r
181 \r
182         lcd_panel_cabc_pwm_bl = backlight_control;\r
183 \r
184         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
185         mipi_dcs_write_t mipi_dcs_write = self->info.mipi->ops->mipi_dcs_write;\r
186         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
187 \r
188         LCD_PRINT("lcd_hx8369b_init\n");\r
189 \r
190         mipi_set_cmd_mode();\r
191         mipi_eotp_set(0,0);\r
192 \r
193         for(i = 0; i < ARRAY_SIZE(init_data); i++){\r
194                 tag = (init->tag >>24);\r
195                 if(tag & LCM_TAG_SEND){\r
196                         mipi_dcs_write(init->data, (init->tag & LCM_TAG_MASK));\r
197                         udelay(20);\r
198                 }else if(tag & LCM_TAG_SLEEP){\r
199                         mdelay(init->tag & LCM_TAG_MASK);//udelay((init->tag & LCM_TAG_MASK) * 1000);\r
200                 }\r
201                 init++;\r
202         }\r
203         mipi_eotp_set(0,0);\r
204 \r
205         return 0;\r
206 }\r
207 \r
208 static uint32_t hx8369b_readid(struct panel_spec *self)\r
209 {\r
210         uint32 j =0;\r
211         uint8_t read_data[4] = {0};\r
212         int32_t read_rtn = 0;\r
213         uint8_t param[2] = {0};\r
214         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
215         mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;\r
216         mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;\r
217         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
218 \r
219         LCD_PRINT("lcd_hx8369b_mipi read id!\n");\r
220 \r
221         mipi_set_cmd_mode();\r
222         mipi_eotp_set(0,0);\r
223 \r
224         for(j = 0; j < 4; j++){\r
225 #ifndef LCD_NEW_PANEL\r
226                 param[0] = 0x01;\r
227                 param[1] = 0x00;\r
228                 mipi_force_write(0x37, param, 2);\r
229                 read_rtn = mipi_force_read(0xda,1,&read_data[0]);\r
230                 LCD_PRINT("lcd_hx8369b_mipi read id 0xda value is 0x%x!\n",read_data[0]);\r
231 \r
232                 read_rtn = mipi_force_read(0xdb,1,&read_data[1]);\r
233                 LCD_PRINT("lcd_hx8369b_mipi read id 0xdb value is 0x%x!\n",read_data[1]);\r
234 \r
235                 read_rtn = mipi_force_read(0xdc,1,&read_data[2]);\r
236                 LCD_PRINT("lcd_hx8369b_mipi read id 0xdc value is 0x%x!\n",read_data[2]);\r
237 \r
238                 if((0x55 == read_data[0])&&(0xbf == read_data[1] || 0xc0 == read_data[1] || 0xbe == read_data[1])&&(0x90 == read_data[2])){\r
239                                 LCD_PRINT("lcd_hx8369b_mipi read id success!\n");\r
240                                 return 0x8369;\r
241                 }\r
242 #else\r
243                 param[0] = 0x03;\r
244                 param[1] = 0x00;\r
245                 mipi_force_write(0x37, param, 2);\r
246                 read_rtn = mipi_force_read(0x04, 3, read_data);\r
247                 LCD_PRINT("lcd_s6d77a1_mipi read id 0xda, 0xdb,0xdc is 0x%x,0x%x,0x%x!\n",\r
248                                 read_data[0], read_data[1], read_data[2]);\r
249                 if ((0x55 == read_data[0]) && (0xB8 == read_data[1])\r
250                                 && (0x10 == read_data[2])) {\r
251                         LCD_PRINT("lcd_s6d77a1_mipi read id success!\n");\r
252                         return 0x8369;\r
253                 }\r
254 #endif\r
255         }\r
256 \r
257         mipi_eotp_set(0,0);\r
258 \r
259         LCD_PRINT("lcd_s6d77a1_mipi read id failed!\n");\r
260         return 0;\r
261 }\r
262 \r
263 static struct panel_operations lcd_hx8369b_mipi_operations = {\r
264         .panel_init = hx8369b_mipi_init,\r
265         .panel_readid = hx8369b_readid,\r
266 };\r
267 \r
268 static struct timing_rgb lcd_hx8369b_mipi_timing = {\r
269 #ifndef LCD_NEW_PANEL\r
270         .hfp = 115,  /* unit: pixel */\r
271         .hbp = 55,\r
272         .hsync = 4,\r
273         .vfp = 6, /*unit: line*/\r
274         .vbp = 19,\r
275         .vsync = 4,\r
276 #else\r
277         .hfp = 74,  /* unit: pixel */\r
278         .hbp = 88,\r
279         .hsync = 26,\r
280         .vfp = 16, /* unit: line */\r
281         .vbp = 12,\r
282         .vsync = 4,\r
283 #endif\r
284 };\r
285 \r
286 \r
287 static struct info_mipi lcd_hx8369b_mipi_info = {\r
288         .work_mode  = SPRDFB_MIPI_MODE_VIDEO,\r
289         .video_bus_width = 24, /*18,16*/\r
290         .lan_number =   2,\r
291         .phy_feq =481*1000,\r
292         .h_sync_pol = SPRDFB_POLARITY_POS,\r
293         .v_sync_pol = SPRDFB_POLARITY_POS,\r
294         .de_pol = SPRDFB_POLARITY_POS,\r
295         .te_pol = SPRDFB_POLARITY_POS,\r
296         .color_mode_pol = SPRDFB_POLARITY_NEG,\r
297         .shut_down_pol = SPRDFB_POLARITY_NEG,\r
298         .timing = &lcd_hx8369b_mipi_timing,\r
299         .ops = NULL,\r
300 };\r
301 \r
302 struct panel_spec lcd_hx8369b_mipi_spec = {\r
303         .width = 480,\r
304         .height = 800,\r
305         .fps = 60,\r
306         .type = LCD_MODE_DSI,\r
307         .direction = LCD_DIRECT_NORMAL,\r
308         .info = {\r
309                 .mipi = &lcd_hx8369b_mipi_info\r
310         },\r
311         .ops = &lcd_hx8369b_mipi_operations,\r
312 };\r