1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "lcd.h"
6 #include <ddk/debug.h>
7 #include <ddk/protocol/platform/device.h>
8 #include <ddktl/device.h>
9 
10 #define DELAY_CMD           (0xFF)
11 #define DCS_CMD             (0xFE)
12 #define GEN_CMD             (0xFD)
13 
14 #define READ_DISPLAY_ID_CMD (0x04)
15 #define READ_DISPLAY_ID_LEN (0x03)
16 
17 namespace astro_display {
18 
19 namespace {
20 // Based on Vendor datasheet
21 // <CMD TYPE><LENGTH><DATA...>
22 // <DELAY_CMD><DELAY (ms)>
23 constexpr uint8_t lcd_shutdown_sequence[] = {
24     DELAY_CMD,5,
25     DCS_CMD,1,0x28,
26     DELAY_CMD, 30,
27     DCS_CMD,1,0x10,
28     DELAY_CMD,150,
29 };
30 
31 constexpr uint8_t lcd_init_sequence_TV070WSM_FT[] = {
32     GEN_CMD,2,0xE0,0x00,
33     GEN_CMD,2,0xE1,0x93,
34     GEN_CMD,2,0xE2,0x65,
35     GEN_CMD,2,0xE3,0xF8,
36     GEN_CMD,2,0xE0,0x01,
37     GEN_CMD,2,0x00,0x00,
38     GEN_CMD,2,0x01,0x90,
39     GEN_CMD,2,0x03,0x00,
40     GEN_CMD,2,0x04,0x90,
41     GEN_CMD,2,0x17,0x00,
42     GEN_CMD,2,0x18,0xB0,
43     GEN_CMD,2,0x19,0x01,
44     GEN_CMD,2,0x1A,0x00,
45     GEN_CMD,2,0x1B,0xB0,
46     GEN_CMD,2,0x1C,0x01,
47     GEN_CMD,2,0x1F,0x3E,
48     GEN_CMD,2,0x20,0x2F,
49     GEN_CMD,2,0x21,0x2F,
50     GEN_CMD,2,0x22,0x0E,
51     GEN_CMD,2,0x37,0x69,
52     GEN_CMD,2,0x38,0x05,
53     GEN_CMD,2,0x39,0x00,
54     GEN_CMD,2,0x3A,0x01,
55     GEN_CMD,2,0x3C,0x90,
56     GEN_CMD,2,0x3D,0xFF,
57     GEN_CMD,2,0x3E,0xFF,
58     GEN_CMD,2,0x3F,0xFF,
59     GEN_CMD,2,0x40,0x02,
60     GEN_CMD,2,0x41,0x80,
61     GEN_CMD,2,0x42,0x99,
62     GEN_CMD,2,0x43,0x06,
63     GEN_CMD,2,0x44,0x09,
64     GEN_CMD,2,0x45,0x3C,
65     GEN_CMD,2,0x4B,0x04,
66     GEN_CMD,2,0x55,0x0D,
67     GEN_CMD,2,0x56,0x01,
68     GEN_CMD,2,0x57,0x89,
69     GEN_CMD,2,0x58,0x0A,
70     GEN_CMD,2,0x59,0x0A,
71     GEN_CMD,2,0x5A,0x27,
72     GEN_CMD,2,0x5B,0x15,
73     GEN_CMD,2,0x5D,0x7C,
74     GEN_CMD,2,0x5E,0x67,
75     GEN_CMD,2,0x5F,0x58,
76     GEN_CMD,2,0x60,0x4C,
77     GEN_CMD,2,0x61,0x48,
78     GEN_CMD,2,0x62,0x38,
79     GEN_CMD,2,0x63,0x3C,
80     GEN_CMD,2,0x64,0x24,
81     GEN_CMD,2,0x65,0x3B,
82     GEN_CMD,2,0x66,0x38,
83     GEN_CMD,2,0x67,0x36,
84     GEN_CMD,2,0x68,0x53,
85     GEN_CMD,2,0x69,0x3F,
86     GEN_CMD,2,0x6A,0x44,
87     GEN_CMD,2,0x6B,0x35,
88     GEN_CMD,2,0x6C,0x2E,
89     GEN_CMD,2,0x6D,0x1F,
90     GEN_CMD,2,0x6E,0x0C,
91     GEN_CMD,2,0x6F,0x00,
92     GEN_CMD,2,0x70,0x7C,
93     GEN_CMD,2,0x71,0x67,
94     GEN_CMD,2,0x72,0x58,
95     GEN_CMD,2,0x73,0x4C,
96     GEN_CMD,2,0x74,0x48,
97     GEN_CMD,2,0x75,0x38,
98     GEN_CMD,2,0x76,0x3C,
99     GEN_CMD,2,0x77,0x24,
100     GEN_CMD,2,0x78,0x3B,
101     GEN_CMD,2,0x79,0x38,
102     GEN_CMD,2,0x7A,0x36,
103     GEN_CMD,2,0x7B,0x53,
104     GEN_CMD,2,0x7C,0x3F,
105     GEN_CMD,2,0x7D,0x44,
106     GEN_CMD,2,0x7E,0x35,
107     GEN_CMD,2,0x7F,0x2E,
108     GEN_CMD,2,0x80,0x1F,
109     GEN_CMD,2,0x81,0x0C,
110     GEN_CMD,2,0x82,0x00,
111     GEN_CMD,2,0xE0,0x02,
112     GEN_CMD,2,0x00,0x45,
113     GEN_CMD,2,0x01,0x45,
114     GEN_CMD,2,0x02,0x47,
115     GEN_CMD,2,0x03,0x47,
116     GEN_CMD,2,0x04,0x41,
117     GEN_CMD,2,0x05,0x41,
118     GEN_CMD,2,0x06,0x1F,
119     GEN_CMD,2,0x07,0x1F,
120     GEN_CMD,2,0x08,0x1F,
121     GEN_CMD,2,0x09,0x1F,
122     GEN_CMD,2,0x0A,0x1F,
123     GEN_CMD,2,0x0B,0x1F,
124     GEN_CMD,2,0x0C,0x1F,
125     GEN_CMD,2,0x0D,0x1D,
126     GEN_CMD,2,0x0E,0x1D,
127     GEN_CMD,2,0x0F,0x1D,
128     GEN_CMD,2,0x10,0x1F,
129     GEN_CMD,2,0x11,0x1F,
130     GEN_CMD,2,0x12,0x1F,
131     GEN_CMD,2,0x13,0x1F,
132     GEN_CMD,2,0x14,0x1F,
133     GEN_CMD,2,0x15,0x1F,
134     GEN_CMD,2,0x16,0x44,
135     GEN_CMD,2,0x17,0x44,
136     GEN_CMD,2,0x18,0x46,
137     GEN_CMD,2,0x19,0x46,
138     GEN_CMD,2,0x1A,0x40,
139     GEN_CMD,2,0x1B,0x40,
140     GEN_CMD,2,0x1C,0x1F,
141     GEN_CMD,2,0x1D,0x1F,
142     GEN_CMD,2,0x1E,0x1F,
143     GEN_CMD,2,0x1F,0x1F,
144     GEN_CMD,2,0x20,0x1F,
145     GEN_CMD,2,0x21,0x1F,
146     GEN_CMD,2,0x22,0x1F,
147     GEN_CMD,2,0x23,0x1D,
148     GEN_CMD,2,0x24,0x1D,
149     GEN_CMD,2,0x25,0x1D,
150     GEN_CMD,2,0x26,0x1F,
151     GEN_CMD,2,0x27,0x1F,
152     GEN_CMD,2,0x28,0x1F,
153     GEN_CMD,2,0x29,0x1F,
154     GEN_CMD,2,0x2A,0x1F,
155     GEN_CMD,2,0x2B,0x1F,
156     GEN_CMD,2,0x58,0x40,
157     GEN_CMD,2,0x59,0x00,
158     GEN_CMD,2,0x5A,0x00,
159     GEN_CMD,2,0x5B,0x10,
160     GEN_CMD,2,0x5C,0x06,
161     GEN_CMD,2,0x5D,0x20,
162     GEN_CMD,2,0x5E,0x00,
163     GEN_CMD,2,0x5F,0x00,
164     GEN_CMD,2,0x61,0x00,
165     GEN_CMD,2,0x62,0x00,
166     GEN_CMD,2,0x63,0x7A,
167     GEN_CMD,2,0x64,0x7A,
168     GEN_CMD,2,0x65,0x00,
169     GEN_CMD,2,0x66,0x00,
170     GEN_CMD,2,0x67,0x32,
171     GEN_CMD,2,0x68,0x08,
172     GEN_CMD,2,0x69,0x7A,
173     GEN_CMD,2,0x6A,0x7A,
174     GEN_CMD,2,0x6B,0x00,
175     GEN_CMD,2,0x6C,0x00,
176     GEN_CMD,2,0x6D,0x04,
177     GEN_CMD,2,0x6E,0x04,
178     GEN_CMD,2,0x6F,0x88,
179     GEN_CMD,2,0x70,0x00,
180     GEN_CMD,2,0x71,0x00,
181     GEN_CMD,2,0x72,0x06,
182     GEN_CMD,2,0x73,0x7B,
183     GEN_CMD,2,0x74,0x00,
184     GEN_CMD,2,0x75,0x07,
185     GEN_CMD,2,0x76,0x00,
186     GEN_CMD,2,0x77,0x5D,
187     GEN_CMD,2,0x78,0x17,
188     GEN_CMD,2,0x79,0x1F,
189     GEN_CMD,2,0x7A,0x00,
190     GEN_CMD,2,0x7B,0x00,
191     GEN_CMD,2,0x7C,0x00,
192     GEN_CMD,2,0x7D,0x03,
193     GEN_CMD,2,0x7E,0x7B,
194     GEN_CMD,2,0xE0,0x03,
195     GEN_CMD,2,0xAF,0x20,
196     GEN_CMD,2,0xE0,0x04,
197     GEN_CMD,2,0x09,0x11,
198     GEN_CMD,2,0x0E,0x48,
199     GEN_CMD,2,0x2B,0x2B,
200     GEN_CMD,2,0x2E,0x44,
201     GEN_CMD,2,0x41,0xFF,
202     GEN_CMD,2,0xE0,0x00,
203     GEN_CMD,2,0xE6,0x02,
204     GEN_CMD,2,0xE7,0x0C,
205     DCS_CMD,1,0x11,
206     DELAY_CMD,120,
207     GEN_CMD,2,0xE0,0x03,
208     GEN_CMD,2,0x2B,0x01,
209     GEN_CMD,2,0x2C,0x00,
210     GEN_CMD,2,0x30,0x03,
211     GEN_CMD,2,0x31,0xCC,
212     GEN_CMD,2,0x32,0x03,
213     GEN_CMD,2,0x33,0xC9,
214     GEN_CMD,2,0x34,0x03,
215     GEN_CMD,2,0x35,0xC0,
216     GEN_CMD,2,0x36,0x03,
217     GEN_CMD,2,0x37,0xB3,
218     GEN_CMD,2,0x38,0x03,
219     GEN_CMD,2,0x39,0xAB,
220     GEN_CMD,2,0x3A,0x03,
221     GEN_CMD,2,0x3B,0x9D,
222     GEN_CMD,2,0x3C,0x03,
223     GEN_CMD,2,0x3D,0x8F,
224     GEN_CMD,2,0x3E,0x03,
225     GEN_CMD,2,0x3F,0x6D,
226     GEN_CMD,2,0x40,0x03,
227     GEN_CMD,2,0x41,0x51,
228     GEN_CMD,2,0x42,0x03,
229     GEN_CMD,2,0x43,0x17,
230     GEN_CMD,2,0x44,0x02,
231     GEN_CMD,2,0x45,0xD8,
232     GEN_CMD,2,0x46,0x02,
233     GEN_CMD,2,0x47,0x60,
234     GEN_CMD,2,0x48,0x01,
235     GEN_CMD,2,0x49,0xEB,
236     GEN_CMD,2,0x4A,0x01,
237     GEN_CMD,2,0x4B,0xE5,
238     GEN_CMD,2,0x4C,0x01,
239     GEN_CMD,2,0x4D,0x6C,
240     GEN_CMD,2,0x4E,0x00,
241     GEN_CMD,2,0x4F,0xF2,
242     GEN_CMD,2,0x50,0x00,
243     GEN_CMD,2,0x51,0xB4,
244     GEN_CMD,2,0x52,0x00,
245     GEN_CMD,2,0x53,0x74,
246     GEN_CMD,2,0x54,0x00,
247     GEN_CMD,2,0x55,0x54,
248     GEN_CMD,2,0x56,0x00,
249     GEN_CMD,2,0x57,0x34,
250     GEN_CMD,2,0x58,0x00,
251     GEN_CMD,2,0x59,0x26,
252     GEN_CMD,2,0x5A,0x00,
253     GEN_CMD,2,0x5B,0x18,
254     GEN_CMD,2,0x5C,0x00,
255     GEN_CMD,2,0x5D,0x11,
256     GEN_CMD,2,0x5E,0x00,
257     GEN_CMD,2,0x5F,0x0A,
258     GEN_CMD,2,0x60,0x00,
259     GEN_CMD,2,0x61,0x03,
260     GEN_CMD,2,0x62,0x00,
261     GEN_CMD,2,0x63,0x00,
262     GEN_CMD,2,0x64,0x03,
263     GEN_CMD,2,0x65,0x9E,
264     GEN_CMD,2,0x66,0x03,
265     GEN_CMD,2,0x67,0x9B,
266     GEN_CMD,2,0x68,0x03,
267     GEN_CMD,2,0x69,0x94,
268     GEN_CMD,2,0x6A,0x03,
269     GEN_CMD,2,0x6B,0x8C,
270     GEN_CMD,2,0x6C,0x03,
271     GEN_CMD,2,0x6D,0x85,
272     GEN_CMD,2,0x6E,0x03,
273     GEN_CMD,2,0x6F,0x76,
274     GEN_CMD,2,0x70,0x03,
275     GEN_CMD,2,0x71,0x67,
276     GEN_CMD,2,0x72,0x03,
277     GEN_CMD,2,0x73,0x4B,
278     GEN_CMD,2,0x74,0x03,
279     GEN_CMD,2,0x75,0x2E,
280     GEN_CMD,2,0x76,0x02,
281     GEN_CMD,2,0x77,0xF7,
282     GEN_CMD,2,0x78,0x02,
283     GEN_CMD,2,0x79,0xB8,
284     GEN_CMD,2,0x7A,0x02,
285     GEN_CMD,2,0x7B,0x46,
286     GEN_CMD,2,0x7C,0x01,
287     GEN_CMD,2,0x7D,0xD6,
288     GEN_CMD,2,0x7E,0x01,
289     GEN_CMD,2,0x7F,0xD0,
290     GEN_CMD,2,0x80,0x01,
291     GEN_CMD,2,0x81,0x5C,
292     GEN_CMD,2,0x82,0x00,
293     GEN_CMD,2,0x83,0xE7,
294     GEN_CMD,2,0x84,0x00,
295     GEN_CMD,2,0x85,0xAA,
296     GEN_CMD,2,0x86,0x00,
297     GEN_CMD,2,0x87,0x74,
298     GEN_CMD,2,0x88,0x00,
299     GEN_CMD,2,0x89,0x5A,
300     GEN_CMD,2,0x8A,0x00,
301     GEN_CMD,2,0x8B,0x3C,
302     GEN_CMD,2,0x8C,0x00,
303     GEN_CMD,2,0x8D,0x2C,
304     GEN_CMD,2,0x8E,0x00,
305     GEN_CMD,2,0x8F,0x1C,
306     GEN_CMD,2,0x90,0x00,
307     GEN_CMD,2,0x91,0x14,
308     GEN_CMD,2,0x92,0x00,
309     GEN_CMD,2,0x93,0x0C,
310     GEN_CMD,2,0x94,0x00,
311     GEN_CMD,2,0x95,0x04,
312     GEN_CMD,2,0x96,0x00,
313     GEN_CMD,2,0x97,0x00,
314     GEN_CMD,2,0xE0,0x00,
315     DCS_CMD,1,0x29,
316     DELAY_CMD,5,
317 };
318 constexpr uint8_t lcd_init_sequence_P070ACB_FT[] = {
319     DELAY_CMD, 100,
320     GEN_CMD,2,0xE0,0x00,
321     GEN_CMD,2,0xE1,0x93,
322     GEN_CMD,2,0xE2,0x65,
323     GEN_CMD,2,0xE3,0xF8,
324     GEN_CMD,2,0x80,0x03,
325     GEN_CMD,2,0xE0,0x01,
326     GEN_CMD,2,0x0C,0x74,
327     GEN_CMD,2,0x17,0x00,
328     GEN_CMD,2,0x18,0xEF,
329     GEN_CMD,2,0x19,0x00,
330     GEN_CMD,2,0x1A,0x00,
331     GEN_CMD,2,0x1B,0xEF,
332     GEN_CMD,2,0x1C,0x00,
333     GEN_CMD,2,0x1F,0x70,
334     GEN_CMD,2,0x20,0x2D,
335     GEN_CMD,2,0x21,0x2D,
336     GEN_CMD,2,0x22,0x7E,
337     GEN_CMD,2,0x26,0xF3,
338     GEN_CMD,2,0x37,0x09,
339     GEN_CMD,2,0x38,0x04,
340     GEN_CMD,2,0x39,0x00,
341     GEN_CMD,2,0x3A,0x01,
342     GEN_CMD,2,0x3C,0x90,
343     GEN_CMD,2,0x3D,0xFF,
344     GEN_CMD,2,0x3E,0xFF,
345     GEN_CMD,2,0x3F,0xFF,
346     GEN_CMD,2,0x40,0x02,
347     GEN_CMD,2,0x41,0x80,
348     GEN_CMD,2,0x42,0x99,
349     GEN_CMD,2,0x43,0x14,
350     GEN_CMD,2,0x44,0x19,
351     GEN_CMD,2,0x45,0x5A,
352     GEN_CMD,2,0x4B,0x04,
353     GEN_CMD,2,0x55,0x02,
354     GEN_CMD,2,0x56,0x01,
355     GEN_CMD,2,0x57,0x69,
356     GEN_CMD,2,0x58,0x0A,
357     GEN_CMD,2,0x59,0x0A,
358     GEN_CMD,2,0x5A,0x2E,
359     GEN_CMD,2,0x5B,0x19,
360     GEN_CMD,2,0x5C,0x15,
361     GEN_CMD,2,0x5D,0x77,
362     GEN_CMD,2,0x5E,0x56,
363     GEN_CMD,2,0x5F,0x45,
364     GEN_CMD,2,0x60,0x38,
365     GEN_CMD,2,0x61,0x35,
366     GEN_CMD,2,0x62,0x27,
367     GEN_CMD,2,0x63,0x2D,
368     GEN_CMD,2,0x64,0x18,
369     GEN_CMD,2,0x65,0x33,
370     GEN_CMD,2,0x66,0x34,
371     GEN_CMD,2,0x67,0x35,
372     GEN_CMD,2,0x68,0x56,
373     GEN_CMD,2,0x69,0x45,
374     GEN_CMD,2,0x6A,0x4F,
375     GEN_CMD,2,0x6B,0x42,
376     GEN_CMD,2,0x6C,0x40,
377     GEN_CMD,2,0x6D,0x34,
378     GEN_CMD,2,0x6E,0x25,
379     GEN_CMD,2,0x6F,0x02,
380     GEN_CMD,2,0x70,0x77,
381     GEN_CMD,2,0x71,0x56,
382     GEN_CMD,2,0x72,0x45,
383     GEN_CMD,2,0x73,0x38,
384     GEN_CMD,2,0x74,0x35,
385     GEN_CMD,2,0x75,0x27,
386     GEN_CMD,2,0x76,0x2D,
387     GEN_CMD,2,0x77,0x18,
388     GEN_CMD,2,0x78,0x33,
389     GEN_CMD,2,0x79,0x34,
390     GEN_CMD,2,0x7A,0x35,
391     GEN_CMD,2,0x7B,0x56,
392     GEN_CMD,2,0x7C,0x45,
393     GEN_CMD,2,0x7D,0x4F,
394     GEN_CMD,2,0x7E,0x42,
395     GEN_CMD,2,0x7F,0x40,
396     GEN_CMD,2,0x80,0x34,
397     GEN_CMD,2,0x81,0x25,
398     GEN_CMD,2,0x82,0x02,
399     GEN_CMD,2,0xE0,0x02,
400     GEN_CMD,2,0x00,0x53,
401     GEN_CMD,2,0x01,0x55,
402     GEN_CMD,2,0x02,0x55,
403     GEN_CMD,2,0x03,0x51,
404     GEN_CMD,2,0x04,0x77,
405     GEN_CMD,2,0x05,0x57,
406     GEN_CMD,2,0x06,0x1F,
407     GEN_CMD,2,0x07,0x4F,
408     GEN_CMD,2,0x08,0x4D,
409     GEN_CMD,2,0x09,0x1F,
410     GEN_CMD,2,0x0A,0x4B,
411     GEN_CMD,2,0x0B,0x49,
412     GEN_CMD,2,0x0C,0x1F,
413     GEN_CMD,2,0x0D,0x47,
414     GEN_CMD,2,0x0E,0x45,
415     GEN_CMD,2,0x0F,0x41,
416     GEN_CMD,2,0x10,0x1F,
417     GEN_CMD,2,0x11,0x1F,
418     GEN_CMD,2,0x12,0x1F,
419     GEN_CMD,2,0x13,0x55,
420     GEN_CMD,2,0x14,0x1F,
421     GEN_CMD,2,0x15,0x1F,
422     GEN_CMD,2,0x16,0x52,
423     GEN_CMD,2,0x17,0x55,
424     GEN_CMD,2,0x18,0x55,
425     GEN_CMD,2,0x19,0x50,
426     GEN_CMD,2,0x1A,0x77,
427     GEN_CMD,2,0x1B,0x57,
428     GEN_CMD,2,0x1C,0x1F,
429     GEN_CMD,2,0x1D,0x4E,
430     GEN_CMD,2,0x1E,0x4C,
431     GEN_CMD,2,0x1F,0x1F,
432     GEN_CMD,2,0x20,0x4A,
433     GEN_CMD,2,0x21,0x48,
434     GEN_CMD,2,0x22,0x1F,
435     GEN_CMD,2,0x23,0x46,
436     GEN_CMD,2,0x24,0x44,
437     GEN_CMD,2,0x25,0x40,
438     GEN_CMD,2,0x26,0x1F,
439     GEN_CMD,2,0x27,0x1F,
440     GEN_CMD,2,0x28,0x1F,
441     GEN_CMD,2,0x29,0x1F,
442     GEN_CMD,2,0x2A,0x1F,
443     GEN_CMD,2,0x2B,0x55,
444     GEN_CMD,2,0x2C,0x12,
445     GEN_CMD,2,0x2D,0x15,
446     GEN_CMD,2,0x2E,0x15,
447     GEN_CMD,2,0x2F,0x00,
448     GEN_CMD,2,0x30,0x37,
449     GEN_CMD,2,0x31,0x17,
450     GEN_CMD,2,0x32,0x1F,
451     GEN_CMD,2,0x33,0x08,
452     GEN_CMD,2,0x34,0x0A,
453     GEN_CMD,2,0x35,0x1F,
454     GEN_CMD,2,0x36,0x0C,
455     GEN_CMD,2,0x37,0x0E,
456     GEN_CMD,2,0x38,0x1F,
457     GEN_CMD,2,0x39,0x04,
458     GEN_CMD,2,0x3A,0x06,
459     GEN_CMD,2,0x3B,0x10,
460     GEN_CMD,2,0x3C,0x1F,
461     GEN_CMD,2,0x3D,0x1F,
462     GEN_CMD,2,0x3E,0x1F,
463     GEN_CMD,2,0x3F,0x15,
464     GEN_CMD,2,0x40,0x1F,
465     GEN_CMD,2,0x41,0x1F,
466     GEN_CMD,2,0x42,0x13,
467     GEN_CMD,2,0x43,0x15,
468     GEN_CMD,2,0x44,0x15,
469     GEN_CMD,2,0x45,0x01,
470     GEN_CMD,2,0x46,0x37,
471     GEN_CMD,2,0x47,0x17,
472     GEN_CMD,2,0x48,0x1F,
473     GEN_CMD,2,0x49,0x09,
474     GEN_CMD,2,0x4A,0x0B,
475     GEN_CMD,2,0x4B,0x1F,
476     GEN_CMD,2,0x4C,0x0D,
477     GEN_CMD,2,0x4D,0x0F,
478     GEN_CMD,2,0x4E,0x1F,
479     GEN_CMD,2,0x4F,0x05,
480     GEN_CMD,2,0x50,0x07,
481     GEN_CMD,2,0x51,0x11,
482     GEN_CMD,2,0x52,0x1F,
483     GEN_CMD,2,0x53,0x1F,
484     GEN_CMD,2,0x54,0x1F,
485     GEN_CMD,2,0x55,0x1F,
486     GEN_CMD,2,0x56,0x1F,
487     GEN_CMD,2,0x57,0x15,
488     GEN_CMD,2,0x58,0x40,
489     GEN_CMD,2,0x59,0x00,
490     GEN_CMD,2,0x5A,0x00,
491     GEN_CMD,2,0x5B,0x10,
492     GEN_CMD,2,0x5C,0x14,
493     GEN_CMD,2,0x5D,0x40,
494     GEN_CMD,2,0x5E,0x01,
495     GEN_CMD,2,0x5F,0x02,
496     GEN_CMD,2,0x60,0x40,
497     GEN_CMD,2,0x61,0x03,
498     GEN_CMD,2,0x62,0x04,
499     GEN_CMD,2,0x63,0x7A,
500     GEN_CMD,2,0x64,0x7A,
501     GEN_CMD,2,0x65,0x74,
502     GEN_CMD,2,0x66,0x16,
503     GEN_CMD,2,0x67,0xB4,
504     GEN_CMD,2,0x68,0x16,
505     GEN_CMD,2,0x69,0x7A,
506     GEN_CMD,2,0x6A,0x7A,
507     GEN_CMD,2,0x6B,0x0C,
508     GEN_CMD,2,0x6C,0x00,
509     GEN_CMD,2,0x6D,0x04,
510     GEN_CMD,2,0x6E,0x04,
511     GEN_CMD,2,0x6F,0x88,
512     GEN_CMD,2,0x70,0x00,
513     GEN_CMD,2,0x71,0x00,
514     GEN_CMD,2,0x72,0x06,
515     GEN_CMD,2,0x73,0x7B,
516     GEN_CMD,2,0x74,0x00,
517     GEN_CMD,2,0x75,0xBC,
518     GEN_CMD,2,0x76,0x00,
519     GEN_CMD,2,0x77,0x04,
520     GEN_CMD,2,0x78,0x2C,
521     GEN_CMD,2,0x79,0x00,
522     GEN_CMD,2,0x7A,0x00,
523     GEN_CMD,2,0x7B,0x00,
524     GEN_CMD,2,0x7C,0x00,
525     GEN_CMD,2,0x7D,0x03,
526     GEN_CMD,2,0x7E,0x7B,
527     GEN_CMD,2,0xE0,0x04,
528     GEN_CMD,2,0x09,0x11,
529     GEN_CMD,2,0x0E,0x48,
530     GEN_CMD,2,0x2B,0x2B,
531     GEN_CMD,2,0x2E,0x44,
532     GEN_CMD,2,0xE0,0x00,
533     GEN_CMD,2,0xE6,0x02,
534     GEN_CMD,2,0xE7,0x0C,
535     DCS_CMD,1,0x11,
536     DELAY_CMD,120,
537     DCS_CMD,1,0x29,
538     DCS_CMD,1,0x35,
539     DELAY_CMD, 20,
540 };
541 } //namespace
542 
GetDisplayId()543 zx_status_t Lcd::GetDisplayId() {
544 
545     uint8_t cmd = READ_DISPLAY_ID_CMD;
546     uint8_t rsp[READ_DISPLAY_ID_LEN];
547     zx_status_t status = ZX_OK;
548     if ((status = dsi_->Cmd(&cmd, 1, rsp, READ_DISPLAY_ID_LEN,
549                             COMMAND_GEN)) != ZX_OK) {
550         DISP_ERROR("Could not read out Display ID\n");
551         return status;
552     }
553 
554     DISP_INFO("Display ID: 0x%x, 0x%x, 0x%x\n", rsp[0], rsp[1], rsp[2]);
555     return status;
556 }
557 
558 // This function write DSI commands based on the input buffer.
LoadInitTable(const uint8_t * buffer,size_t size)559 zx_status_t Lcd::LoadInitTable(const uint8_t* buffer, size_t size) {
560     zx_status_t status = ZX_OK;
561     size_t i;
562     i  = 0;
563     bool isDCS = false;
564     while (i < size) {
565         switch (buffer[i]) {
566         case DELAY_CMD:
567             zx_nanosleep(zx_deadline_after(ZX_MSEC(buffer[i + 1])));
568             i += 2;
569             break;
570         case DCS_CMD:
571             isDCS = true;
572              __FALLTHROUGH;
573         case GEN_CMD:
574         default:
575             if ((status = dsi_->Cmd(&buffer[i+2], buffer[i+1], NULL, 0,
576                                     isDCS)) != ZX_OK) {
577                 DISP_ERROR("Error loading LCD init table. Aborting %d\n", status);
578                 return status;
579             }
580             // increment by payload length
581             i += buffer[i + 1] + 2; // the 2 includes current plus size field
582             isDCS = false;
583             break;
584         }
585     }
586     return status;
587 }
588 
Disable()589 zx_status_t Lcd::Disable() {
590     ZX_DEBUG_ASSERT(initialized_);
591     if (!enabled_) {
592         return ZX_OK;
593     }
594     // First send shutdown command to LCD
595     enabled_ = false;
596     return LoadInitTable(lcd_shutdown_sequence, sizeof(lcd_shutdown_sequence));
597 }
598 
Enable()599 zx_status_t Lcd::Enable() {
600     ZX_DEBUG_ASSERT(initialized_);
601     if (enabled_) {
602         return ZX_OK;
603     }
604     // reset LCD panel via GPIO according to vendor doc
605     gpio_config_out(&gpio_, 1);
606     gpio_write(&gpio_, 1);
607     zx_nanosleep(zx_deadline_after(ZX_MSEC(30)));
608     gpio_write(&gpio_, 0);
609     zx_nanosleep(zx_deadline_after(ZX_MSEC(10)));
610     gpio_write(&gpio_, 1);
611     zx_nanosleep(zx_deadline_after(ZX_MSEC(30)));
612     // check status
613     if (GetDisplayId() != ZX_OK) {
614         DISP_ERROR("Cannot communicate with LCD Panel!\n");
615         return ZX_ERR_TIMED_OUT;
616     }
617     zx_nanosleep(zx_deadline_after(ZX_USEC(10)));
618 
619     // load table
620     zx_status_t status;
621     if (panel_type_ == PANEL_TV070WSM_FT) {
622         status = LoadInitTable(lcd_init_sequence_TV070WSM_FT,
623                              sizeof(lcd_init_sequence_TV070WSM_FT));
624     } else if (panel_type_ == PANEL_P070ACB_FT) {
625         status = LoadInitTable(lcd_init_sequence_P070ACB_FT,
626                              sizeof(lcd_init_sequence_P070ACB_FT));
627     } else {
628         DISP_ERROR("Unsupported panel detected!\n");
629         status = ZX_ERR_NOT_SUPPORTED;
630     }
631 
632     if (status == ZX_OK) {
633         // LCD is on now.
634         enabled_ = true;
635     }
636     return status;
637 }
638 
Init(zx_device_t * parent)639 zx_status_t Lcd::Init(zx_device_t* parent) {
640     if (initialized_) {
641         return ZX_OK;
642     }
643     pdev_protocol_t pdev;
644     zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PDEV, &pdev);
645     if (status != ZX_OK) {
646         DISP_ERROR("Could not obtain platform device protocol\n");
647         return status;
648     }
649 
650     // Obtain GPIO protocol
651     size_t actual;
652     status = pdev_get_protocol(&pdev, ZX_PROTOCOL_GPIO, GPIO_LCD, &gpio_, sizeof(gpio_), &actual);
653     if (status != ZX_OK) {
654         DISP_ERROR("Could not obtain GPIO protocol\n");
655         return status;
656     }
657 
658     // Create a DW MIPI DSI object to use for sending dsi commands
659     fbl::AllocChecker ac;
660     dsi_ = fbl::make_unique_checked<astro_display::DwMipiDsi>(&ac);
661     if (!ac.check()) {
662         DISP_ERROR("Lcd: Could not create MIPI DSI object\n");
663         return ZX_ERR_NO_MEMORY;
664     }
665     status = dsi_->Init(parent);
666     if (status != ZX_OK) {
667         DISP_ERROR("Lcd: MIPI DSI initialization failed\n");
668         return status;
669     }
670 
671     initialized_ = true;
672 
673     if (kBootloaderDisplayEnabled) {
674         DISP_INFO("LCD Enabled by Bootloader. Disabling before proceeding\n");
675         enabled_ = true;
676         Disable();
677     }
678 
679     return ZX_OK;
680 }
681 
682 } // namespace astro_display
683