1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree: 4 * Copyright (c) 2013, The Linux Foundation. All rights reserved. 5 * Copyright (c) 2025, Eugene Lepshy <fekz115@gmail.com> 6 * Copyright (c) 2025, Danila Tikhonov <danila@jiaxyga.com> 7 */ 8 9 #include <linux/backlight.h> 10 #include <linux/delay.h> 11 #include <linux/gpio/consumer.h> 12 #include <linux/mod_devicetable.h> 13 #include <linux/module.h> 14 #include <linux/regulator/consumer.h> 15 16 #include <video/mipi_display.h> 17 18 #include <drm/display/drm_dsc.h> 19 #include <drm/display/drm_dsc_helper.h> 20 #include <drm/drm_mipi_dsi.h> 21 #include <drm/drm_modes.h> 22 #include <drm/drm_panel.h> 23 #include <drm/drm_probe_helper.h> 24 25 struct visionox_rm692e5 { 26 struct drm_panel panel; 27 struct mipi_dsi_device *dsi; 28 struct drm_dsc_config dsc; 29 struct gpio_desc *reset_gpio; 30 struct regulator_bulk_data *supplies; 31 }; 32 33 static const struct regulator_bulk_data visionox_rm692e5_supplies[] = { 34 { .supply = "vddio" }, /* 1p8 */ 35 { .supply = "vdd" }, /* 3p3 */ 36 }; 37 38 static inline 39 struct visionox_rm692e5 *to_visionox_rm692e5(struct drm_panel *panel) 40 { 41 return container_of(panel, struct visionox_rm692e5, panel); 42 } 43 44 static void visionox_rm692e5_reset(struct visionox_rm692e5 *ctx) 45 { 46 gpiod_set_value_cansleep(ctx->reset_gpio, 0); 47 usleep_range(10000, 11000); 48 gpiod_set_value_cansleep(ctx->reset_gpio, 1); 49 usleep_range(1000, 2000); 50 gpiod_set_value_cansleep(ctx->reset_gpio, 0); 51 msleep(32); 52 } 53 54 static int visionox_rm692e5_on(struct visionox_rm692e5 *ctx) 55 { 56 struct mipi_dsi_device *dsi = ctx->dsi; 57 struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 58 59 dsi->mode_flags |= MIPI_DSI_MODE_LPM; 60 61 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0x40); 62 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xbd, 0x07); 63 mipi_dsi_usleep_range(&dsi_ctx, 17000, 18000); 64 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0xd2); 65 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x11); 66 mipi_dsi_dcs_set_display_brightness_multi(&dsi_ctx, 0x00ab); 67 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x52, 0x30); 68 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x09); 69 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x54, 0x60); 70 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x04); 71 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x56, 0x38); 72 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x00); 73 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x14); 74 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x02); 75 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x1c); 76 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5c, 0x02); 77 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x00); 78 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_SET_CABC_MIN_BRIGHTNESS, 0x20); 79 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x01); 80 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0xe8); 81 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x00); 82 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x07); 83 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x0c); 84 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x05); 85 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x0e); 86 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x05); 87 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x16); 88 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x18); 89 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x00); 90 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x10); 91 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0xf0); 92 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x07); 93 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x10); 94 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x20); 95 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x00); 96 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x06); 97 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x0f); 98 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x0f); 99 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x33); 100 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x0e); 101 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x1c); 102 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x2a); 103 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x38); 104 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x46); 105 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x54); 106 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x62); 107 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7b, 0x69); 108 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7c, 0x70); 109 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x77); 110 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x79); 111 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7f, 0x7b); 112 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x7d); 113 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x7e); 114 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x82, 0x01); 115 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x83, 0x02); 116 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x84, 0x22); 117 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x85, 0x00); 118 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x86, 0x2a); 119 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x87, 0x40); 120 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x88, 0x2a); 121 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x89, 0xbe); 122 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8a, 0x3a); 123 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8b, 0xfc); 124 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8c, 0x3a); 125 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8d, 0xfa); 126 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8e, 0x3a); 127 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8f, 0xf8); 128 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x90, 0x3b); 129 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x91, 0x38); 130 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x92, 0x3b); 131 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x93, 0x78); 132 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x94, 0x3b); 133 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x95, 0xb6); 134 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x96, 0x4b); 135 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x97, 0xf6); 136 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x98, 0x4c); 137 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x99, 0x34); 138 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9a, 0x4c); 139 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9b, 0x74); 140 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9c, 0x5c); 141 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9d, 0x74); 142 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9e, 0x8c); 143 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9f, 0xf4); 144 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_READ_PPS_START, 0x02); 145 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa3, 0x1c); 146 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa4, 0x00); 147 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa5, 0x00); 148 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa6, 0x00); 149 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa7, 0x00); 150 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_READ_PPS_CONTINUE, 0x00); 151 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xaa, 0x00); 152 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xa0, 0x80); 153 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0xa1); 154 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xcd, 0x6b); 155 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xce, 0xbb); 156 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0xd1); 157 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb4, 0x01); 158 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0x38); 159 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x0f); 160 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x0f); 161 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0x00); 162 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfa, 0x01); 163 mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xc2, 0x08); 164 mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK); 165 mipi_dsi_dcs_set_display_brightness_multi(&dsi_ctx, 0x000d); 166 mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); 167 mipi_dsi_msleep(&dsi_ctx, 50); 168 mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); 169 mipi_dsi_usleep_range(&dsi_ctx, 1000, 2000); 170 171 return dsi_ctx.accum_err; 172 } 173 174 static int visionox_rm692e5_disable(struct drm_panel *panel) 175 { 176 struct visionox_rm692e5 *ctx = to_visionox_rm692e5(panel); 177 struct mipi_dsi_device *dsi = ctx->dsi; 178 struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 179 180 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; 181 182 mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); 183 mipi_dsi_usleep_range(&dsi_ctx, 1000, 2000); 184 mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); 185 mipi_dsi_usleep_range(&dsi_ctx, 1000, 2000); 186 187 return dsi_ctx.accum_err; 188 } 189 190 static int visionox_rm692e5_prepare(struct drm_panel *panel) 191 { 192 struct visionox_rm692e5 *ctx = to_visionox_rm692e5(panel); 193 struct drm_dsc_picture_parameter_set pps; 194 struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; 195 int ret; 196 197 ret = regulator_bulk_enable(ARRAY_SIZE(visionox_rm692e5_supplies), 198 ctx->supplies); 199 if (ret < 0) 200 return ret; 201 202 visionox_rm692e5_reset(ctx); 203 204 ret = visionox_rm692e5_on(ctx); 205 if (ret < 0) { 206 gpiod_set_value_cansleep(ctx->reset_gpio, 1); 207 goto err; 208 } 209 210 drm_dsc_pps_payload_pack(&pps, &ctx->dsc); 211 mipi_dsi_picture_parameter_set_multi(&dsi_ctx, &pps); 212 mipi_dsi_compression_mode_ext_multi(&dsi_ctx, true, MIPI_DSI_COMPRESSION_DSC, 0); 213 214 mipi_dsi_msleep(&dsi_ctx, 28); 215 216 if (dsi_ctx.accum_err < 0) { 217 ret = dsi_ctx.accum_err; 218 goto err; 219 } 220 221 return dsi_ctx.accum_err; 222 err: 223 regulator_bulk_disable(ARRAY_SIZE(visionox_rm692e5_supplies), 224 ctx->supplies); 225 return ret; 226 } 227 228 static int visionox_rm692e5_unprepare(struct drm_panel *panel) 229 { 230 struct visionox_rm692e5 *ctx = to_visionox_rm692e5(panel); 231 232 gpiod_set_value_cansleep(ctx->reset_gpio, 1); 233 regulator_bulk_disable(ARRAY_SIZE(visionox_rm692e5_supplies), 234 ctx->supplies); 235 236 return 0; 237 } 238 239 static const struct drm_display_mode visionox_rm692e5_modes[] = { 240 /* Let's initialize the highest frequency first */ 241 { /* 120Hz mode */ 242 .clock = (1080 + 26 + 39 + 36) * (2400 + 16 + 21 + 16) * 120 / 1000, 243 .hdisplay = 1080, 244 .hsync_start = 1080 + 26, 245 .hsync_end = 1080 + 26 + 39, 246 .htotal = 1080 + 26 + 39 + 36, 247 .vdisplay = 2400, 248 .vsync_start = 2400 + 16, 249 .vsync_end = 2400 + 16 + 21, 250 .vtotal = 2400 + 16 + 21 + 16, 251 .width_mm = 68, 252 .height_mm = 152, 253 .type = DRM_MODE_TYPE_DRIVER, 254 }, 255 { /* 90Hz mode */ 256 .clock = (1080 + 26 + 39 + 36) * (2400 + 16 + 21 + 16) * 90 / 1000, 257 .hdisplay = 1080, 258 .hsync_start = 1080 + 26, 259 .hsync_end = 1080 + 26 + 39, 260 .htotal = 1080 + 26 + 39 + 36, 261 .vdisplay = 2400, 262 .vsync_start = 2400 + 16, 263 .vsync_end = 2400 + 16 + 21, 264 .vtotal = 2400 + 16 + 21 + 16, 265 .width_mm = 68, 266 .height_mm = 152, 267 .type = DRM_MODE_TYPE_DRIVER, 268 }, 269 { /* 60Hz mode */ 270 .clock = (1080 + 26 + 39 + 36) * (2400 + 16 + 21 + 16) * 60 / 1000, 271 .hdisplay = 1080, 272 .hsync_start = 1080 + 26, 273 .hsync_end = 1080 + 26 + 39, 274 .htotal = 1080 + 26 + 39 + 36, 275 .vdisplay = 2400, 276 .vsync_start = 2400 + 16, 277 .vsync_end = 2400 + 16 + 21, 278 .vtotal = 2400 + 16 + 21 + 16, 279 .width_mm = 68, 280 .height_mm = 152, 281 .type = DRM_MODE_TYPE_DRIVER, 282 }, 283 }; 284 285 static int visionox_rm692e5_get_modes(struct drm_panel *panel, 286 struct drm_connector *connector) 287 { 288 int count = 0; 289 290 for (int i = 0; i < ARRAY_SIZE(visionox_rm692e5_modes); i++) 291 count += drm_connector_helper_get_modes_fixed(connector, 292 &visionox_rm692e5_modes[i]); 293 294 return count; 295 } 296 297 static const struct drm_panel_funcs visionox_rm692e5_panel_funcs = { 298 .prepare = visionox_rm692e5_prepare, 299 .unprepare = visionox_rm692e5_unprepare, 300 .disable = visionox_rm692e5_disable, 301 .get_modes = visionox_rm692e5_get_modes, 302 }; 303 304 static int visionox_rm692e5_bl_update_status(struct backlight_device *bl) 305 { 306 struct mipi_dsi_device *dsi = bl_get_data(bl); 307 u16 brightness = backlight_get_brightness(bl); 308 int ret; 309 310 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; 311 312 ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); 313 if (ret < 0) 314 return ret; 315 316 dsi->mode_flags |= MIPI_DSI_MODE_LPM; 317 318 return 0; 319 } 320 321 static int visionox_rm692e5_bl_get_brightness(struct backlight_device *bl) 322 { 323 struct mipi_dsi_device *dsi = bl_get_data(bl); 324 u16 brightness; 325 int ret; 326 327 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; 328 329 ret = mipi_dsi_dcs_get_display_brightness_large(dsi, &brightness); 330 if (ret < 0) 331 return ret; 332 333 dsi->mode_flags |= MIPI_DSI_MODE_LPM; 334 335 return brightness; 336 } 337 338 static const struct backlight_ops visionox_rm692e5_bl_ops = { 339 .update_status = visionox_rm692e5_bl_update_status, 340 .get_brightness = visionox_rm692e5_bl_get_brightness, 341 }; 342 343 static struct backlight_device * 344 visionox_rm692e5_create_backlight(struct mipi_dsi_device *dsi) 345 { 346 struct device *dev = &dsi->dev; 347 const struct backlight_properties props = { 348 .type = BACKLIGHT_RAW, 349 .brightness = 2047, 350 .max_brightness = 4095, 351 }; 352 353 return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, 354 &visionox_rm692e5_bl_ops, &props); 355 } 356 357 static int visionox_rm692e5_probe(struct mipi_dsi_device *dsi) 358 { 359 struct device *dev = &dsi->dev; 360 struct visionox_rm692e5 *ctx; 361 int ret; 362 363 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 364 if (!ctx) 365 return -ENOMEM; 366 367 ret = devm_regulator_bulk_get_const(&dsi->dev, 368 ARRAY_SIZE(visionox_rm692e5_supplies), 369 visionox_rm692e5_supplies, 370 &ctx->supplies); 371 if (ret < 0) 372 return dev_err_probe(dev, ret, "Failed to get regulators\n"); 373 374 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); 375 if (IS_ERR(ctx->reset_gpio)) 376 return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), 377 "Failed to get reset-gpios\n"); 378 379 ctx->dsi = dsi; 380 mipi_dsi_set_drvdata(dsi, ctx); 381 382 dsi->lanes = 4; 383 dsi->format = MIPI_DSI_FMT_RGB888; 384 dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS; 385 386 drm_panel_init(&ctx->panel, dev, &visionox_rm692e5_panel_funcs, 387 DRM_MODE_CONNECTOR_DSI); 388 ctx->panel.prepare_prev_first = true; 389 390 ctx->panel.backlight = visionox_rm692e5_create_backlight(dsi); 391 if (IS_ERR(ctx->panel.backlight)) 392 return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), 393 "Failed to create backlight\n"); 394 395 drm_panel_add(&ctx->panel); 396 397 dsi->dsc = &ctx->dsc; 398 ctx->dsc.dsc_version_major = 1; 399 ctx->dsc.dsc_version_minor = 1; 400 ctx->dsc.slice_height = 20; 401 ctx->dsc.slice_width = 540; 402 ctx->dsc.slice_count = 1080 / ctx->dsc.slice_width; 403 ctx->dsc.bits_per_component = 10; 404 ctx->dsc.bits_per_pixel = 8 << 4; 405 ctx->dsc.block_pred_enable = true; 406 407 ret = devm_mipi_dsi_attach(dev, dsi); 408 if (ret < 0) { 409 drm_panel_remove(&ctx->panel); 410 return dev_err_probe(dev, ret, "Failed to attach to DSI host\n"); 411 } 412 413 return 0; 414 } 415 416 static void visionox_rm692e5_remove(struct mipi_dsi_device *dsi) 417 { 418 struct visionox_rm692e5 *ctx = mipi_dsi_get_drvdata(dsi); 419 420 drm_panel_remove(&ctx->panel); 421 } 422 423 static const struct of_device_id visionox_rm692e5_of_match[] = { 424 { .compatible = "visionox,rm692e5" }, 425 { /* sentinel */ } 426 }; 427 MODULE_DEVICE_TABLE(of, visionox_rm692e5_of_match); 428 429 static struct mipi_dsi_driver visionox_rm692e5_driver = { 430 .probe = visionox_rm692e5_probe, 431 .remove = visionox_rm692e5_remove, 432 .driver = { 433 .name = "panel-visionox-rm692e5", 434 .of_match_table = visionox_rm692e5_of_match, 435 }, 436 }; 437 module_mipi_dsi_driver(visionox_rm692e5_driver); 438 439 MODULE_AUTHOR("Eugene Lepshy <fekz115@gmail.com>"); 440 MODULE_AUTHOR("Danila Tikhonov <danila@jiaxyga.com>"); 441 MODULE_DESCRIPTION("DRM driver for Visionox RM692E5 cmd mode dsi panel"); 442 MODULE_LICENSE("GPL"); 443