]> Git Repo - linux.git/blob - drivers/gpu/drm/panel/panel-khadas-ts050.c
Merge tag 'bootconfig-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[linux.git] / drivers / gpu / drm / panel / panel-khadas-ts050.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2020 BayLibre, SAS
4  * Author: Neil Armstrong <[email protected]>
5  */
6
7 #include <linux/delay.h>
8 #include <linux/gpio/consumer.h>
9 #include <linux/module.h>
10 #include <linux/of.h>
11 #include <linux/regulator/consumer.h>
12
13 #include <video/mipi_display.h>
14
15 #include <drm/drm_crtc.h>
16 #include <drm/drm_device.h>
17 #include <drm/drm_mipi_dsi.h>
18 #include <drm/drm_modes.h>
19 #include <drm/drm_panel.h>
20
21 struct khadas_ts050_panel {
22         struct drm_panel base;
23         struct mipi_dsi_device *link;
24
25         struct regulator *supply;
26         struct gpio_desc *reset_gpio;
27         struct gpio_desc *enable_gpio;
28         struct khadas_ts050_panel_data *panel_data;
29
30         bool prepared;
31         bool enabled;
32 };
33
34 struct khadas_ts050_panel_cmd {
35         u8 cmd;
36         u8 data[55];
37         u8 size;
38 };
39
40 struct khadas_ts050_panel_data {
41         struct khadas_ts050_panel_cmd *init_code;
42         int len;
43 };
44
45 static const struct khadas_ts050_panel_cmd ts050v2_init_code[] = {
46         {0xB9, {0xFF, 0x83, 0x99}, 0x03},
47         {0xBA, {0x63, 0x23, 0x68, 0xCF}, 0x04},
48         {0xD2, {0x55}, 0x01},
49         {0xB1, {0x02, 0x04, 0x70, 0x90, 0x01, 0x32, 0x33,
50                         0x11, 0x11, 0x4D, 0x57, 0x56, 0x73, 0x02, 0x02}, 0x0f},
51         {0xB2, {0x00, 0x80, 0x80, 0xAE, 0x0A, 0x0E, 0x75, 0x11, 0x00, 0x00, 0x00}, 0x0b},
52         {0xB4, {0x00, 0xFF, 0x04, 0xA4, 0x02, 0xA0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02,
53                         0x00, 0x24,     0x02, 0x04, 0x0A, 0x21, 0x03, 0x00, 0x00, 0x08, 0xA6, 0x88,
54                         0x04, 0xA4, 0x02, 0xA0, 0x00, 0x00,     0x10, 0x00, 0x00, 0x02, 0x00, 0x24,
55                         0x02, 0x04, 0x0A, 0x00, 0x00, 0x08,     0xA6, 0x00, 0x08, 0x11}, 0x2e},
56         {0xD3, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
57                         0x18, 0x32, 0x10, 0x09, 0x00, 0x09, 0x32,
58                         0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59                         0x00, 0x00, 0x11, 0x00, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00, 0x0A,
60                         0x40}, 0x21},
61         {0xD5, {0x18, 0x18, 0x18, 0x18, 0x21, 0x20, 0x18, 0x18, 0x19, 0x19, 0x19,
62                         0x19, 0x18, 0x18, 0x18, 0x18, 0x03, 0x02, 0x01, 0x00, 0x2F, 0x2F,
63                         0x30, 0x30, 0x31, 0x31, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, 0x20},
64         {0xD6, {0x18, 0x18, 0x18, 0x18, 0x20, 0x21, 0x19, 0x19, 0x18, 0x18, 0x19,
65                         0x19, 0x18, 0x18, 0x18, 0x18, 0x00, 0x01, 0x02, 0x03, 0x2F, 0x2F,
66                         0x30, 0x30, 0x31, 0x31, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, 0x20},
67         {0xD8, {0x0A, 0xBE, 0xFA, 0xA0, 0x0A, 0xBE, 0xFA, 0xA0}, 0x08},
68         {0xBD, {0x01}, 0x01},
69         {0xD8, {0x0F, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xE0}, 0x08},
70         {0xBD, {0x02}, 0x01},
71         {0xD8, {0x0F, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xE0}, 0x08},
72         {0xBD, {0x00}, 0x01},
73         {0xE0, {0x01, 0x35, 0x41, 0x3B, 0x79, 0x81, 0x8C, 0x85, 0x8E,
74                         0x95, 0x9B, 0xA0, 0xA4, 0xAB, 0xB1, 0xB3, 0xB7, 0xC5, 0xBD, 0xC5,
75                         0xB6, 0xC2, 0xC2, 0x62, 0x5D, 0x66, 0x73, 0x01, 0x35, 0x41, 0x3B,
76                         0x79, 0x81, 0x8C, 0x85, 0x8E, 0x95, 0x9B, 0xA0, 0xA4, 0xAB, 0xB1,
77                         0xB3, 0xB7, 0xB5, 0xBD, 0xC5, 0xB6, 0xC2, 0xC2, 0x62, 0x5D, 0x66,
78                         0x73}, 0x36},
79         {0xB6, {0x97, 0x97}, 0x02},
80         {0xCC, {0xC8}, 0x02},
81         {0xBF, {0x40, 0x41, 0x50, 0x19}, 0x04},
82         {0xC6, {0xFF, 0xF9}, 0x02},
83         {0xC0, {0x25, 0x5A}, 0x02},
84 };
85
86 /* Only the CMD1 User Command set is documented */
87 static const struct khadas_ts050_panel_cmd ts050_init_code[] = {
88         /* Select Unknown CMD Page (Undocumented) */
89         {0xff, {0xee}, 0x01},
90         /* Reload CMD1: Don't reload default value to register */
91         {0xfb, {0x01}, 0x01},
92         {0x1f, {0x45}, 0x01},
93         {0x24, {0x4f}, 0x01},
94         {0x38, {0xc8}, 0x01},
95         {0x39, {0x27}, 0x01},
96         {0x1e, {0x77}, 0x01},
97         {0x1d, {0x0f}, 0x01},
98         {0x7e, {0x71}, 0x01},
99         {0x7c, {0x03}, 0x01},
100         {0xff, {0x00}, 0x01},
101         {0xfb, {0x01}, 0x01},
102         {0x35, {0x01}, 0x01},
103         /* Select CMD2 Page0 (Undocumented) */
104         {0xff, {0x01}, 0x01},
105         /* Reload CMD1: Don't reload default value to register */
106         {0xfb, {0x01}, 0x01},
107         {0x00, {0x01}, 0x01},
108         {0x01, {0x55}, 0x01},
109         {0x02, {0x40}, 0x01},
110         {0x05, {0x40}, 0x01},
111         {0x06, {0x4a}, 0x01},
112         {0x07, {0x24}, 0x01},
113         {0x08, {0x0c}, 0x01},
114         {0x0b, {0x7d}, 0x01},
115         {0x0c, {0x7d}, 0x01},
116         {0x0e, {0xb0}, 0x01},
117         {0x0f, {0xae}, 0x01},
118         {0x11, {0x10}, 0x01},
119         {0x12, {0x10}, 0x01},
120         {0x13, {0x03}, 0x01},
121         {0x14, {0x4a}, 0x01},
122         {0x15, {0x12}, 0x01},
123         {0x16, {0x12}, 0x01},
124         {0x18, {0x00}, 0x01},
125         {0x19, {0x77}, 0x01},
126         {0x1a, {0x55}, 0x01},
127         {0x1b, {0x13}, 0x01},
128         {0x1c, {0x00}, 0x01},
129         {0x1d, {0x00}, 0x01},
130         {0x1e, {0x13}, 0x01},
131         {0x1f, {0x00}, 0x01},
132         {0x23, {0x00}, 0x01},
133         {0x24, {0x00}, 0x01},
134         {0x25, {0x00}, 0x01},
135         {0x26, {0x00}, 0x01},
136         {0x27, {0x00}, 0x01},
137         {0x28, {0x00}, 0x01},
138         {0x35, {0x00}, 0x01},
139         {0x66, {0x00}, 0x01},
140         {0x58, {0x82}, 0x01},
141         {0x59, {0x02}, 0x01},
142         {0x5a, {0x02}, 0x01},
143         {0x5b, {0x02}, 0x01},
144         {0x5c, {0x82}, 0x01},
145         {0x5d, {0x82}, 0x01},
146         {0x5e, {0x02}, 0x01},
147         {0x5f, {0x02}, 0x01},
148         {0x72, {0x31}, 0x01},
149         /* Select CMD2 Page4 (Undocumented) */
150         {0xff, {0x05}, 0x01},
151         /* Reload CMD1: Don't reload default value to register */
152         {0xfb, {0x01}, 0x01},
153         {0x00, {0x01}, 0x01},
154         {0x01, {0x0b}, 0x01},
155         {0x02, {0x0c}, 0x01},
156         {0x03, {0x09}, 0x01},
157         {0x04, {0x0a}, 0x01},
158         {0x05, {0x00}, 0x01},
159         {0x06, {0x0f}, 0x01},
160         {0x07, {0x10}, 0x01},
161         {0x08, {0x00}, 0x01},
162         {0x09, {0x00}, 0x01},
163         {0x0a, {0x00}, 0x01},
164         {0x0b, {0x00}, 0x01},
165         {0x0c, {0x00}, 0x01},
166         {0x0d, {0x13}, 0x01},
167         {0x0e, {0x15}, 0x01},
168         {0x0f, {0x17}, 0x01},
169         {0x10, {0x01}, 0x01},
170         {0x11, {0x0b}, 0x01},
171         {0x12, {0x0c}, 0x01},
172         {0x13, {0x09}, 0x01},
173         {0x14, {0x0a}, 0x01},
174         {0x15, {0x00}, 0x01},
175         {0x16, {0x0f}, 0x01},
176         {0x17, {0x10}, 0x01},
177         {0x18, {0x00}, 0x01},
178         {0x19, {0x00}, 0x01},
179         {0x1a, {0x00}, 0x01},
180         {0x1b, {0x00}, 0x01},
181         {0x1c, {0x00}, 0x01},
182         {0x1d, {0x13}, 0x01},
183         {0x1e, {0x15}, 0x01},
184         {0x1f, {0x17}, 0x01},
185         {0x20, {0x00}, 0x01},
186         {0x21, {0x03}, 0x01},
187         {0x22, {0x01}, 0x01},
188         {0x23, {0x40}, 0x01},
189         {0x24, {0x40}, 0x01},
190         {0x25, {0xed}, 0x01},
191         {0x29, {0x58}, 0x01},
192         {0x2a, {0x12}, 0x01},
193         {0x2b, {0x01}, 0x01},
194         {0x4b, {0x06}, 0x01},
195         {0x4c, {0x11}, 0x01},
196         {0x4d, {0x20}, 0x01},
197         {0x4e, {0x02}, 0x01},
198         {0x4f, {0x02}, 0x01},
199         {0x50, {0x20}, 0x01},
200         {0x51, {0x61}, 0x01},
201         {0x52, {0x01}, 0x01},
202         {0x53, {0x63}, 0x01},
203         {0x54, {0x77}, 0x01},
204         {0x55, {0xed}, 0x01},
205         {0x5b, {0x00}, 0x01},
206         {0x5c, {0x00}, 0x01},
207         {0x5d, {0x00}, 0x01},
208         {0x5e, {0x00}, 0x01},
209         {0x5f, {0x15}, 0x01},
210         {0x60, {0x75}, 0x01},
211         {0x61, {0x00}, 0x01},
212         {0x62, {0x00}, 0x01},
213         {0x63, {0x00}, 0x01},
214         {0x64, {0x00}, 0x01},
215         {0x65, {0x00}, 0x01},
216         {0x66, {0x00}, 0x01},
217         {0x67, {0x00}, 0x01},
218         {0x68, {0x04}, 0x01},
219         {0x69, {0x00}, 0x01},
220         {0x6a, {0x00}, 0x01},
221         {0x6c, {0x40}, 0x01},
222         {0x75, {0x01}, 0x01},
223         {0x76, {0x01}, 0x01},
224         {0x7a, {0x80}, 0x01},
225         {0x7b, {0xa3}, 0x01},
226         {0x7c, {0xd8}, 0x01},
227         {0x7d, {0x60}, 0x01},
228         {0x7f, {0x15}, 0x01},
229         {0x80, {0x81}, 0x01},
230         {0x83, {0x05}, 0x01},
231         {0x93, {0x08}, 0x01},
232         {0x94, {0x10}, 0x01},
233         {0x8a, {0x00}, 0x01},
234         {0x9b, {0x0f}, 0x01},
235         {0xea, {0xff}, 0x01},
236         {0xec, {0x00}, 0x01},
237         /* Select CMD2 Page0 (Undocumented) */
238         {0xff, {0x01}, 0x01},
239         /* Reload CMD1: Don't reload default value to register */
240         {0xfb, {0x01}, 0x01},
241         {0x75, {0x00}, 0x01},
242         {0x76, {0xdf}, 0x01},
243         {0x77, {0x00}, 0x01},
244         {0x78, {0xe4}, 0x01},
245         {0x79, {0x00}, 0x01},
246         {0x7a, {0xed}, 0x01},
247         {0x7b, {0x00}, 0x01},
248         {0x7c, {0xf6}, 0x01},
249         {0x7d, {0x00}, 0x01},
250         {0x7e, {0xff}, 0x01},
251         {0x7f, {0x01}, 0x01},
252         {0x80, {0x07}, 0x01},
253         {0x81, {0x01}, 0x01},
254         {0x82, {0x10}, 0x01},
255         {0x83, {0x01}, 0x01},
256         {0x84, {0x18}, 0x01},
257         {0x85, {0x01}, 0x01},
258         {0x86, {0x20}, 0x01},
259         {0x87, {0x01}, 0x01},
260         {0x88, {0x3d}, 0x01},
261         {0x89, {0x01}, 0x01},
262         {0x8a, {0x56}, 0x01},
263         {0x8b, {0x01}, 0x01},
264         {0x8c, {0x84}, 0x01},
265         {0x8d, {0x01}, 0x01},
266         {0x8e, {0xab}, 0x01},
267         {0x8f, {0x01}, 0x01},
268         {0x90, {0xec}, 0x01},
269         {0x91, {0x02}, 0x01},
270         {0x92, {0x22}, 0x01},
271         {0x93, {0x02}, 0x01},
272         {0x94, {0x23}, 0x01},
273         {0x95, {0x02}, 0x01},
274         {0x96, {0x55}, 0x01},
275         {0x97, {0x02}, 0x01},
276         {0x98, {0x8b}, 0x01},
277         {0x99, {0x02}, 0x01},
278         {0x9a, {0xaf}, 0x01},
279         {0x9b, {0x02}, 0x01},
280         {0x9c, {0xdf}, 0x01},
281         {0x9d, {0x03}, 0x01},
282         {0x9e, {0x01}, 0x01},
283         {0x9f, {0x03}, 0x01},
284         {0xa0, {0x2c}, 0x01},
285         {0xa2, {0x03}, 0x01},
286         {0xa3, {0x39}, 0x01},
287         {0xa4, {0x03}, 0x01},
288         {0xa5, {0x47}, 0x01},
289         {0xa6, {0x03}, 0x01},
290         {0xa7, {0x56}, 0x01},
291         {0xa9, {0x03}, 0x01},
292         {0xaa, {0x66}, 0x01},
293         {0xab, {0x03}, 0x01},
294         {0xac, {0x76}, 0x01},
295         {0xad, {0x03}, 0x01},
296         {0xae, {0x85}, 0x01},
297         {0xaf, {0x03}, 0x01},
298         {0xb0, {0x90}, 0x01},
299         {0xb1, {0x03}, 0x01},
300         {0xb2, {0xcb}, 0x01},
301         {0xb3, {0x00}, 0x01},
302         {0xb4, {0xdf}, 0x01},
303         {0xb5, {0x00}, 0x01},
304         {0xb6, {0xe4}, 0x01},
305         {0xb7, {0x00}, 0x01},
306         {0xb8, {0xed}, 0x01},
307         {0xb9, {0x00}, 0x01},
308         {0xba, {0xf6}, 0x01},
309         {0xbb, {0x00}, 0x01},
310         {0xbc, {0xff}, 0x01},
311         {0xbd, {0x01}, 0x01},
312         {0xbe, {0x07}, 0x01},
313         {0xbf, {0x01}, 0x01},
314         {0xc0, {0x10}, 0x01},
315         {0xc1, {0x01}, 0x01},
316         {0xc2, {0x18}, 0x01},
317         {0xc3, {0x01}, 0x01},
318         {0xc4, {0x20}, 0x01},
319         {0xc5, {0x01}, 0x01},
320         {0xc6, {0x3d}, 0x01},
321         {0xc7, {0x01}, 0x01},
322         {0xc8, {0x56}, 0x01},
323         {0xc9, {0x01}, 0x01},
324         {0xca, {0x84}, 0x01},
325         {0xcb, {0x01}, 0x01},
326         {0xcc, {0xab}, 0x01},
327         {0xcd, {0x01}, 0x01},
328         {0xce, {0xec}, 0x01},
329         {0xcf, {0x02}, 0x01},
330         {0xd0, {0x22}, 0x01},
331         {0xd1, {0x02}, 0x01},
332         {0xd2, {0x23}, 0x01},
333         {0xd3, {0x02}, 0x01},
334         {0xd4, {0x55}, 0x01},
335         {0xd5, {0x02}, 0x01},
336         {0xd6, {0x8b}, 0x01},
337         {0xd7, {0x02}, 0x01},
338         {0xd8, {0xaf}, 0x01},
339         {0xd9, {0x02}, 0x01},
340         {0xda, {0xdf}, 0x01},
341         {0xdb, {0x03}, 0x01},
342         {0xdc, {0x01}, 0x01},
343         {0xdd, {0x03}, 0x01},
344         {0xde, {0x2c}, 0x01},
345         {0xdf, {0x03}, 0x01},
346         {0xe0, {0x39}, 0x01},
347         {0xe1, {0x03}, 0x01},
348         {0xe2, {0x47}, 0x01},
349         {0xe3, {0x03}, 0x01},
350         {0xe4, {0x56}, 0x01},
351         {0xe5, {0x03}, 0x01},
352         {0xe6, {0x66}, 0x01},
353         {0xe7, {0x03}, 0x01},
354         {0xe8, {0x76}, 0x01},
355         {0xe9, {0x03}, 0x01},
356         {0xea, {0x85}, 0x01},
357         {0xeb, {0x03}, 0x01},
358         {0xec, {0x90}, 0x01},
359         {0xed, {0x03}, 0x01},
360         {0xee, {0xcb}, 0x01},
361         {0xef, {0x00}, 0x01},
362         {0xf0, {0xbb}, 0x01},
363         {0xf1, {0x00}, 0x01},
364         {0xf2, {0xc0}, 0x01},
365         {0xf3, {0x00}, 0x01},
366         {0xf4, {0xcc}, 0x01},
367         {0xf5, {0x00}, 0x01},
368         {0xf6, {0xd6}, 0x01},
369         {0xf7, {0x00}, 0x01},
370         {0xf8, {0xe1}, 0x01},
371         {0xf9, {0x00}, 0x01},
372         {0xfa, {0xea}, 0x01},
373         /* Select CMD2 Page2 (Undocumented) */
374         {0xff, {0x02}, 0x01},
375         /* Reload CMD1: Don't reload default value to register */
376         {0xfb, {0x01}, 0x01},
377         {0x00, {0x00}, 0x01},
378         {0x01, {0xf4}, 0x01},
379         {0x02, {0x00}, 0x01},
380         {0x03, {0xef}, 0x01},
381         {0x04, {0x01}, 0x01},
382         {0x05, {0x07}, 0x01},
383         {0x06, {0x01}, 0x01},
384         {0x07, {0x28}, 0x01},
385         {0x08, {0x01}, 0x01},
386         {0x09, {0x44}, 0x01},
387         {0x0a, {0x01}, 0x01},
388         {0x0b, {0x76}, 0x01},
389         {0x0c, {0x01}, 0x01},
390         {0x0d, {0xa0}, 0x01},
391         {0x0e, {0x01}, 0x01},
392         {0x0f, {0xe7}, 0x01},
393         {0x10, {0x02}, 0x01},
394         {0x11, {0x1f}, 0x01},
395         {0x12, {0x02}, 0x01},
396         {0x13, {0x22}, 0x01},
397         {0x14, {0x02}, 0x01},
398         {0x15, {0x54}, 0x01},
399         {0x16, {0x02}, 0x01},
400         {0x17, {0x8b}, 0x01},
401         {0x18, {0x02}, 0x01},
402         {0x19, {0xaf}, 0x01},
403         {0x1a, {0x02}, 0x01},
404         {0x1b, {0xe0}, 0x01},
405         {0x1c, {0x03}, 0x01},
406         {0x1d, {0x01}, 0x01},
407         {0x1e, {0x03}, 0x01},
408         {0x1f, {0x2d}, 0x01},
409         {0x20, {0x03}, 0x01},
410         {0x21, {0x39}, 0x01},
411         {0x22, {0x03}, 0x01},
412         {0x23, {0x47}, 0x01},
413         {0x24, {0x03}, 0x01},
414         {0x25, {0x57}, 0x01},
415         {0x26, {0x03}, 0x01},
416         {0x27, {0x65}, 0x01},
417         {0x28, {0x03}, 0x01},
418         {0x29, {0x77}, 0x01},
419         {0x2a, {0x03}, 0x01},
420         {0x2b, {0x85}, 0x01},
421         {0x2d, {0x03}, 0x01},
422         {0x2f, {0x8f}, 0x01},
423         {0x30, {0x03}, 0x01},
424         {0x31, {0xcb}, 0x01},
425         {0x32, {0x00}, 0x01},
426         {0x33, {0xbb}, 0x01},
427         {0x34, {0x00}, 0x01},
428         {0x35, {0xc0}, 0x01},
429         {0x36, {0x00}, 0x01},
430         {0x37, {0xcc}, 0x01},
431         {0x38, {0x00}, 0x01},
432         {0x39, {0xd6}, 0x01},
433         {0x3a, {0x00}, 0x01},
434         {0x3b, {0xe1}, 0x01},
435         {0x3d, {0x00}, 0x01},
436         {0x3f, {0xea}, 0x01},
437         {0x40, {0x00}, 0x01},
438         {0x41, {0xf4}, 0x01},
439         {0x42, {0x00}, 0x01},
440         {0x43, {0xfe}, 0x01},
441         {0x44, {0x01}, 0x01},
442         {0x45, {0x07}, 0x01},
443         {0x46, {0x01}, 0x01},
444         {0x47, {0x28}, 0x01},
445         {0x48, {0x01}, 0x01},
446         {0x49, {0x44}, 0x01},
447         {0x4a, {0x01}, 0x01},
448         {0x4b, {0x76}, 0x01},
449         {0x4c, {0x01}, 0x01},
450         {0x4d, {0xa0}, 0x01},
451         {0x4e, {0x01}, 0x01},
452         {0x4f, {0xe7}, 0x01},
453         {0x50, {0x02}, 0x01},
454         {0x51, {0x1f}, 0x01},
455         {0x52, {0x02}, 0x01},
456         {0x53, {0x22}, 0x01},
457         {0x54, {0x02}, 0x01},
458         {0x55, {0x54}, 0x01},
459         {0x56, {0x02}, 0x01},
460         {0x58, {0x8b}, 0x01},
461         {0x59, {0x02}, 0x01},
462         {0x5a, {0xaf}, 0x01},
463         {0x5b, {0x02}, 0x01},
464         {0x5c, {0xe0}, 0x01},
465         {0x5d, {0x03}, 0x01},
466         {0x5e, {0x01}, 0x01},
467         {0x5f, {0x03}, 0x01},
468         {0x60, {0x2d}, 0x01},
469         {0x61, {0x03}, 0x01},
470         {0x62, {0x39}, 0x01},
471         {0x63, {0x03}, 0x01},
472         {0x64, {0x47}, 0x01},
473         {0x65, {0x03}, 0x01},
474         {0x66, {0x57}, 0x01},
475         {0x67, {0x03}, 0x01},
476         {0x68, {0x65}, 0x01},
477         {0x69, {0x03}, 0x01},
478         {0x6a, {0x77}, 0x01},
479         {0x6b, {0x03}, 0x01},
480         {0x6c, {0x85}, 0x01},
481         {0x6d, {0x03}, 0x01},
482         {0x6e, {0x8f}, 0x01},
483         {0x6f, {0x03}, 0x01},
484         {0x70, {0xcb}, 0x01},
485         {0x71, {0x00}, 0x01},
486         {0x72, {0x00}, 0x01},
487         {0x73, {0x00}, 0x01},
488         {0x74, {0x21}, 0x01},
489         {0x75, {0x00}, 0x01},
490         {0x76, {0x4c}, 0x01},
491         {0x77, {0x00}, 0x01},
492         {0x78, {0x6b}, 0x01},
493         {0x79, {0x00}, 0x01},
494         {0x7a, {0x85}, 0x01},
495         {0x7b, {0x00}, 0x01},
496         {0x7c, {0x9a}, 0x01},
497         {0x7d, {0x00}, 0x01},
498         {0x7e, {0xad}, 0x01},
499         {0x7f, {0x00}, 0x01},
500         {0x80, {0xbe}, 0x01},
501         {0x81, {0x00}, 0x01},
502         {0x82, {0xcd}, 0x01},
503         {0x83, {0x01}, 0x01},
504         {0x84, {0x01}, 0x01},
505         {0x85, {0x01}, 0x01},
506         {0x86, {0x29}, 0x01},
507         {0x87, {0x01}, 0x01},
508         {0x88, {0x68}, 0x01},
509         {0x89, {0x01}, 0x01},
510         {0x8a, {0x98}, 0x01},
511         {0x8b, {0x01}, 0x01},
512         {0x8c, {0xe5}, 0x01},
513         {0x8d, {0x02}, 0x01},
514         {0x8e, {0x1e}, 0x01},
515         {0x8f, {0x02}, 0x01},
516         {0x90, {0x30}, 0x01},
517         {0x91, {0x02}, 0x01},
518         {0x92, {0x52}, 0x01},
519         {0x93, {0x02}, 0x01},
520         {0x94, {0x88}, 0x01},
521         {0x95, {0x02}, 0x01},
522         {0x96, {0xaa}, 0x01},
523         {0x97, {0x02}, 0x01},
524         {0x98, {0xd7}, 0x01},
525         {0x99, {0x02}, 0x01},
526         {0x9a, {0xf7}, 0x01},
527         {0x9b, {0x03}, 0x01},
528         {0x9c, {0x21}, 0x01},
529         {0x9d, {0x03}, 0x01},
530         {0x9e, {0x2e}, 0x01},
531         {0x9f, {0x03}, 0x01},
532         {0xa0, {0x3d}, 0x01},
533         {0xa2, {0x03}, 0x01},
534         {0xa3, {0x4c}, 0x01},
535         {0xa4, {0x03}, 0x01},
536         {0xa5, {0x5e}, 0x01},
537         {0xa6, {0x03}, 0x01},
538         {0xa7, {0x71}, 0x01},
539         {0xa9, {0x03}, 0x01},
540         {0xaa, {0x86}, 0x01},
541         {0xab, {0x03}, 0x01},
542         {0xac, {0x94}, 0x01},
543         {0xad, {0x03}, 0x01},
544         {0xae, {0xfa}, 0x01},
545         {0xaf, {0x00}, 0x01},
546         {0xb0, {0x00}, 0x01},
547         {0xb1, {0x00}, 0x01},
548         {0xb2, {0x21}, 0x01},
549         {0xb3, {0x00}, 0x01},
550         {0xb4, {0x4c}, 0x01},
551         {0xb5, {0x00}, 0x01},
552         {0xb6, {0x6b}, 0x01},
553         {0xb7, {0x00}, 0x01},
554         {0xb8, {0x85}, 0x01},
555         {0xb9, {0x00}, 0x01},
556         {0xba, {0x9a}, 0x01},
557         {0xbb, {0x00}, 0x01},
558         {0xbc, {0xad}, 0x01},
559         {0xbd, {0x00}, 0x01},
560         {0xbe, {0xbe}, 0x01},
561         {0xbf, {0x00}, 0x01},
562         {0xc0, {0xcd}, 0x01},
563         {0xc1, {0x01}, 0x01},
564         {0xc2, {0x01}, 0x01},
565         {0xc3, {0x01}, 0x01},
566         {0xc4, {0x29}, 0x01},
567         {0xc5, {0x01}, 0x01},
568         {0xc6, {0x68}, 0x01},
569         {0xc7, {0x01}, 0x01},
570         {0xc8, {0x98}, 0x01},
571         {0xc9, {0x01}, 0x01},
572         {0xca, {0xe5}, 0x01},
573         {0xcb, {0x02}, 0x01},
574         {0xcc, {0x1e}, 0x01},
575         {0xcd, {0x02}, 0x01},
576         {0xce, {0x20}, 0x01},
577         {0xcf, {0x02}, 0x01},
578         {0xd0, {0x52}, 0x01},
579         {0xd1, {0x02}, 0x01},
580         {0xd2, {0x88}, 0x01},
581         {0xd3, {0x02}, 0x01},
582         {0xd4, {0xaa}, 0x01},
583         {0xd5, {0x02}, 0x01},
584         {0xd6, {0xd7}, 0x01},
585         {0xd7, {0x02}, 0x01},
586         {0xd8, {0xf7}, 0x01},
587         {0xd9, {0x03}, 0x01},
588         {0xda, {0x21}, 0x01},
589         {0xdb, {0x03}, 0x01},
590         {0xdc, {0x2e}, 0x01},
591         {0xdd, {0x03}, 0x01},
592         {0xde, {0x3d}, 0x01},
593         {0xdf, {0x03}, 0x01},
594         {0xe0, {0x4c}, 0x01},
595         {0xe1, {0x03}, 0x01},
596         {0xe2, {0x5e}, 0x01},
597         {0xe3, {0x03}, 0x01},
598         {0xe4, {0x71}, 0x01},
599         {0xe5, {0x03}, 0x01},
600         {0xe6, {0x86}, 0x01},
601         {0xe7, {0x03}, 0x01},
602         {0xe8, {0x94}, 0x01},
603         {0xe9, {0x03}, 0x01},
604         {0xea, {0xfa}, 0x01},
605         /* Select CMD2 Page0 (Undocumented) */
606         {0xff, {0x01}, 0x01},
607         /* Reload CMD1: Don't reload default value to register */
608         {0xfb, {0x01}, 0x01},
609         /* Select CMD2 Page1 (Undocumented) */
610         {0xff, {0x02}, 0x01},
611         /* Reload CMD1: Don't reload default value to register */
612         {0xfb, {0x01}, 0x01},
613         /* Select CMD2 Page3 (Undocumented) */
614         {0xff, {0x04}, 0x01},
615         /* Reload CMD1: Don't reload default value to register */
616         {0xfb, {0x01}, 0x01},
617         /* Select CMD1 */
618         {0xff, {0x00}, 0x01},
619         {0xd3, {0x22}, 0x01}, /* RGBMIPICTRL: VSYNC back porch = 34 */
620         {0xd4, {0x04}, 0x01}, /* RGBMIPICTRL: VSYNC front porch = 4 */
621 };
622
623 struct khadas_ts050_panel_data ts050_panel_data = {
624         .init_code = (struct khadas_ts050_panel_cmd *)ts050_init_code,
625         .len = ARRAY_SIZE(ts050_init_code)
626 };
627
628 struct khadas_ts050_panel_data ts050v2_panel_data = {
629         .init_code = (struct khadas_ts050_panel_cmd *)ts050v2_init_code,
630         .len = ARRAY_SIZE(ts050v2_init_code)
631 };
632
633 static inline
634 struct khadas_ts050_panel *to_khadas_ts050_panel(struct drm_panel *panel)
635 {
636         return container_of(panel, struct khadas_ts050_panel, base);
637 }
638
639 static int khadas_ts050_panel_prepare(struct drm_panel *panel)
640 {
641         struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
642         unsigned int i;
643         int err;
644
645         if (khadas_ts050->prepared)
646                 return 0;
647
648         gpiod_set_value_cansleep(khadas_ts050->enable_gpio, 0);
649
650         err = regulator_enable(khadas_ts050->supply);
651         if (err < 0)
652                 return err;
653
654         gpiod_set_value_cansleep(khadas_ts050->enable_gpio, 1);
655
656         msleep(60);
657
658         gpiod_set_value_cansleep(khadas_ts050->reset_gpio, 1);
659
660         usleep_range(10000, 11000);
661
662         gpiod_set_value_cansleep(khadas_ts050->reset_gpio, 0);
663
664         /* Select CMD2 page 4 (Undocumented) */
665         mipi_dsi_dcs_write(khadas_ts050->link, 0xff, (u8[]){ 0x05 }, 1);
666
667         /* Reload CMD1: Don't reload default value to register */
668         mipi_dsi_dcs_write(khadas_ts050->link, 0xfb, (u8[]){ 0x01 }, 1);
669
670         mipi_dsi_dcs_write(khadas_ts050->link, 0xc5, (u8[]){ 0x01 }, 1);
671
672         msleep(100);
673
674         for (i = 0; i < khadas_ts050->panel_data->len; i++) {
675                 err = mipi_dsi_dcs_write(khadas_ts050->link,
676                                                 khadas_ts050->panel_data->init_code[i].cmd,
677                                                 &khadas_ts050->panel_data->init_code[i].data,
678                                                 khadas_ts050->panel_data->init_code[i].size);
679                 if (err < 0) {
680                         dev_err(panel->dev, "failed write cmds: %d\n", err);
681                         goto poweroff;
682                 }
683         }
684
685         err = mipi_dsi_dcs_exit_sleep_mode(khadas_ts050->link);
686         if (err < 0) {
687                 dev_err(panel->dev, "failed to exit sleep mode: %d\n", err);
688                 goto poweroff;
689         }
690
691         msleep(120);
692
693         /* Select CMD1 */
694         mipi_dsi_dcs_write(khadas_ts050->link, 0xff, (u8[]){ 0x00 }, 1);
695
696         err = mipi_dsi_dcs_set_tear_on(khadas_ts050->link,
697                                        MIPI_DSI_DCS_TEAR_MODE_VBLANK);
698         if (err < 0) {
699                 dev_err(panel->dev, "failed to set tear on: %d\n", err);
700                 goto poweroff;
701         }
702
703         err = mipi_dsi_dcs_set_display_on(khadas_ts050->link);
704         if (err < 0) {
705                 dev_err(panel->dev, "failed to set display on: %d\n", err);
706                 goto poweroff;
707         }
708
709         usleep_range(10000, 11000);
710
711         khadas_ts050->prepared = true;
712
713         return 0;
714
715 poweroff:
716         gpiod_set_value_cansleep(khadas_ts050->enable_gpio, 0);
717         gpiod_set_value_cansleep(khadas_ts050->reset_gpio, 1);
718
719         regulator_disable(khadas_ts050->supply);
720
721         return err;
722 }
723
724 static int khadas_ts050_panel_unprepare(struct drm_panel *panel)
725 {
726         struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
727         int err;
728
729         if (!khadas_ts050->prepared)
730                 return 0;
731
732         khadas_ts050->prepared = false;
733
734         err = mipi_dsi_dcs_enter_sleep_mode(khadas_ts050->link);
735         if (err < 0)
736                 dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
737
738         msleep(150);
739
740         gpiod_set_value_cansleep(khadas_ts050->enable_gpio, 0);
741         gpiod_set_value_cansleep(khadas_ts050->reset_gpio, 1);
742
743         err = regulator_disable(khadas_ts050->supply);
744         if (err < 0)
745                 return err;
746
747         return 0;
748 }
749
750 static int khadas_ts050_panel_enable(struct drm_panel *panel)
751 {
752         struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
753
754         khadas_ts050->enabled = true;
755
756         return 0;
757 }
758
759 static int khadas_ts050_panel_disable(struct drm_panel *panel)
760 {
761         struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
762         int err;
763
764         if (!khadas_ts050->enabled)
765                 return 0;
766
767         err = mipi_dsi_dcs_set_display_off(khadas_ts050->link);
768         if (err < 0)
769                 dev_err(panel->dev, "failed to set display off: %d\n", err);
770
771         usleep_range(10000, 11000);
772
773         khadas_ts050->enabled = false;
774
775         return 0;
776 }
777
778 static const struct drm_display_mode default_mode = {
779         .clock = 160000,
780         .hdisplay = 1080,
781         .hsync_start = 1080 + 117,
782         .hsync_end = 1080 + 117 + 5,
783         .htotal = 1080 + 117 + 5 + 160,
784         .vdisplay = 1920,
785         .vsync_start = 1920 + 4,
786         .vsync_end = 1920 + 4 + 3,
787         .vtotal = 1920 + 4 + 3 + 31,
788         .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
789 };
790
791 static int khadas_ts050_panel_get_modes(struct drm_panel *panel,
792                                         struct drm_connector *connector)
793 {
794         struct drm_display_mode *mode;
795
796         mode = drm_mode_duplicate(connector->dev, &default_mode);
797         if (!mode) {
798                 dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
799                         default_mode.hdisplay, default_mode.vdisplay,
800                         drm_mode_vrefresh(&default_mode));
801                 return -ENOMEM;
802         }
803
804         drm_mode_set_name(mode);
805
806         drm_mode_probed_add(connector, mode);
807
808         connector->display_info.width_mm = 64;
809         connector->display_info.height_mm = 118;
810         connector->display_info.bpc = 8;
811
812         return 1;
813 }
814
815 static const struct drm_panel_funcs khadas_ts050_panel_funcs = {
816         .prepare = khadas_ts050_panel_prepare,
817         .unprepare = khadas_ts050_panel_unprepare,
818         .enable = khadas_ts050_panel_enable,
819         .disable = khadas_ts050_panel_disable,
820         .get_modes = khadas_ts050_panel_get_modes,
821 };
822
823 static const struct of_device_id khadas_ts050_of_match[] = {
824         { .compatible = "khadas,ts050",    .data = &ts050_panel_data, },
825         { .compatible = "khadas,ts050v2",  .data = &ts050v2_panel_data, },
826         { /* sentinel */ }
827 };
828 MODULE_DEVICE_TABLE(of, khadas_ts050_of_match);
829
830 static int khadas_ts050_panel_add(struct khadas_ts050_panel *khadas_ts050)
831 {
832         struct device *dev = &khadas_ts050->link->dev;
833         int err;
834
835         khadas_ts050->supply = devm_regulator_get(dev, "power");
836         if (IS_ERR(khadas_ts050->supply))
837                 return dev_err_probe(dev, PTR_ERR(khadas_ts050->supply),
838                                      "failed to get power supply");
839
840         khadas_ts050->reset_gpio = devm_gpiod_get(dev, "reset",
841                                                   GPIOD_OUT_LOW);
842         if (IS_ERR(khadas_ts050->reset_gpio))
843                 return dev_err_probe(dev, PTR_ERR(khadas_ts050->reset_gpio),
844                                      "failed to get reset gpio");
845
846         khadas_ts050->enable_gpio = devm_gpiod_get(dev, "enable",
847                                                    GPIOD_OUT_HIGH);
848         if (IS_ERR(khadas_ts050->enable_gpio))
849                 return dev_err_probe(dev, PTR_ERR(khadas_ts050->enable_gpio),
850                                      "failed to get enable gpio");
851
852         drm_panel_init(&khadas_ts050->base, &khadas_ts050->link->dev,
853                        &khadas_ts050_panel_funcs, DRM_MODE_CONNECTOR_DSI);
854
855         err = drm_panel_of_backlight(&khadas_ts050->base);
856         if (err)
857                 return err;
858
859         drm_panel_add(&khadas_ts050->base);
860
861         return 0;
862 }
863
864 static int khadas_ts050_panel_probe(struct mipi_dsi_device *dsi)
865 {
866         struct khadas_ts050_panel *khadas_ts050;
867         int err;
868
869         const void *data = of_device_get_match_data(&dsi->dev);
870
871         if (!data) {
872                 dev_err(&dsi->dev, "No matching data\n");
873                 return -ENODEV;
874         }
875
876         dsi->lanes = 4;
877         dsi->format = MIPI_DSI_FMT_RGB888;
878         dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
879                           MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET;
880
881         khadas_ts050 = devm_kzalloc(&dsi->dev, sizeof(*khadas_ts050),
882                                     GFP_KERNEL);
883         if (!khadas_ts050)
884                 return -ENOMEM;
885
886         khadas_ts050->panel_data = (struct khadas_ts050_panel_data *)data;
887         mipi_dsi_set_drvdata(dsi, khadas_ts050);
888         khadas_ts050->link = dsi;
889
890         err = khadas_ts050_panel_add(khadas_ts050);
891         if (err < 0)
892                 return err;
893
894         err = mipi_dsi_attach(dsi);
895         if (err)
896                 drm_panel_remove(&khadas_ts050->base);
897
898         return err;
899 }
900
901 static void khadas_ts050_panel_remove(struct mipi_dsi_device *dsi)
902 {
903         struct khadas_ts050_panel *khadas_ts050 = mipi_dsi_get_drvdata(dsi);
904         int err;
905
906         err = mipi_dsi_detach(dsi);
907         if (err < 0)
908                 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
909
910         drm_panel_remove(&khadas_ts050->base);
911         drm_panel_disable(&khadas_ts050->base);
912         drm_panel_unprepare(&khadas_ts050->base);
913 }
914
915 static void khadas_ts050_panel_shutdown(struct mipi_dsi_device *dsi)
916 {
917         struct khadas_ts050_panel *khadas_ts050 = mipi_dsi_get_drvdata(dsi);
918
919         drm_panel_disable(&khadas_ts050->base);
920         drm_panel_unprepare(&khadas_ts050->base);
921 }
922
923 static struct mipi_dsi_driver khadas_ts050_panel_driver = {
924         .driver = {
925                 .name = "panel-khadas-ts050",
926                 .of_match_table = khadas_ts050_of_match,
927         },
928         .probe = khadas_ts050_panel_probe,
929         .remove = khadas_ts050_panel_remove,
930         .shutdown = khadas_ts050_panel_shutdown,
931 };
932 module_mipi_dsi_driver(khadas_ts050_panel_driver);
933
934 MODULE_AUTHOR("Neil Armstrong <[email protected]>");
935 MODULE_DESCRIPTION("Khadas TS050 panel driver");
936 MODULE_LICENSE("GPL v2");
This page took 0.090728 seconds and 4 git commands to generate.