Merge tag 'timers-urgent-2020-09-27' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / gpu / drm / panel / panel-sitronix-st7703.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Driver for panels based on Sitronix ST7703 controller, souch as:
4  *
5  * - Rocktech jh057n00900 5.5" MIPI-DSI panel
6  *
7  * Copyright (C) Purism SPC 2019
8  */
9
10 #include <linux/debugfs.h>
11 #include <linux/delay.h>
12 #include <linux/gpio/consumer.h>
13 #include <linux/media-bus-format.h>
14 #include <linux/mod_devicetable.h>
15 #include <linux/module.h>
16 #include <linux/of_device.h>
17 #include <linux/regulator/consumer.h>
18
19 #include <video/display_timing.h>
20 #include <video/mipi_display.h>
21
22 #include <drm/drm_mipi_dsi.h>
23 #include <drm/drm_modes.h>
24 #include <drm/drm_panel.h>
25 #include <drm/drm_print.h>
26
27 #define DRV_NAME "panel-sitronix-st7703"
28
29 /* Manufacturer specific Commands send via DSI */
30 #define ST7703_CMD_ALL_PIXEL_OFF 0x22
31 #define ST7703_CMD_ALL_PIXEL_ON  0x23
32 #define ST7703_CMD_SETDISP       0xB2
33 #define ST7703_CMD_SETRGBIF      0xB3
34 #define ST7703_CMD_SETCYC        0xB4
35 #define ST7703_CMD_SETBGP        0xB5
36 #define ST7703_CMD_SETVCOM       0xB6
37 #define ST7703_CMD_SETOTP        0xB7
38 #define ST7703_CMD_SETPOWER_EXT  0xB8
39 #define ST7703_CMD_SETEXTC       0xB9
40 #define ST7703_CMD_SETMIPI       0xBA
41 #define ST7703_CMD_SETVDC        0xBC
42 #define ST7703_CMD_UNKNOWN_BF    0xBF
43 #define ST7703_CMD_SETSCR        0xC0
44 #define ST7703_CMD_SETPOWER      0xC1
45 #define ST7703_CMD_SETPANEL      0xCC
46 #define ST7703_CMD_UNKNOWN_C6    0xC6
47 #define ST7703_CMD_SETGAMMA      0xE0
48 #define ST7703_CMD_SETEQ         0xE3
49 #define ST7703_CMD_SETGIP1       0xE9
50 #define ST7703_CMD_SETGIP2       0xEA
51
52 struct st7703 {
53         struct device *dev;
54         struct drm_panel panel;
55         struct gpio_desc *reset_gpio;
56         struct regulator *vcc;
57         struct regulator *iovcc;
58         bool prepared;
59
60         struct dentry *debugfs;
61         const struct st7703_panel_desc *desc;
62 };
63
64 struct st7703_panel_desc {
65         const struct drm_display_mode *mode;
66         unsigned int lanes;
67         unsigned long mode_flags;
68         enum mipi_dsi_pixel_format format;
69         int (*init_sequence)(struct st7703 *ctx);
70 };
71
72 static inline struct st7703 *panel_to_st7703(struct drm_panel *panel)
73 {
74         return container_of(panel, struct st7703, panel);
75 }
76
77 #define dsi_generic_write_seq(dsi, seq...) do {                         \
78                 static const u8 d[] = { seq };                          \
79                 int ret;                                                \
80                 ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));    \
81                 if (ret < 0)                                            \
82                         return ret;                                     \
83         } while (0)
84
85 static int jh057n_init_sequence(struct st7703 *ctx)
86 {
87         struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
88
89         /*
90          * Init sequence was supplied by the panel vendor. Most of the commands
91          * resemble the ST7703 but the number of parameters often don't match
92          * so it's likely a clone.
93          */
94         dsi_generic_write_seq(dsi, ST7703_CMD_SETEXTC,
95                               0xF1, 0x12, 0x83);
96         dsi_generic_write_seq(dsi, ST7703_CMD_SETRGBIF,
97                               0x10, 0x10, 0x05, 0x05, 0x03, 0xFF, 0x00, 0x00,
98                               0x00, 0x00);
99         dsi_generic_write_seq(dsi, ST7703_CMD_SETSCR,
100                               0x73, 0x73, 0x50, 0x50, 0x00, 0x00, 0x08, 0x70,
101                               0x00);
102         dsi_generic_write_seq(dsi, ST7703_CMD_SETVDC, 0x4E);
103         dsi_generic_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0B);
104         dsi_generic_write_seq(dsi, ST7703_CMD_SETCYC, 0x80);
105         dsi_generic_write_seq(dsi, ST7703_CMD_SETDISP, 0xF0, 0x12, 0x30);
106         dsi_generic_write_seq(dsi, ST7703_CMD_SETEQ,
107                               0x07, 0x07, 0x0B, 0x0B, 0x03, 0x0B, 0x00, 0x00,
108                               0x00, 0x00, 0xFF, 0x00, 0xC0, 0x10);
109         dsi_generic_write_seq(dsi, ST7703_CMD_SETBGP, 0x08, 0x08);
110         msleep(20);
111
112         dsi_generic_write_seq(dsi, ST7703_CMD_SETVCOM, 0x3F, 0x3F);
113         dsi_generic_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00);
114         dsi_generic_write_seq(dsi, ST7703_CMD_SETGIP1,
115                               0x82, 0x10, 0x06, 0x05, 0x9E, 0x0A, 0xA5, 0x12,
116                               0x31, 0x23, 0x37, 0x83, 0x04, 0xBC, 0x27, 0x38,
117                               0x0C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00,
118                               0x03, 0x00, 0x00, 0x00, 0x75, 0x75, 0x31, 0x88,
119                               0x88, 0x88, 0x88, 0x88, 0x88, 0x13, 0x88, 0x64,
120                               0x64, 0x20, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
121                               0x02, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
123         dsi_generic_write_seq(dsi, ST7703_CMD_SETGIP2,
124                               0x02, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125                               0x00, 0x00, 0x00, 0x00, 0x02, 0x46, 0x02, 0x88,
126                               0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0x88, 0x13,
127                               0x57, 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
128                               0x75, 0x88, 0x23, 0x14, 0x00, 0x00, 0x02, 0x00,
129                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0A,
131                               0xA5, 0x00, 0x00, 0x00, 0x00);
132         dsi_generic_write_seq(dsi, ST7703_CMD_SETGAMMA,
133                               0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41, 0x37,
134                               0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10, 0x11,
135                               0x18, 0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41,
136                               0x37, 0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10,
137                               0x11, 0x18);
138
139         return 0;
140 }
141
142 static const struct drm_display_mode jh057n00900_mode = {
143         .hdisplay    = 720,
144         .hsync_start = 720 + 90,
145         .hsync_end   = 720 + 90 + 20,
146         .htotal      = 720 + 90 + 20 + 20,
147         .vdisplay    = 1440,
148         .vsync_start = 1440 + 20,
149         .vsync_end   = 1440 + 20 + 4,
150         .vtotal      = 1440 + 20 + 4 + 12,
151         .clock       = 75276,
152         .flags       = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
153         .width_mm    = 65,
154         .height_mm   = 130,
155 };
156
157 struct st7703_panel_desc jh057n00900_panel_desc = {
158         .mode = &jh057n00900_mode,
159         .lanes = 4,
160         .mode_flags = MIPI_DSI_MODE_VIDEO |
161                 MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_SYNC_PULSE,
162         .format = MIPI_DSI_FMT_RGB888,
163         .init_sequence = jh057n_init_sequence,
164 };
165
166 #define dsi_dcs_write_seq(dsi, cmd, seq...) do {                        \
167                 static const u8 d[] = { seq };                          \
168                 int ret;                                                \
169                 ret = mipi_dsi_dcs_write(dsi, cmd, d, ARRAY_SIZE(d));   \
170                 if (ret < 0)                                            \
171                         return ret;                                     \
172         } while (0)
173
174
175 static int xbd599_init_sequence(struct st7703 *ctx)
176 {
177         struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
178
179         /*
180          * Init sequence was supplied by the panel vendor.
181          */
182
183         /* Magic sequence to unlock user commands below. */
184         dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC, 0xF1, 0x12, 0x83);
185
186         dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI,
187                           0x33, /* VC_main = 0, Lane_Number = 3 (4 lanes) */
188                           0x81, /* DSI_LDO_SEL = 1.7V, RTERM = 90 Ohm */
189                           0x05, /* IHSRX = x6 (Low High Speed driving ability) */
190                           0xF9, /* TX_CLK_SEL = fDSICLK/16 */
191                           0x0E, /* HFP_OSC (min. HFP number in DSI mode) */
192                           0x0E, /* HBP_OSC (min. HBP number in DSI mode) */
193                           /* The rest is undocumented in ST7703 datasheet */
194                           0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195                           0x44, 0x25, 0x00, 0x91, 0x0a, 0x00, 0x00, 0x02,
196                           0x4F, 0x11, 0x00, 0x00, 0x37);
197
198         dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT,
199                           0x25, /* PCCS = 2, ECP_DC_DIV = 1/4 HSYNC */
200                           0x22, /* DT = 15ms XDK_ECP = x2 */
201                           0x20, /* PFM_DC_DIV = /1 */
202                           0x03  /* ECP_SYNC_EN = 1, VGX_SYNC_EN = 1 */);
203
204         /* RGB I/F porch timing */
205         dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF,
206                           0x10, /* VBP_RGB_GEN */
207                           0x10, /* VFP_RGB_GEN */
208                           0x05, /* DE_BP_RGB_GEN */
209                           0x05, /* DE_FP_RGB_GEN */
210                           /* The rest is undocumented in ST7703 datasheet */
211                           0x03, 0xFF,
212                           0x00, 0x00,
213                           0x00, 0x00);
214
215         /* Source driving settings. */
216         dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR,
217                           0x73, /* N_POPON */
218                           0x73, /* N_NOPON */
219                           0x50, /* I_POPON */
220                           0x50, /* I_NOPON */
221                           0x00, /* SCR[31,24] */
222                           0xC0, /* SCR[23,16] */
223                           0x08, /* SCR[15,8] */
224                           0x70, /* SCR[7,0] */
225                           0x00  /* Undocumented */);
226
227         /* NVDDD_SEL = -1.8V, VDDD_SEL = out of range (possibly 1.9V?) */
228         dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x4E);
229
230         /*
231          * SS_PANEL = 1 (reverse scan), GS_PANEL = 0 (normal scan)
232          * REV_PANEL = 1 (normally black panel), BGR_PANEL = 1 (BGR)
233          */
234         dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0B);
235
236         /* Zig-Zag Type C column inversion. */
237         dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80);
238
239         /* Set display resolution. */
240         dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP,
241                           0xF0, /* NL = 240 */
242                           0x12, /* RES_V_LSB = 0, BLK_CON = VSSD,
243                                  * RESO_SEL = 720RGB
244                                  */
245                           0xF0  /* WHITE_GND_EN = 1 (GND),
246                                  * WHITE_FRAME_SEL = 7 frames,
247                                  * ISC = 0 frames
248                                  */);
249
250         dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ,
251                           0x00, /* PNOEQ */
252                           0x00, /* NNOEQ */
253                           0x0B, /* PEQGND */
254                           0x0B, /* NEQGND */
255                           0x10, /* PEQVCI */
256                           0x10, /* NEQVCI */
257                           0x00, /* PEQVCI1 */
258                           0x00, /* NEQVCI1 */
259                           0x00, /* reserved */
260                           0x00, /* reserved */
261                           0xFF, /* reserved */
262                           0x00, /* reserved */
263                           0xC0, /* ESD_DET_DATA_WHITE = 1, ESD_WHITE_EN = 1 */
264                           0x10  /* SLPIN_OPTION = 1 (no need vsync after sleep-in)
265                                  * VEDIO_NO_CHECK_EN = 0
266                                  * ESD_WHITE_GND_EN = 0
267                                  * ESD_DET_TIME_SEL = 0 frames
268                                  */);
269
270         /* Undocumented command. */
271         dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_C6, 0x01, 0x00, 0xFF, 0xFF, 0x00);
272
273         dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER,
274                           0x74, /* VBTHS, VBTLS: VGH = 17V, VBL = -11V */
275                           0x00, /* FBOFF_VGH = 0, FBOFF_VGL = 0 */
276                           0x32, /* VRP  */
277                           0x32, /* VRN */
278                           0x77, /* reserved */
279                           0xF1, /* APS = 1 (small),
280                                  * VGL_DET_EN = 1, VGH_DET_EN = 1,
281                                  * VGL_TURBO = 1, VGH_TURBO = 1
282                                  */
283                           0xFF, /* VGH1_L_DIV, VGL1_L_DIV (1.5MHz) */
284                           0xFF, /* VGH1_R_DIV, VGL1_R_DIV (1.5MHz) */
285                           0xCC, /* VGH2_L_DIV, VGL2_L_DIV (2.6MHz) */
286                           0xCC, /* VGH2_R_DIV, VGL2_R_DIV (2.6MHz) */
287                           0x77, /* VGH3_L_DIV, VGL3_L_DIV (4.5MHz) */
288                           0x77  /* VGH3_R_DIV, VGL3_R_DIV (4.5MHz) */);
289
290         /* Reference voltage. */
291         dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP,
292                           0x07, /* VREF_SEL = 4.2V */
293                           0x07  /* NVREF_SEL = 4.2V */);
294         msleep(20);
295
296         dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM,
297                           0x2C, /* VCOMDC_F = -0.67V */
298                           0x2C  /* VCOMDC_B = -0.67V */);
299
300         /* Undocumented command. */
301         dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00);
302
303         /* This command is to set forward GIP timing. */
304         dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1,
305                           0x82, 0x10, 0x06, 0x05, 0xA2, 0x0A, 0xA5, 0x12,
306                           0x31, 0x23, 0x37, 0x83, 0x04, 0xBC, 0x27, 0x38,
307                           0x0C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00,
308                           0x03, 0x00, 0x00, 0x00, 0x75, 0x75, 0x31, 0x88,
309                           0x88, 0x88, 0x88, 0x88, 0x88, 0x13, 0x88, 0x64,
310                           0x64, 0x20, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
311                           0x02, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
313
314         /* This command is to set backward GIP timing. */
315         dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2,
316                           0x02, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317                           0x00, 0x00, 0x00, 0x00, 0x02, 0x46, 0x02, 0x88,
318                           0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0x88, 0x13,
319                           0x57, 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
320                           0x75, 0x88, 0x23, 0x14, 0x00, 0x00, 0x02, 0x00,
321                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0A,
323                           0xA5, 0x00, 0x00, 0x00, 0x00);
324
325         /* Adjust the gamma characteristics of the panel. */
326         dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA,
327                           0x00, 0x09, 0x0D, 0x23, 0x27, 0x3C, 0x41, 0x35,
328                           0x07, 0x0D, 0x0E, 0x12, 0x13, 0x10, 0x12, 0x12,
329                           0x18, 0x00, 0x09, 0x0D, 0x23, 0x27, 0x3C, 0x41,
330                           0x35, 0x07, 0x0D, 0x0E, 0x12, 0x13, 0x10, 0x12,
331                           0x12, 0x18);
332
333         return 0;
334 }
335
336 static const struct drm_display_mode xbd599_mode = {
337         .hdisplay    = 720,
338         .hsync_start = 720 + 40,
339         .hsync_end   = 720 + 40 + 40,
340         .htotal      = 720 + 40 + 40 + 40,
341         .vdisplay    = 1440,
342         .vsync_start = 1440 + 18,
343         .vsync_end   = 1440 + 18 + 10,
344         .vtotal      = 1440 + 18 + 10 + 17,
345         .clock       = 69000,
346         .flags       = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
347         .width_mm    = 68,
348         .height_mm   = 136,
349 };
350
351 static const struct st7703_panel_desc xbd599_desc = {
352         .mode = &xbd599_mode,
353         .lanes = 4,
354         .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE,
355         .format = MIPI_DSI_FMT_RGB888,
356         .init_sequence = xbd599_init_sequence,
357 };
358
359 static int st7703_enable(struct drm_panel *panel)
360 {
361         struct st7703 *ctx = panel_to_st7703(panel);
362         struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
363         int ret;
364
365         ret = ctx->desc->init_sequence(ctx);
366         if (ret < 0) {
367                 DRM_DEV_ERROR(ctx->dev, "Panel init sequence failed: %d\n",
368                               ret);
369                 return ret;
370         }
371
372         msleep(20);
373
374         ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
375         if (ret < 0) {
376                 DRM_DEV_ERROR(ctx->dev, "Failed to exit sleep mode: %d\n", ret);
377                 return ret;
378         }
379
380         /* Panel is operational 120 msec after reset */
381         msleep(60);
382
383         ret = mipi_dsi_dcs_set_display_on(dsi);
384         if (ret)
385                 return ret;
386
387         DRM_DEV_DEBUG_DRIVER(ctx->dev, "Panel init sequence done\n");
388
389         return 0;
390 }
391
392 static int st7703_disable(struct drm_panel *panel)
393 {
394         struct st7703 *ctx = panel_to_st7703(panel);
395         struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
396         int ret;
397
398         ret = mipi_dsi_dcs_set_display_off(dsi);
399         if (ret < 0)
400                 DRM_DEV_ERROR(ctx->dev,
401                               "Failed to turn off the display: %d\n", ret);
402
403         ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
404         if (ret < 0)
405                 DRM_DEV_ERROR(ctx->dev,
406                               "Failed to enter sleep mode: %d\n", ret);
407
408         return 0;
409 }
410
411 static int st7703_unprepare(struct drm_panel *panel)
412 {
413         struct st7703 *ctx = panel_to_st7703(panel);
414
415         if (!ctx->prepared)
416                 return 0;
417
418         gpiod_set_value_cansleep(ctx->reset_gpio, 1);
419         regulator_disable(ctx->iovcc);
420         regulator_disable(ctx->vcc);
421         ctx->prepared = false;
422
423         return 0;
424 }
425
426 static int st7703_prepare(struct drm_panel *panel)
427 {
428         struct st7703 *ctx = panel_to_st7703(panel);
429         int ret;
430
431         if (ctx->prepared)
432                 return 0;
433
434         DRM_DEV_DEBUG_DRIVER(ctx->dev, "Resetting the panel\n");
435         ret = regulator_enable(ctx->vcc);
436         if (ret < 0) {
437                 DRM_DEV_ERROR(ctx->dev,
438                               "Failed to enable vcc supply: %d\n", ret);
439                 return ret;
440         }
441         ret = regulator_enable(ctx->iovcc);
442         if (ret < 0) {
443                 DRM_DEV_ERROR(ctx->dev,
444                               "Failed to enable iovcc supply: %d\n", ret);
445                 goto disable_vcc;
446         }
447
448         gpiod_set_value_cansleep(ctx->reset_gpio, 1);
449         usleep_range(20, 40);
450         gpiod_set_value_cansleep(ctx->reset_gpio, 0);
451         msleep(20);
452
453         ctx->prepared = true;
454
455         return 0;
456
457 disable_vcc:
458         regulator_disable(ctx->vcc);
459         return ret;
460 }
461
462 static int st7703_get_modes(struct drm_panel *panel,
463                             struct drm_connector *connector)
464 {
465         struct st7703 *ctx = panel_to_st7703(panel);
466         struct drm_display_mode *mode;
467
468         mode = drm_mode_duplicate(connector->dev, ctx->desc->mode);
469         if (!mode) {
470                 DRM_DEV_ERROR(ctx->dev, "Failed to add mode %ux%u@%u\n",
471                               ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,
472                               drm_mode_vrefresh(ctx->desc->mode));
473                 return -ENOMEM;
474         }
475
476         drm_mode_set_name(mode);
477
478         mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
479         connector->display_info.width_mm = mode->width_mm;
480         connector->display_info.height_mm = mode->height_mm;
481         drm_mode_probed_add(connector, mode);
482
483         return 1;
484 }
485
486 static const struct drm_panel_funcs st7703_drm_funcs = {
487         .disable   = st7703_disable,
488         .unprepare = st7703_unprepare,
489         .prepare   = st7703_prepare,
490         .enable    = st7703_enable,
491         .get_modes = st7703_get_modes,
492 };
493
494 static int allpixelson_set(void *data, u64 val)
495 {
496         struct st7703 *ctx = data;
497         struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
498
499         DRM_DEV_DEBUG_DRIVER(ctx->dev, "Setting all pixels on\n");
500         dsi_generic_write_seq(dsi, ST7703_CMD_ALL_PIXEL_ON);
501         msleep(val * 1000);
502         /* Reset the panel to get video back */
503         drm_panel_disable(&ctx->panel);
504         drm_panel_unprepare(&ctx->panel);
505         drm_panel_prepare(&ctx->panel);
506         drm_panel_enable(&ctx->panel);
507
508         return 0;
509 }
510
511 DEFINE_SIMPLE_ATTRIBUTE(allpixelson_fops, NULL,
512                         allpixelson_set, "%llu\n");
513
514 static void st7703_debugfs_init(struct st7703 *ctx)
515 {
516         ctx->debugfs = debugfs_create_dir(DRV_NAME, NULL);
517
518         debugfs_create_file("allpixelson", 0600, ctx->debugfs, ctx,
519                             &allpixelson_fops);
520 }
521
522 static void st7703_debugfs_remove(struct st7703 *ctx)
523 {
524         debugfs_remove_recursive(ctx->debugfs);
525         ctx->debugfs = NULL;
526 }
527
528 static int st7703_probe(struct mipi_dsi_device *dsi)
529 {
530         struct device *dev = &dsi->dev;
531         struct st7703 *ctx;
532         int ret;
533
534         ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
535         if (!ctx)
536                 return -ENOMEM;
537
538         ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
539         if (IS_ERR(ctx->reset_gpio)) {
540                 DRM_DEV_ERROR(dev, "cannot get reset gpio\n");
541                 return PTR_ERR(ctx->reset_gpio);
542         }
543
544         mipi_dsi_set_drvdata(dsi, ctx);
545
546         ctx->dev = dev;
547         ctx->desc = of_device_get_match_data(dev);
548
549         dsi->mode_flags = ctx->desc->mode_flags;
550         dsi->format = ctx->desc->format;
551         dsi->lanes = ctx->desc->lanes;
552
553         ctx->vcc = devm_regulator_get(dev, "vcc");
554         if (IS_ERR(ctx->vcc)) {
555                 ret = PTR_ERR(ctx->vcc);
556                 if (ret != -EPROBE_DEFER)
557                         DRM_DEV_ERROR(dev,
558                                       "Failed to request vcc regulator: %d\n",
559                                       ret);
560                 return ret;
561         }
562         ctx->iovcc = devm_regulator_get(dev, "iovcc");
563         if (IS_ERR(ctx->iovcc)) {
564                 ret = PTR_ERR(ctx->iovcc);
565                 if (ret != -EPROBE_DEFER)
566                         DRM_DEV_ERROR(dev,
567                                       "Failed to request iovcc regulator: %d\n",
568                                       ret);
569                 return ret;
570         }
571
572         drm_panel_init(&ctx->panel, dev, &st7703_drm_funcs,
573                        DRM_MODE_CONNECTOR_DSI);
574
575         ret = drm_panel_of_backlight(&ctx->panel);
576         if (ret)
577                 return ret;
578
579         drm_panel_add(&ctx->panel);
580
581         ret = mipi_dsi_attach(dsi);
582         if (ret < 0) {
583                 DRM_DEV_ERROR(dev,
584                               "mipi_dsi_attach failed (%d). Is host ready?\n",
585                               ret);
586                 drm_panel_remove(&ctx->panel);
587                 return ret;
588         }
589
590         DRM_DEV_INFO(dev, "%ux%u@%u %ubpp dsi %udl - ready\n",
591                      ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,
592                      drm_mode_vrefresh(ctx->desc->mode),
593                      mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes);
594
595         st7703_debugfs_init(ctx);
596         return 0;
597 }
598
599 static void st7703_shutdown(struct mipi_dsi_device *dsi)
600 {
601         struct st7703 *ctx = mipi_dsi_get_drvdata(dsi);
602         int ret;
603
604         ret = drm_panel_unprepare(&ctx->panel);
605         if (ret < 0)
606                 DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n",
607                               ret);
608
609         ret = drm_panel_disable(&ctx->panel);
610         if (ret < 0)
611                 DRM_DEV_ERROR(&dsi->dev, "Failed to disable panel: %d\n",
612                               ret);
613 }
614
615 static int st7703_remove(struct mipi_dsi_device *dsi)
616 {
617         struct st7703 *ctx = mipi_dsi_get_drvdata(dsi);
618         int ret;
619
620         st7703_shutdown(dsi);
621
622         ret = mipi_dsi_detach(dsi);
623         if (ret < 0)
624                 DRM_DEV_ERROR(&dsi->dev, "Failed to detach from DSI host: %d\n",
625                               ret);
626
627         drm_panel_remove(&ctx->panel);
628
629         st7703_debugfs_remove(ctx);
630
631         return 0;
632 }
633
634 static const struct of_device_id st7703_of_match[] = {
635         { .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc },
636         { .compatible = "xingbangda,xbd599", .data = &xbd599_desc },
637         { /* sentinel */ }
638 };
639 MODULE_DEVICE_TABLE(of, st7703_of_match);
640
641 static struct mipi_dsi_driver st7703_driver = {
642         .probe  = st7703_probe,
643         .remove = st7703_remove,
644         .shutdown = st7703_shutdown,
645         .driver = {
646                 .name = DRV_NAME,
647                 .of_match_table = st7703_of_match,
648         },
649 };
650 module_mipi_dsi_driver(st7703_driver);
651
652 MODULE_AUTHOR("Guido Günther <agx@sigxcpu.org>");
653 MODULE_DESCRIPTION("DRM driver for Sitronix ST7703 based MIPI DSI panels");
654 MODULE_LICENSE("GPL v2");