1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for panels based on Sitronix ST7703 controller, souch as:
5 * - Rocktech jh057n00900 5.5" MIPI-DSI panel
7 * Copyright (C) Purism SPC 2019
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>
19 #include <video/display_timing.h>
20 #include <video/mipi_display.h>
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>
27 #define DRV_NAME "panel-sitronix-st7703"
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
54 struct drm_panel panel
;
55 struct gpio_desc
*reset_gpio
;
56 struct regulator
*vcc
;
57 struct regulator
*iovcc
;
60 struct dentry
*debugfs
;
61 const struct st7703_panel_desc
*desc
;
64 struct st7703_panel_desc
{
65 const struct drm_display_mode
*mode
;
67 unsigned long mode_flags
;
68 enum mipi_dsi_pixel_format format
;
69 int (*init_sequence
)(struct st7703
*ctx
);
72 static inline struct st7703
*panel_to_st7703(struct drm_panel
*panel
)
74 return container_of(panel
, struct st7703
, panel
);
77 #define dsi_generic_write_seq(dsi, seq...) do { \
78 static const u8 d[] = { seq }; \
80 ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \
85 static int jh057n_init_sequence(struct st7703
*ctx
)
87 struct mipi_dsi_device
*dsi
= to_mipi_dsi_device(ctx
->dev
);
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.
94 dsi_generic_write_seq(dsi
, ST7703_CMD_SETEXTC
,
96 dsi_generic_write_seq(dsi
, ST7703_CMD_SETRGBIF
,
97 0x10, 0x10, 0x05, 0x05, 0x03, 0xFF, 0x00, 0x00,
99 dsi_generic_write_seq(dsi
, ST7703_CMD_SETSCR
,
100 0x73, 0x73, 0x50, 0x50, 0x00, 0x00, 0x08, 0x70,
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);
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,
142 static const struct drm_display_mode jh057n00900_mode
= {
144 .hsync_start
= 720 + 90,
145 .hsync_end
= 720 + 90 + 20,
146 .htotal
= 720 + 90 + 20 + 20,
148 .vsync_start
= 1440 + 20,
149 .vsync_end
= 1440 + 20 + 4,
150 .vtotal
= 1440 + 20 + 4 + 12,
152 .flags
= DRM_MODE_FLAG_NHSYNC
| DRM_MODE_FLAG_NVSYNC
,
157 struct st7703_panel_desc jh057n00900_panel_desc
= {
158 .mode
= &jh057n00900_mode
,
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
,
166 #define dsi_dcs_write_seq(dsi, cmd, seq...) do { \
167 static const u8 d[] = { seq }; \
169 ret = mipi_dsi_dcs_write(dsi, cmd, d, ARRAY_SIZE(d)); \
175 static int xbd599_init_sequence(struct st7703
*ctx
)
177 struct mipi_dsi_device
*dsi
= to_mipi_dsi_device(ctx
->dev
);
180 * Init sequence was supplied by the panel vendor.
183 /* Magic sequence to unlock user commands below. */
184 dsi_dcs_write_seq(dsi
, ST7703_CMD_SETEXTC
, 0xF1, 0x12, 0x83);
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);
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 */);
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 */
215 /* Source driving settings. */
216 dsi_dcs_write_seq(dsi
, ST7703_CMD_SETSCR
,
221 0x00, /* SCR[31,24] */
222 0xC0, /* SCR[23,16] */
223 0x08, /* SCR[15,8] */
225 0x00 /* Undocumented */);
227 /* NVDDD_SEL = -1.8V, VDDD_SEL = out of range (possibly 1.9V?) */
228 dsi_dcs_write_seq(dsi
, ST7703_CMD_SETVDC
, 0x4E);
231 * SS_PANEL = 1 (reverse scan), GS_PANEL = 0 (normal scan)
232 * REV_PANEL = 1 (normally black panel), BGR_PANEL = 1 (BGR)
234 dsi_dcs_write_seq(dsi
, ST7703_CMD_SETPANEL
, 0x0B);
236 /* Zig-Zag Type C column inversion. */
237 dsi_dcs_write_seq(dsi
, ST7703_CMD_SETCYC
, 0x80);
239 /* Set display resolution. */
240 dsi_dcs_write_seq(dsi
, ST7703_CMD_SETDISP
,
242 0x12, /* RES_V_LSB = 0, BLK_CON = VSSD,
245 0xF0 /* WHITE_GND_EN = 1 (GND),
246 * WHITE_FRAME_SEL = 7 frames,
250 dsi_dcs_write_seq(dsi
, ST7703_CMD_SETEQ
,
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
270 /* Undocumented command. */
271 dsi_dcs_write_seq(dsi
, ST7703_CMD_UNKNOWN_C6
, 0x01, 0x00, 0xFF, 0xFF, 0x00);
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 */
279 0xF1, /* APS = 1 (small),
280 * VGL_DET_EN = 1, VGH_DET_EN = 1,
281 * VGL_TURBO = 1, VGH_TURBO = 1
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) */);
290 /* Reference voltage. */
291 dsi_dcs_write_seq(dsi
, ST7703_CMD_SETBGP
,
292 0x07, /* VREF_SEL = 4.2V */
293 0x07 /* NVREF_SEL = 4.2V */);
296 dsi_dcs_write_seq(dsi
, ST7703_CMD_SETVCOM
,
297 0x2C, /* VCOMDC_F = -0.67V */
298 0x2C /* VCOMDC_B = -0.67V */);
300 /* Undocumented command. */
301 dsi_dcs_write_seq(dsi
, ST7703_CMD_UNKNOWN_BF
, 0x02, 0x11, 0x00);
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);
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);
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,
336 static const struct drm_display_mode xbd599_mode
= {
338 .hsync_start
= 720 + 40,
339 .hsync_end
= 720 + 40 + 40,
340 .htotal
= 720 + 40 + 40 + 40,
342 .vsync_start
= 1440 + 18,
343 .vsync_end
= 1440 + 18 + 10,
344 .vtotal
= 1440 + 18 + 10 + 17,
346 .flags
= DRM_MODE_FLAG_NHSYNC
| DRM_MODE_FLAG_NVSYNC
,
351 static const struct st7703_panel_desc xbd599_desc
= {
352 .mode
= &xbd599_mode
,
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
,
359 static int st7703_enable(struct drm_panel
*panel
)
361 struct st7703
*ctx
= panel_to_st7703(panel
);
362 struct mipi_dsi_device
*dsi
= to_mipi_dsi_device(ctx
->dev
);
365 ret
= ctx
->desc
->init_sequence(ctx
);
367 DRM_DEV_ERROR(ctx
->dev
, "Panel init sequence failed: %d\n",
374 ret
= mipi_dsi_dcs_exit_sleep_mode(dsi
);
376 DRM_DEV_ERROR(ctx
->dev
, "Failed to exit sleep mode: %d\n", ret
);
380 /* Panel is operational 120 msec after reset */
383 ret
= mipi_dsi_dcs_set_display_on(dsi
);
387 DRM_DEV_DEBUG_DRIVER(ctx
->dev
, "Panel init sequence done\n");
392 static int st7703_disable(struct drm_panel
*panel
)
394 struct st7703
*ctx
= panel_to_st7703(panel
);
395 struct mipi_dsi_device
*dsi
= to_mipi_dsi_device(ctx
->dev
);
398 ret
= mipi_dsi_dcs_set_display_off(dsi
);
400 DRM_DEV_ERROR(ctx
->dev
,
401 "Failed to turn off the display: %d\n", ret
);
403 ret
= mipi_dsi_dcs_enter_sleep_mode(dsi
);
405 DRM_DEV_ERROR(ctx
->dev
,
406 "Failed to enter sleep mode: %d\n", ret
);
411 static int st7703_unprepare(struct drm_panel
*panel
)
413 struct st7703
*ctx
= panel_to_st7703(panel
);
418 gpiod_set_value_cansleep(ctx
->reset_gpio
, 1);
419 regulator_disable(ctx
->iovcc
);
420 regulator_disable(ctx
->vcc
);
421 ctx
->prepared
= false;
426 static int st7703_prepare(struct drm_panel
*panel
)
428 struct st7703
*ctx
= panel_to_st7703(panel
);
434 DRM_DEV_DEBUG_DRIVER(ctx
->dev
, "Resetting the panel\n");
435 ret
= regulator_enable(ctx
->vcc
);
437 DRM_DEV_ERROR(ctx
->dev
,
438 "Failed to enable vcc supply: %d\n", ret
);
441 ret
= regulator_enable(ctx
->iovcc
);
443 DRM_DEV_ERROR(ctx
->dev
,
444 "Failed to enable iovcc supply: %d\n", ret
);
448 gpiod_set_value_cansleep(ctx
->reset_gpio
, 1);
449 usleep_range(20, 40);
450 gpiod_set_value_cansleep(ctx
->reset_gpio
, 0);
453 ctx
->prepared
= true;
458 regulator_disable(ctx
->vcc
);
462 static int st7703_get_modes(struct drm_panel
*panel
,
463 struct drm_connector
*connector
)
465 struct st7703
*ctx
= panel_to_st7703(panel
);
466 struct drm_display_mode
*mode
;
468 mode
= drm_mode_duplicate(connector
->dev
, ctx
->desc
->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
));
476 drm_mode_set_name(mode
);
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
);
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
,
494 static int allpixelson_set(void *data
, u64 val
)
496 struct st7703
*ctx
= data
;
497 struct mipi_dsi_device
*dsi
= to_mipi_dsi_device(ctx
->dev
);
499 DRM_DEV_DEBUG_DRIVER(ctx
->dev
, "Setting all pixels on\n");
500 dsi_generic_write_seq(dsi
, ST7703_CMD_ALL_PIXEL_ON
);
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
);
511 DEFINE_SIMPLE_ATTRIBUTE(allpixelson_fops
, NULL
,
512 allpixelson_set
, "%llu\n");
514 static void st7703_debugfs_init(struct st7703
*ctx
)
516 ctx
->debugfs
= debugfs_create_dir(DRV_NAME
, NULL
);
518 debugfs_create_file("allpixelson", 0600, ctx
->debugfs
, ctx
,
522 static void st7703_debugfs_remove(struct st7703
*ctx
)
524 debugfs_remove_recursive(ctx
->debugfs
);
528 static int st7703_probe(struct mipi_dsi_device
*dsi
)
530 struct device
*dev
= &dsi
->dev
;
534 ctx
= devm_kzalloc(dev
, sizeof(*ctx
), GFP_KERNEL
);
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
);
544 mipi_dsi_set_drvdata(dsi
, ctx
);
547 ctx
->desc
= of_device_get_match_data(dev
);
549 dsi
->mode_flags
= ctx
->desc
->mode_flags
;
550 dsi
->format
= ctx
->desc
->format
;
551 dsi
->lanes
= ctx
->desc
->lanes
;
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
)
558 "Failed to request vcc regulator: %d\n",
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
)
567 "Failed to request iovcc regulator: %d\n",
572 drm_panel_init(&ctx
->panel
, dev
, &st7703_drm_funcs
,
573 DRM_MODE_CONNECTOR_DSI
);
575 ret
= drm_panel_of_backlight(&ctx
->panel
);
579 drm_panel_add(&ctx
->panel
);
581 ret
= mipi_dsi_attach(dsi
);
584 "mipi_dsi_attach failed (%d). Is host ready?\n",
586 drm_panel_remove(&ctx
->panel
);
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
);
595 st7703_debugfs_init(ctx
);
599 static void st7703_shutdown(struct mipi_dsi_device
*dsi
)
601 struct st7703
*ctx
= mipi_dsi_get_drvdata(dsi
);
604 ret
= drm_panel_unprepare(&ctx
->panel
);
606 DRM_DEV_ERROR(&dsi
->dev
, "Failed to unprepare panel: %d\n",
609 ret
= drm_panel_disable(&ctx
->panel
);
611 DRM_DEV_ERROR(&dsi
->dev
, "Failed to disable panel: %d\n",
615 static int st7703_remove(struct mipi_dsi_device
*dsi
)
617 struct st7703
*ctx
= mipi_dsi_get_drvdata(dsi
);
620 st7703_shutdown(dsi
);
622 ret
= mipi_dsi_detach(dsi
);
624 DRM_DEV_ERROR(&dsi
->dev
, "Failed to detach from DSI host: %d\n",
627 drm_panel_remove(&ctx
->panel
);
629 st7703_debugfs_remove(ctx
);
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
},
639 MODULE_DEVICE_TABLE(of
, st7703_of_match
);
641 static struct mipi_dsi_driver st7703_driver
= {
642 .probe
= st7703_probe
,
643 .remove
= st7703_remove
,
644 .shutdown
= st7703_shutdown
,
647 .of_match_table
= st7703_of_match
,
650 module_mipi_dsi_driver(st7703_driver
);
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");