]> Git Repo - linux.git/blob - drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
net: bgmac: Fix return value check for fixed_phy_register()
[linux.git] / drivers / gpu / drm / panel / panel-jadard-jd9365da-h3.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2019 Radxa Limited
4  * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
5  *
6  * Author:
7  * - Jagan Teki <[email protected]>
8  * - Stephen Chen <[email protected]>
9  */
10
11 #include <drm/drm_mipi_dsi.h>
12 #include <drm/drm_modes.h>
13 #include <drm/drm_panel.h>
14 #include <drm/drm_print.h>
15
16 #include <linux/gpio/consumer.h>
17 #include <linux/delay.h>
18 #include <linux/module.h>
19 #include <linux/of_device.h>
20 #include <linux/regulator/consumer.h>
21
22 #define JD9365DA_INIT_CMD_LEN           2
23
24 struct jadard_init_cmd {
25         u8 data[JD9365DA_INIT_CMD_LEN];
26 };
27
28 struct jadard_panel_desc {
29         const struct drm_display_mode mode;
30         unsigned int lanes;
31         enum mipi_dsi_pixel_format format;
32         const struct jadard_init_cmd *init_cmds;
33         u32 num_init_cmds;
34 };
35
36 struct jadard {
37         struct drm_panel panel;
38         struct mipi_dsi_device *dsi;
39         const struct jadard_panel_desc *desc;
40
41         struct regulator *vdd;
42         struct regulator *vccio;
43         struct gpio_desc *reset;
44 };
45
46 static inline struct jadard *panel_to_jadard(struct drm_panel *panel)
47 {
48         return container_of(panel, struct jadard, panel);
49 }
50
51 static int jadard_enable(struct drm_panel *panel)
52 {
53         struct device *dev = panel->dev;
54         struct jadard *jadard = panel_to_jadard(panel);
55         const struct jadard_panel_desc *desc = jadard->desc;
56         struct mipi_dsi_device *dsi = jadard->dsi;
57         unsigned int i;
58         int err;
59
60         msleep(10);
61
62         for (i = 0; i < desc->num_init_cmds; i++) {
63                 const struct jadard_init_cmd *cmd = &desc->init_cmds[i];
64
65                 err = mipi_dsi_dcs_write_buffer(dsi, cmd->data, JD9365DA_INIT_CMD_LEN);
66                 if (err < 0)
67                         return err;
68         }
69
70         msleep(120);
71
72         err = mipi_dsi_dcs_exit_sleep_mode(dsi);
73         if (err < 0)
74                 DRM_DEV_ERROR(dev, "failed to exit sleep mode ret = %d\n", err);
75
76         err =  mipi_dsi_dcs_set_display_on(dsi);
77         if (err < 0)
78                 DRM_DEV_ERROR(dev, "failed to set display on ret = %d\n", err);
79
80         return 0;
81 }
82
83 static int jadard_disable(struct drm_panel *panel)
84 {
85         struct device *dev = panel->dev;
86         struct jadard *jadard = panel_to_jadard(panel);
87         int ret;
88
89         ret = mipi_dsi_dcs_set_display_off(jadard->dsi);
90         if (ret < 0)
91                 DRM_DEV_ERROR(dev, "failed to set display off: %d\n", ret);
92
93         ret = mipi_dsi_dcs_enter_sleep_mode(jadard->dsi);
94         if (ret < 0)
95                 DRM_DEV_ERROR(dev, "failed to enter sleep mode: %d\n", ret);
96
97         return 0;
98 }
99
100 static int jadard_prepare(struct drm_panel *panel)
101 {
102         struct jadard *jadard = panel_to_jadard(panel);
103         int ret;
104
105         ret = regulator_enable(jadard->vccio);
106         if (ret)
107                 return ret;
108
109         ret = regulator_enable(jadard->vdd);
110         if (ret)
111                 return ret;
112
113         gpiod_set_value(jadard->reset, 1);
114         msleep(5);
115
116         gpiod_set_value(jadard->reset, 0);
117         msleep(10);
118
119         gpiod_set_value(jadard->reset, 1);
120         msleep(120);
121
122         return 0;
123 }
124
125 static int jadard_unprepare(struct drm_panel *panel)
126 {
127         struct jadard *jadard = panel_to_jadard(panel);
128
129         gpiod_set_value(jadard->reset, 1);
130         msleep(120);
131
132         regulator_disable(jadard->vdd);
133         regulator_disable(jadard->vccio);
134
135         return 0;
136 }
137
138 static int jadard_get_modes(struct drm_panel *panel,
139                             struct drm_connector *connector)
140 {
141         struct jadard *jadard = panel_to_jadard(panel);
142         const struct drm_display_mode *desc_mode = &jadard->desc->mode;
143         struct drm_display_mode *mode;
144
145         mode = drm_mode_duplicate(connector->dev, desc_mode);
146         if (!mode) {
147                 DRM_DEV_ERROR(&jadard->dsi->dev, "failed to add mode %ux%ux@%u\n",
148                               desc_mode->hdisplay, desc_mode->vdisplay,
149                               drm_mode_vrefresh(desc_mode));
150                 return -ENOMEM;
151         }
152
153         drm_mode_set_name(mode);
154         drm_mode_probed_add(connector, mode);
155
156         connector->display_info.width_mm = mode->width_mm;
157         connector->display_info.height_mm = mode->height_mm;
158
159         return 1;
160 }
161
162 static const struct drm_panel_funcs jadard_funcs = {
163         .disable = jadard_disable,
164         .unprepare = jadard_unprepare,
165         .prepare = jadard_prepare,
166         .enable = jadard_enable,
167         .get_modes = jadard_get_modes,
168 };
169
170 static const struct jadard_init_cmd radxa_display_8hd_ad002_init_cmds[] = {
171         { .data = { 0xE0, 0x00 } },
172         { .data = { 0xE1, 0x93 } },
173         { .data = { 0xE2, 0x65 } },
174         { .data = { 0xE3, 0xF8 } },
175         { .data = { 0x80, 0x03 } },
176         { .data = { 0xE0, 0x01 } },
177         { .data = { 0x00, 0x00 } },
178         { .data = { 0x01, 0x7E } },
179         { .data = { 0x03, 0x00 } },
180         { .data = { 0x04, 0x65 } },
181         { .data = { 0x0C, 0x74 } },
182         { .data = { 0x17, 0x00 } },
183         { .data = { 0x18, 0xB7 } },
184         { .data = { 0x19, 0x00 } },
185         { .data = { 0x1A, 0x00 } },
186         { .data = { 0x1B, 0xB7 } },
187         { .data = { 0x1C, 0x00 } },
188         { .data = { 0x24, 0xFE } },
189         { .data = { 0x37, 0x19 } },
190         { .data = { 0x38, 0x05 } },
191         { .data = { 0x39, 0x00 } },
192         { .data = { 0x3A, 0x01 } },
193         { .data = { 0x3B, 0x01 } },
194         { .data = { 0x3C, 0x70 } },
195         { .data = { 0x3D, 0xFF } },
196         { .data = { 0x3E, 0xFF } },
197         { .data = { 0x3F, 0xFF } },
198         { .data = { 0x40, 0x06 } },
199         { .data = { 0x41, 0xA0 } },
200         { .data = { 0x43, 0x1E } },
201         { .data = { 0x44, 0x0F } },
202         { .data = { 0x45, 0x28 } },
203         { .data = { 0x4B, 0x04 } },
204         { .data = { 0x55, 0x02 } },
205         { .data = { 0x56, 0x01 } },
206         { .data = { 0x57, 0xA9 } },
207         { .data = { 0x58, 0x0A } },
208         { .data = { 0x59, 0x0A } },
209         { .data = { 0x5A, 0x37 } },
210         { .data = { 0x5B, 0x19 } },
211         { .data = { 0x5D, 0x78 } },
212         { .data = { 0x5E, 0x63 } },
213         { .data = { 0x5F, 0x54 } },
214         { .data = { 0x60, 0x49 } },
215         { .data = { 0x61, 0x45 } },
216         { .data = { 0x62, 0x38 } },
217         { .data = { 0x63, 0x3D } },
218         { .data = { 0x64, 0x28 } },
219         { .data = { 0x65, 0x43 } },
220         { .data = { 0x66, 0x41 } },
221         { .data = { 0x67, 0x43 } },
222         { .data = { 0x68, 0x62 } },
223         { .data = { 0x69, 0x50 } },
224         { .data = { 0x6A, 0x57 } },
225         { .data = { 0x6B, 0x49 } },
226         { .data = { 0x6C, 0x44 } },
227         { .data = { 0x6D, 0x37 } },
228         { .data = { 0x6E, 0x23 } },
229         { .data = { 0x6F, 0x10 } },
230         { .data = { 0x70, 0x78 } },
231         { .data = { 0x71, 0x63 } },
232         { .data = { 0x72, 0x54 } },
233         { .data = { 0x73, 0x49 } },
234         { .data = { 0x74, 0x45 } },
235         { .data = { 0x75, 0x38 } },
236         { .data = { 0x76, 0x3D } },
237         { .data = { 0x77, 0x28 } },
238         { .data = { 0x78, 0x43 } },
239         { .data = { 0x79, 0x41 } },
240         { .data = { 0x7A, 0x43 } },
241         { .data = { 0x7B, 0x62 } },
242         { .data = { 0x7C, 0x50 } },
243         { .data = { 0x7D, 0x57 } },
244         { .data = { 0x7E, 0x49 } },
245         { .data = { 0x7F, 0x44 } },
246         { .data = { 0x80, 0x37 } },
247         { .data = { 0x81, 0x23 } },
248         { .data = { 0x82, 0x10 } },
249         { .data = { 0xE0, 0x02 } },
250         { .data = { 0x00, 0x47 } },
251         { .data = { 0x01, 0x47 } },
252         { .data = { 0x02, 0x45 } },
253         { .data = { 0x03, 0x45 } },
254         { .data = { 0x04, 0x4B } },
255         { .data = { 0x05, 0x4B } },
256         { .data = { 0x06, 0x49 } },
257         { .data = { 0x07, 0x49 } },
258         { .data = { 0x08, 0x41 } },
259         { .data = { 0x09, 0x1F } },
260         { .data = { 0x0A, 0x1F } },
261         { .data = { 0x0B, 0x1F } },
262         { .data = { 0x0C, 0x1F } },
263         { .data = { 0x0D, 0x1F } },
264         { .data = { 0x0E, 0x1F } },
265         { .data = { 0x0F, 0x5F } },
266         { .data = { 0x10, 0x5F } },
267         { .data = { 0x11, 0x57 } },
268         { .data = { 0x12, 0x77 } },
269         { .data = { 0x13, 0x35 } },
270         { .data = { 0x14, 0x1F } },
271         { .data = { 0x15, 0x1F } },
272         { .data = { 0x16, 0x46 } },
273         { .data = { 0x17, 0x46 } },
274         { .data = { 0x18, 0x44 } },
275         { .data = { 0x19, 0x44 } },
276         { .data = { 0x1A, 0x4A } },
277         { .data = { 0x1B, 0x4A } },
278         { .data = { 0x1C, 0x48 } },
279         { .data = { 0x1D, 0x48 } },
280         { .data = { 0x1E, 0x40 } },
281         { .data = { 0x1F, 0x1F } },
282         { .data = { 0x20, 0x1F } },
283         { .data = { 0x21, 0x1F } },
284         { .data = { 0x22, 0x1F } },
285         { .data = { 0x23, 0x1F } },
286         { .data = { 0x24, 0x1F } },
287         { .data = { 0x25, 0x5F } },
288         { .data = { 0x26, 0x5F } },
289         { .data = { 0x27, 0x57 } },
290         { .data = { 0x28, 0x77 } },
291         { .data = { 0x29, 0x35 } },
292         { .data = { 0x2A, 0x1F } },
293         { .data = { 0x2B, 0x1F } },
294         { .data = { 0x58, 0x40 } },
295         { .data = { 0x59, 0x00 } },
296         { .data = { 0x5A, 0x00 } },
297         { .data = { 0x5B, 0x10 } },
298         { .data = { 0x5C, 0x06 } },
299         { .data = { 0x5D, 0x40 } },
300         { .data = { 0x5E, 0x01 } },
301         { .data = { 0x5F, 0x02 } },
302         { .data = { 0x60, 0x30 } },
303         { .data = { 0x61, 0x01 } },
304         { .data = { 0x62, 0x02 } },
305         { .data = { 0x63, 0x03 } },
306         { .data = { 0x64, 0x6B } },
307         { .data = { 0x65, 0x05 } },
308         { .data = { 0x66, 0x0C } },
309         { .data = { 0x67, 0x73 } },
310         { .data = { 0x68, 0x09 } },
311         { .data = { 0x69, 0x03 } },
312         { .data = { 0x6A, 0x56 } },
313         { .data = { 0x6B, 0x08 } },
314         { .data = { 0x6C, 0x00 } },
315         { .data = { 0x6D, 0x04 } },
316         { .data = { 0x6E, 0x04 } },
317         { .data = { 0x6F, 0x88 } },
318         { .data = { 0x70, 0x00 } },
319         { .data = { 0x71, 0x00 } },
320         { .data = { 0x72, 0x06 } },
321         { .data = { 0x73, 0x7B } },
322         { .data = { 0x74, 0x00 } },
323         { .data = { 0x75, 0xF8 } },
324         { .data = { 0x76, 0x00 } },
325         { .data = { 0x77, 0xD5 } },
326         { .data = { 0x78, 0x2E } },
327         { .data = { 0x79, 0x12 } },
328         { .data = { 0x7A, 0x03 } },
329         { .data = { 0x7B, 0x00 } },
330         { .data = { 0x7C, 0x00 } },
331         { .data = { 0x7D, 0x03 } },
332         { .data = { 0x7E, 0x7B } },
333         { .data = { 0xE0, 0x04 } },
334         { .data = { 0x00, 0x0E } },
335         { .data = { 0x02, 0xB3 } },
336         { .data = { 0x09, 0x60 } },
337         { .data = { 0x0E, 0x2A } },
338         { .data = { 0x36, 0x59 } },
339         { .data = { 0xE0, 0x00 } },
340 };
341
342 static const struct jadard_panel_desc radxa_display_8hd_ad002_desc = {
343         .mode = {
344                 .clock          = 70000,
345
346                 .hdisplay       = 800,
347                 .hsync_start    = 800 + 40,
348                 .hsync_end      = 800 + 40 + 18,
349                 .htotal         = 800 + 40 + 18 + 20,
350
351                 .vdisplay       = 1280,
352                 .vsync_start    = 1280 + 20,
353                 .vsync_end      = 1280 + 20 + 4,
354                 .vtotal         = 1280 + 20 + 4 + 20,
355
356                 .width_mm       = 127,
357                 .height_mm      = 199,
358                 .type           = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
359         },
360         .lanes = 4,
361         .format = MIPI_DSI_FMT_RGB888,
362         .init_cmds = radxa_display_8hd_ad002_init_cmds,
363         .num_init_cmds = ARRAY_SIZE(radxa_display_8hd_ad002_init_cmds),
364 };
365
366 static const struct jadard_init_cmd cz101b4001_init_cmds[] = {
367         { .data = { 0xE0, 0x00 } },
368         { .data = { 0xE1, 0x93 } },
369         { .data = { 0xE2, 0x65 } },
370         { .data = { 0xE3, 0xF8 } },
371         { .data = { 0x80, 0x03 } },
372         { .data = { 0xE0, 0x01 } },
373         { .data = { 0x00, 0x00 } },
374         { .data = { 0x01, 0x3B } },
375         { .data = { 0x0C, 0x74 } },
376         { .data = { 0x17, 0x00 } },
377         { .data = { 0x18, 0xAF } },
378         { .data = { 0x19, 0x00 } },
379         { .data = { 0x1A, 0x00 } },
380         { .data = { 0x1B, 0xAF } },
381         { .data = { 0x1C, 0x00 } },
382         { .data = { 0x35, 0x26 } },
383         { .data = { 0x37, 0x09 } },
384         { .data = { 0x38, 0x04 } },
385         { .data = { 0x39, 0x00 } },
386         { .data = { 0x3A, 0x01 } },
387         { .data = { 0x3C, 0x78 } },
388         { .data = { 0x3D, 0xFF } },
389         { .data = { 0x3E, 0xFF } },
390         { .data = { 0x3F, 0x7F } },
391         { .data = { 0x40, 0x06 } },
392         { .data = { 0x41, 0xA0 } },
393         { .data = { 0x42, 0x81 } },
394         { .data = { 0x43, 0x14 } },
395         { .data = { 0x44, 0x23 } },
396         { .data = { 0x45, 0x28 } },
397         { .data = { 0x55, 0x02 } },
398         { .data = { 0x57, 0x69 } },
399         { .data = { 0x59, 0x0A } },
400         { .data = { 0x5A, 0x2A } },
401         { .data = { 0x5B, 0x17 } },
402         { .data = { 0x5D, 0x7F } },
403         { .data = { 0x5E, 0x6B } },
404         { .data = { 0x5F, 0x5C } },
405         { .data = { 0x60, 0x4F } },
406         { .data = { 0x61, 0x4D } },
407         { .data = { 0x62, 0x3F } },
408         { .data = { 0x63, 0x42 } },
409         { .data = { 0x64, 0x2B } },
410         { .data = { 0x65, 0x44 } },
411         { .data = { 0x66, 0x43 } },
412         { .data = { 0x67, 0x43 } },
413         { .data = { 0x68, 0x63 } },
414         { .data = { 0x69, 0x52 } },
415         { .data = { 0x6A, 0x5A } },
416         { .data = { 0x6B, 0x4F } },
417         { .data = { 0x6C, 0x4E } },
418         { .data = { 0x6D, 0x20 } },
419         { .data = { 0x6E, 0x0F } },
420         { .data = { 0x6F, 0x00 } },
421         { .data = { 0x70, 0x7F } },
422         { .data = { 0x71, 0x6B } },
423         { .data = { 0x72, 0x5C } },
424         { .data = { 0x73, 0x4F } },
425         { .data = { 0x74, 0x4D } },
426         { .data = { 0x75, 0x3F } },
427         { .data = { 0x76, 0x42 } },
428         { .data = { 0x77, 0x2B } },
429         { .data = { 0x78, 0x44 } },
430         { .data = { 0x79, 0x43 } },
431         { .data = { 0x7A, 0x43 } },
432         { .data = { 0x7B, 0x63 } },
433         { .data = { 0x7C, 0x52 } },
434         { .data = { 0x7D, 0x5A } },
435         { .data = { 0x7E, 0x4F } },
436         { .data = { 0x7F, 0x4E } },
437         { .data = { 0x80, 0x20 } },
438         { .data = { 0x81, 0x0F } },
439         { .data = { 0x82, 0x00 } },
440         { .data = { 0xE0, 0x02 } },
441         { .data = { 0x00, 0x02 } },
442         { .data = { 0x01, 0x02 } },
443         { .data = { 0x02, 0x00 } },
444         { .data = { 0x03, 0x00 } },
445         { .data = { 0x04, 0x1E } },
446         { .data = { 0x05, 0x1E } },
447         { .data = { 0x06, 0x1F } },
448         { .data = { 0x07, 0x1F } },
449         { .data = { 0x08, 0x1F } },
450         { .data = { 0x09, 0x17 } },
451         { .data = { 0x0A, 0x17 } },
452         { .data = { 0x0B, 0x37 } },
453         { .data = { 0x0C, 0x37 } },
454         { .data = { 0x0D, 0x47 } },
455         { .data = { 0x0E, 0x47 } },
456         { .data = { 0x0F, 0x45 } },
457         { .data = { 0x10, 0x45 } },
458         { .data = { 0x11, 0x4B } },
459         { .data = { 0x12, 0x4B } },
460         { .data = { 0x13, 0x49 } },
461         { .data = { 0x14, 0x49 } },
462         { .data = { 0x15, 0x1F } },
463         { .data = { 0x16, 0x01 } },
464         { .data = { 0x17, 0x01 } },
465         { .data = { 0x18, 0x00 } },
466         { .data = { 0x19, 0x00 } },
467         { .data = { 0x1A, 0x1E } },
468         { .data = { 0x1B, 0x1E } },
469         { .data = { 0x1C, 0x1F } },
470         { .data = { 0x1D, 0x1F } },
471         { .data = { 0x1E, 0x1F } },
472         { .data = { 0x1F, 0x17 } },
473         { .data = { 0x20, 0x17 } },
474         { .data = { 0x21, 0x37 } },
475         { .data = { 0x22, 0x37 } },
476         { .data = { 0x23, 0x46 } },
477         { .data = { 0x24, 0x46 } },
478         { .data = { 0x25, 0x44 } },
479         { .data = { 0x26, 0x44 } },
480         { .data = { 0x27, 0x4A } },
481         { .data = { 0x28, 0x4A } },
482         { .data = { 0x29, 0x48 } },
483         { .data = { 0x2A, 0x48 } },
484         { .data = { 0x2B, 0x1F } },
485         { .data = { 0x2C, 0x01 } },
486         { .data = { 0x2D, 0x01 } },
487         { .data = { 0x2E, 0x00 } },
488         { .data = { 0x2F, 0x00 } },
489         { .data = { 0x30, 0x1F } },
490         { .data = { 0x31, 0x1F } },
491         { .data = { 0x32, 0x1E } },
492         { .data = { 0x33, 0x1E } },
493         { .data = { 0x34, 0x1F } },
494         { .data = { 0x35, 0x17 } },
495         { .data = { 0x36, 0x17 } },
496         { .data = { 0x37, 0x37 } },
497         { .data = { 0x38, 0x37 } },
498         { .data = { 0x39, 0x08 } },
499         { .data = { 0x3A, 0x08 } },
500         { .data = { 0x3B, 0x0A } },
501         { .data = { 0x3C, 0x0A } },
502         { .data = { 0x3D, 0x04 } },
503         { .data = { 0x3E, 0x04 } },
504         { .data = { 0x3F, 0x06 } },
505         { .data = { 0x40, 0x06 } },
506         { .data = { 0x41, 0x1F } },
507         { .data = { 0x42, 0x02 } },
508         { .data = { 0x43, 0x02 } },
509         { .data = { 0x44, 0x00 } },
510         { .data = { 0x45, 0x00 } },
511         { .data = { 0x46, 0x1F } },
512         { .data = { 0x47, 0x1F } },
513         { .data = { 0x48, 0x1E } },
514         { .data = { 0x49, 0x1E } },
515         { .data = { 0x4A, 0x1F } },
516         { .data = { 0x4B, 0x17 } },
517         { .data = { 0x4C, 0x17 } },
518         { .data = { 0x4D, 0x37 } },
519         { .data = { 0x4E, 0x37 } },
520         { .data = { 0x4F, 0x09 } },
521         { .data = { 0x50, 0x09 } },
522         { .data = { 0x51, 0x0B } },
523         { .data = { 0x52, 0x0B } },
524         { .data = { 0x53, 0x05 } },
525         { .data = { 0x54, 0x05 } },
526         { .data = { 0x55, 0x07 } },
527         { .data = { 0x56, 0x07 } },
528         { .data = { 0x57, 0x1F } },
529         { .data = { 0x58, 0x40 } },
530         { .data = { 0x5B, 0x30 } },
531         { .data = { 0x5C, 0x16 } },
532         { .data = { 0x5D, 0x34 } },
533         { .data = { 0x5E, 0x05 } },
534         { .data = { 0x5F, 0x02 } },
535         { .data = { 0x63, 0x00 } },
536         { .data = { 0x64, 0x6A } },
537         { .data = { 0x67, 0x73 } },
538         { .data = { 0x68, 0x1D } },
539         { .data = { 0x69, 0x08 } },
540         { .data = { 0x6A, 0x6A } },
541         { .data = { 0x6B, 0x08 } },
542         { .data = { 0x6C, 0x00 } },
543         { .data = { 0x6D, 0x00 } },
544         { .data = { 0x6E, 0x00 } },
545         { .data = { 0x6F, 0x88 } },
546         { .data = { 0x75, 0xFF } },
547         { .data = { 0x77, 0xDD } },
548         { .data = { 0x78, 0x3F } },
549         { .data = { 0x79, 0x15 } },
550         { .data = { 0x7A, 0x17 } },
551         { .data = { 0x7D, 0x14 } },
552         { .data = { 0x7E, 0x82 } },
553         { .data = { 0xE0, 0x04 } },
554         { .data = { 0x00, 0x0E } },
555         { .data = { 0x02, 0xB3 } },
556         { .data = { 0x09, 0x61 } },
557         { .data = { 0x0E, 0x48 } },
558         { .data = { 0xE0, 0x00 } },
559         { .data = { 0xE6, 0x02 } },
560         { .data = { 0xE7, 0x0C } },
561 };
562
563 static const struct jadard_panel_desc cz101b4001_desc = {
564         .mode = {
565                 .clock          = 70000,
566
567                 .hdisplay       = 800,
568                 .hsync_start    = 800 + 40,
569                 .hsync_end      = 800 + 40 + 18,
570                 .htotal         = 800 + 40 + 18 + 20,
571
572                 .vdisplay       = 1280,
573                 .vsync_start    = 1280 + 20,
574                 .vsync_end      = 1280 + 20 + 4,
575                 .vtotal         = 1280 + 20 + 4 + 20,
576
577                 .width_mm       = 62,
578                 .height_mm      = 110,
579                 .type           = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
580         },
581         .lanes = 4,
582         .format = MIPI_DSI_FMT_RGB888,
583         .init_cmds = cz101b4001_init_cmds,
584         .num_init_cmds = ARRAY_SIZE(cz101b4001_init_cmds),
585 };
586
587 static int jadard_dsi_probe(struct mipi_dsi_device *dsi)
588 {
589         struct device *dev = &dsi->dev;
590         const struct jadard_panel_desc *desc;
591         struct jadard *jadard;
592         int ret;
593
594         jadard = devm_kzalloc(&dsi->dev, sizeof(*jadard), GFP_KERNEL);
595         if (!jadard)
596                 return -ENOMEM;
597
598         desc = of_device_get_match_data(dev);
599         dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
600                           MIPI_DSI_MODE_NO_EOT_PACKET;
601         dsi->format = desc->format;
602         dsi->lanes = desc->lanes;
603
604         jadard->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
605         if (IS_ERR(jadard->reset)) {
606                 DRM_DEV_ERROR(&dsi->dev, "failed to get our reset GPIO\n");
607                 return PTR_ERR(jadard->reset);
608         }
609
610         jadard->vdd = devm_regulator_get(dev, "vdd");
611         if (IS_ERR(jadard->vdd)) {
612                 DRM_DEV_ERROR(&dsi->dev, "failed to get vdd regulator\n");
613                 return PTR_ERR(jadard->vdd);
614         }
615
616         jadard->vccio = devm_regulator_get(dev, "vccio");
617         if (IS_ERR(jadard->vccio)) {
618                 DRM_DEV_ERROR(&dsi->dev, "failed to get vccio regulator\n");
619                 return PTR_ERR(jadard->vccio);
620         }
621
622         drm_panel_init(&jadard->panel, dev, &jadard_funcs,
623                        DRM_MODE_CONNECTOR_DSI);
624
625         ret = drm_panel_of_backlight(&jadard->panel);
626         if (ret)
627                 return ret;
628
629         drm_panel_add(&jadard->panel);
630
631         mipi_dsi_set_drvdata(dsi, jadard);
632         jadard->dsi = dsi;
633         jadard->desc = desc;
634
635         ret = mipi_dsi_attach(dsi);
636         if (ret < 0)
637                 drm_panel_remove(&jadard->panel);
638
639         return ret;
640 }
641
642 static void jadard_dsi_remove(struct mipi_dsi_device *dsi)
643 {
644         struct jadard *jadard = mipi_dsi_get_drvdata(dsi);
645
646         mipi_dsi_detach(dsi);
647         drm_panel_remove(&jadard->panel);
648 }
649
650 static const struct of_device_id jadard_of_match[] = {
651         {
652                 .compatible = "chongzhou,cz101b4001",
653                 .data = &cz101b4001_desc
654         },
655         {
656                 .compatible = "radxa,display-10hd-ad001",
657                 .data = &cz101b4001_desc
658         },
659         {
660                 .compatible = "radxa,display-8hd-ad002",
661                 .data = &radxa_display_8hd_ad002_desc
662         },
663         { /* sentinel */ }
664 };
665 MODULE_DEVICE_TABLE(of, jadard_of_match);
666
667 static struct mipi_dsi_driver jadard_driver = {
668         .probe = jadard_dsi_probe,
669         .remove = jadard_dsi_remove,
670         .driver = {
671                 .name = "jadard-jd9365da",
672                 .of_match_table = jadard_of_match,
673         },
674 };
675 module_mipi_dsi_driver(jadard_driver);
676
677 MODULE_AUTHOR("Jagan Teki <[email protected]>");
678 MODULE_AUTHOR("Stephen Chen <[email protected]>");
679 MODULE_DESCRIPTION("Jadard JD9365DA-H3 WXGA DSI panel");
680 MODULE_LICENSE("GPL");
This page took 0.075223 seconds and 4 git commands to generate.