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"); 655