Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/panel: Add support for S6E63J0X03 panel

This patch adds MIPI-DSI based S6E63J0X03 AMOLED LCD panel driver
which uses MIPI DSI bus to communicate with panel. The panel has
320×320 resolution in 1.63" physical panel. This panel is used in
Samsung Galaxy Gear 2.

Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1499912443-3671-3-git-send-email-hoegeun.kwon@samsung.com

authored by

Hoegeun Kwon and committed by
Thierry Reding
2a05177d a4e6f1c4

+540
+7
drivers/gpu/drm/panel/Kconfig
··· 80 80 depends on BACKLIGHT_CLASS_DEVICE 81 81 select VIDEOMODE_HELPERS 82 82 83 + config DRM_PANEL_SAMSUNG_S6E63J0X03 84 + tristate "Samsung S6E63J0X03 DSI command mode panel" 85 + depends on OF 86 + depends on DRM_MIPI_DSI 87 + depends on BACKLIGHT_CLASS_DEVICE 88 + select VIDEOMODE_HELPERS 89 + 83 90 config DRM_PANEL_SAMSUNG_S6E8AA0 84 91 tristate "Samsung S6E8AA0 DSI video mode panel" 85 92 depends on OF
+1
drivers/gpu/drm/panel/Makefile
··· 6 6 obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o 7 7 obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o 8 8 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o 9 + obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o 9 10 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o 10 11 obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o 11 12 obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
+532
drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c
··· 1 + /* 2 + * MIPI-DSI based S6E63J0X03 AMOLED lcd 1.63 inch panel driver. 3 + * 4 + * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd 5 + * 6 + * Inki Dae <inki.dae@samsung.com> 7 + * Hoegeun Kwon <hoegeun.kwon@samsung.com> 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License version 2 as 11 + * published by the Free Software Foundation. 12 + */ 13 + 14 + #include <drm/drmP.h> 15 + #include <drm/drm_mipi_dsi.h> 16 + #include <drm/drm_panel.h> 17 + #include <linux/backlight.h> 18 + #include <linux/gpio/consumer.h> 19 + #include <linux/regulator/consumer.h> 20 + #include <video/mipi_display.h> 21 + 22 + #define MCS_LEVEL2_KEY 0xf0 23 + #define MCS_MTP_KEY 0xf1 24 + #define MCS_MTP_SET3 0xd4 25 + 26 + #define MAX_BRIGHTNESS 100 27 + #define DEFAULT_BRIGHTNESS 80 28 + 29 + #define NUM_GAMMA_STEPS 9 30 + #define GAMMA_CMD_CNT 28 31 + 32 + #define FIRST_COLUMN 20 33 + 34 + struct s6e63j0x03 { 35 + struct device *dev; 36 + struct drm_panel panel; 37 + struct backlight_device *bl_dev; 38 + 39 + struct regulator_bulk_data supplies[2]; 40 + struct gpio_desc *reset_gpio; 41 + }; 42 + 43 + static const struct drm_display_mode default_mode = { 44 + .clock = 4649, 45 + .hdisplay = 320, 46 + .hsync_start = 320 + 1, 47 + .hsync_end = 320 + 1 + 1, 48 + .htotal = 320 + 1 + 1 + 1, 49 + .vdisplay = 320, 50 + .vsync_start = 320 + 150, 51 + .vsync_end = 320 + 150 + 1, 52 + .vtotal = 320 + 150 + 1 + 2, 53 + .vrefresh = 30, 54 + .flags = 0, 55 + }; 56 + 57 + static const unsigned char gamma_tbl[NUM_GAMMA_STEPS][GAMMA_CMD_CNT] = { 58 + { /* Gamma 10 */ 59 + MCS_MTP_SET3, 60 + 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x52, 0x6b, 0x6f, 0x26, 61 + 0x28, 0x2d, 0x28, 0x26, 0x27, 0x33, 0x34, 0x32, 0x36, 0x36, 62 + 0x35, 0x00, 0xab, 0x00, 0xae, 0x00, 0xbf 63 + }, 64 + { /* gamma 30 */ 65 + MCS_MTP_SET3, 66 + 0x00, 0x00, 0x00, 0x70, 0x7f, 0x7f, 0x4e, 0x64, 0x69, 0x26, 67 + 0x27, 0x2a, 0x28, 0x29, 0x27, 0x31, 0x32, 0x31, 0x35, 0x34, 68 + 0x35, 0x00, 0xc4, 0x00, 0xca, 0x00, 0xdc 69 + }, 70 + { /* gamma 60 */ 71 + MCS_MTP_SET3, 72 + 0x00, 0x00, 0x00, 0x65, 0x7b, 0x7d, 0x5f, 0x67, 0x68, 0x2a, 73 + 0x28, 0x29, 0x28, 0x2a, 0x27, 0x31, 0x2f, 0x30, 0x34, 0x33, 74 + 0x34, 0x00, 0xd9, 0x00, 0xe4, 0x00, 0xf5 75 + }, 76 + { /* gamma 90 */ 77 + MCS_MTP_SET3, 78 + 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x71, 0x67, 0x6a, 0x6c, 0x29, 79 + 0x28, 0x28, 0x28, 0x29, 0x27, 0x30, 0x2e, 0x30, 0x32, 0x31, 80 + 0x31, 0x00, 0xea, 0x00, 0xf6, 0x01, 0x09 81 + }, 82 + { /* gamma 120 */ 83 + MCS_MTP_SET3, 84 + 0x00, 0x00, 0x00, 0x3d, 0x66, 0x68, 0x69, 0x69, 0x69, 0x28, 85 + 0x28, 0x27, 0x28, 0x28, 0x27, 0x30, 0x2e, 0x2f, 0x31, 0x31, 86 + 0x30, 0x00, 0xf9, 0x01, 0x05, 0x01, 0x1b 87 + }, 88 + { /* gamma 150 */ 89 + MCS_MTP_SET3, 90 + 0x00, 0x00, 0x00, 0x31, 0x51, 0x53, 0x66, 0x66, 0x67, 0x28, 91 + 0x29, 0x27, 0x28, 0x27, 0x27, 0x2e, 0x2d, 0x2e, 0x31, 0x31, 92 + 0x30, 0x01, 0x04, 0x01, 0x11, 0x01, 0x29 93 + }, 94 + { /* gamma 200 */ 95 + MCS_MTP_SET3, 96 + 0x00, 0x00, 0x00, 0x2f, 0x4f, 0x51, 0x67, 0x65, 0x65, 0x29, 97 + 0x2a, 0x28, 0x27, 0x25, 0x26, 0x2d, 0x2c, 0x2c, 0x30, 0x30, 98 + 0x30, 0x01, 0x14, 0x01, 0x23, 0x01, 0x3b 99 + }, 100 + { /* gamma 240 */ 101 + MCS_MTP_SET3, 102 + 0x00, 0x00, 0x00, 0x2c, 0x4d, 0x50, 0x65, 0x63, 0x64, 0x2a, 103 + 0x2c, 0x29, 0x26, 0x24, 0x25, 0x2c, 0x2b, 0x2b, 0x30, 0x30, 104 + 0x30, 0x01, 0x1e, 0x01, 0x2f, 0x01, 0x47 105 + }, 106 + { /* gamma 300 */ 107 + MCS_MTP_SET3, 108 + 0x00, 0x00, 0x00, 0x38, 0x61, 0x64, 0x65, 0x63, 0x64, 0x28, 109 + 0x2a, 0x27, 0x26, 0x23, 0x25, 0x2b, 0x2b, 0x2a, 0x30, 0x2f, 110 + 0x30, 0x01, 0x2d, 0x01, 0x3f, 0x01, 0x57 111 + } 112 + }; 113 + 114 + static inline struct s6e63j0x03 *panel_to_s6e63j0x03(struct drm_panel *panel) 115 + { 116 + return container_of(panel, struct s6e63j0x03, panel); 117 + } 118 + 119 + static inline ssize_t s6e63j0x03_dcs_write_seq(struct s6e63j0x03 *ctx, 120 + const void *seq, size_t len) 121 + { 122 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 123 + 124 + return mipi_dsi_dcs_write_buffer(dsi, seq, len); 125 + } 126 + 127 + #define s6e63j0x03_dcs_write_seq_static(ctx, seq...) \ 128 + ({ \ 129 + static const u8 d[] = { seq }; \ 130 + s6e63j0x03_dcs_write_seq(ctx, d, ARRAY_SIZE(d)); \ 131 + }) 132 + 133 + static inline int s6e63j0x03_enable_lv2_command(struct s6e63j0x03 *ctx) 134 + { 135 + return s6e63j0x03_dcs_write_seq_static(ctx, MCS_LEVEL2_KEY, 0x5a, 0x5a); 136 + } 137 + 138 + static inline int s6e63j0x03_apply_mtp_key(struct s6e63j0x03 *ctx, bool on) 139 + { 140 + if (on) 141 + return s6e63j0x03_dcs_write_seq_static(ctx, 142 + MCS_MTP_KEY, 0x5a, 0x5a); 143 + 144 + return s6e63j0x03_dcs_write_seq_static(ctx, MCS_MTP_KEY, 0xa5, 0xa5); 145 + } 146 + 147 + static int s6e63j0x03_power_on(struct s6e63j0x03 *ctx) 148 + { 149 + int ret; 150 + 151 + ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); 152 + if (ret < 0) 153 + return ret; 154 + 155 + msleep(30); 156 + 157 + gpiod_set_value(ctx->reset_gpio, 1); 158 + usleep_range(1000, 2000); 159 + gpiod_set_value(ctx->reset_gpio, 0); 160 + usleep_range(5000, 6000); 161 + 162 + return 0; 163 + } 164 + 165 + static int s6e63j0x03_power_off(struct s6e63j0x03 *ctx) 166 + { 167 + return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); 168 + } 169 + 170 + static unsigned int s6e63j0x03_get_brightness_index(unsigned int brightness) 171 + { 172 + unsigned int index; 173 + 174 + index = brightness / (MAX_BRIGHTNESS / NUM_GAMMA_STEPS); 175 + 176 + if (index >= NUM_GAMMA_STEPS) 177 + index = NUM_GAMMA_STEPS - 1; 178 + 179 + return index; 180 + } 181 + 182 + static int s6e63j0x03_update_gamma(struct s6e63j0x03 *ctx, 183 + unsigned int brightness) 184 + { 185 + struct backlight_device *bl_dev = ctx->bl_dev; 186 + unsigned int index = s6e63j0x03_get_brightness_index(brightness); 187 + int ret; 188 + 189 + ret = s6e63j0x03_apply_mtp_key(ctx, true); 190 + if (ret < 0) 191 + return ret; 192 + 193 + ret = s6e63j0x03_dcs_write_seq(ctx, gamma_tbl[index], GAMMA_CMD_CNT); 194 + if (ret < 0) 195 + return ret; 196 + 197 + ret = s6e63j0x03_apply_mtp_key(ctx, false); 198 + if (ret < 0) 199 + return ret; 200 + 201 + bl_dev->props.brightness = brightness; 202 + 203 + return 0; 204 + } 205 + 206 + static int s6e63j0x03_set_brightness(struct backlight_device *bl_dev) 207 + { 208 + struct s6e63j0x03 *ctx = bl_get_data(bl_dev); 209 + unsigned int brightness = bl_dev->props.brightness; 210 + 211 + return s6e63j0x03_update_gamma(ctx, brightness); 212 + } 213 + 214 + static const struct backlight_ops s6e63j0x03_bl_ops = { 215 + .update_status = s6e63j0x03_set_brightness, 216 + }; 217 + 218 + static int s6e63j0x03_disable(struct drm_panel *panel) 219 + { 220 + struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel); 221 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 222 + int ret; 223 + 224 + ret = mipi_dsi_dcs_set_display_off(dsi); 225 + if (ret < 0) 226 + return ret; 227 + 228 + ctx->bl_dev->props.power = FB_BLANK_NORMAL; 229 + 230 + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 231 + if (ret < 0) 232 + return ret; 233 + 234 + msleep(120); 235 + 236 + return 0; 237 + } 238 + 239 + static int s6e63j0x03_unprepare(struct drm_panel *panel) 240 + { 241 + struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel); 242 + int ret; 243 + 244 + ret = s6e63j0x03_power_off(ctx); 245 + if (ret < 0) 246 + return ret; 247 + 248 + ctx->bl_dev->props.power = FB_BLANK_POWERDOWN; 249 + 250 + return 0; 251 + } 252 + 253 + static int s6e63j0x03_panel_init(struct s6e63j0x03 *ctx) 254 + { 255 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 256 + int ret; 257 + 258 + ret = s6e63j0x03_enable_lv2_command(ctx); 259 + if (ret < 0) 260 + return ret; 261 + 262 + ret = s6e63j0x03_apply_mtp_key(ctx, true); 263 + if (ret < 0) 264 + return ret; 265 + 266 + /* set porch adjustment */ 267 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xf2, 0x1c, 0x28); 268 + if (ret < 0) 269 + return ret; 270 + 271 + /* set frame freq */ 272 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xb5, 0x00, 0x02, 0x00); 273 + if (ret < 0) 274 + return ret; 275 + 276 + /* set caset, paset */ 277 + ret = mipi_dsi_dcs_set_column_address(dsi, FIRST_COLUMN, 278 + default_mode.hdisplay - 1 + FIRST_COLUMN); 279 + if (ret < 0) 280 + return ret; 281 + 282 + ret = mipi_dsi_dcs_set_page_address(dsi, 0, default_mode.vdisplay - 1); 283 + if (ret < 0) 284 + return ret; 285 + 286 + /* set ltps timming 0, 1 */ 287 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xf8, 0x08, 0x08, 0x08, 0x17, 288 + 0x00, 0x2a, 0x02, 0x26, 0x00, 0x00, 0x02, 0x00, 0x00); 289 + if (ret < 0) 290 + return ret; 291 + 292 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xf7, 0x02); 293 + if (ret < 0) 294 + return ret; 295 + 296 + /* set param pos te_edge */ 297 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xb0, 0x01); 298 + if (ret < 0) 299 + return ret; 300 + 301 + /* set te rising edge */ 302 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xe2, 0x0f); 303 + if (ret < 0) 304 + return ret; 305 + 306 + /* set param pos default */ 307 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xb0, 0x00); 308 + if (ret < 0) 309 + return ret; 310 + 311 + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 312 + if (ret < 0) 313 + return ret; 314 + 315 + ret = s6e63j0x03_apply_mtp_key(ctx, false); 316 + if (ret < 0) 317 + return ret; 318 + 319 + return 0; 320 + } 321 + 322 + static int s6e63j0x03_prepare(struct drm_panel *panel) 323 + { 324 + struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel); 325 + int ret; 326 + 327 + ret = s6e63j0x03_power_on(ctx); 328 + if (ret < 0) 329 + return ret; 330 + 331 + ret = s6e63j0x03_panel_init(ctx); 332 + if (ret < 0) 333 + goto err; 334 + 335 + ctx->bl_dev->props.power = FB_BLANK_NORMAL; 336 + 337 + return 0; 338 + 339 + err: 340 + s6e63j0x03_power_off(ctx); 341 + return ret; 342 + } 343 + 344 + static int s6e63j0x03_enable(struct drm_panel *panel) 345 + { 346 + struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel); 347 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 348 + int ret; 349 + 350 + msleep(120); 351 + 352 + ret = s6e63j0x03_apply_mtp_key(ctx, true); 353 + if (ret < 0) 354 + return ret; 355 + 356 + /* set elvss_cond */ 357 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xb1, 0x00, 0x09); 358 + if (ret < 0) 359 + return ret; 360 + 361 + /* set pos */ 362 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 363 + MIPI_DCS_SET_ADDRESS_MODE, 0x40); 364 + if (ret < 0) 365 + return ret; 366 + 367 + /* set default white brightness */ 368 + ret = mipi_dsi_dcs_set_display_brightness(dsi, 0x00ff); 369 + if (ret < 0) 370 + return ret; 371 + 372 + /* set white ctrl */ 373 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 374 + MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20); 375 + if (ret < 0) 376 + return ret; 377 + 378 + /* set acl off */ 379 + ret = s6e63j0x03_dcs_write_seq_static(ctx, 380 + MIPI_DCS_WRITE_POWER_SAVE, 0x00); 381 + if (ret < 0) 382 + return ret; 383 + 384 + ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); 385 + if (ret < 0) 386 + return ret; 387 + 388 + ret = s6e63j0x03_apply_mtp_key(ctx, false); 389 + if (ret < 0) 390 + return ret; 391 + 392 + ret = mipi_dsi_dcs_set_display_on(dsi); 393 + if (ret < 0) 394 + return ret; 395 + 396 + ctx->bl_dev->props.power = FB_BLANK_UNBLANK; 397 + 398 + return 0; 399 + } 400 + 401 + static int s6e63j0x03_get_modes(struct drm_panel *panel) 402 + { 403 + struct drm_connector *connector = panel->connector; 404 + struct drm_display_mode *mode; 405 + 406 + mode = drm_mode_duplicate(panel->drm, &default_mode); 407 + if (!mode) { 408 + DRM_ERROR("failed to add mode %ux%ux@%u\n", 409 + default_mode.hdisplay, default_mode.vdisplay, 410 + default_mode.vrefresh); 411 + return -ENOMEM; 412 + } 413 + 414 + drm_mode_set_name(mode); 415 + 416 + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 417 + drm_mode_probed_add(connector, mode); 418 + 419 + connector->display_info.width_mm = 29; 420 + connector->display_info.height_mm = 29; 421 + 422 + return 1; 423 + } 424 + 425 + static const struct drm_panel_funcs s6e63j0x03_funcs = { 426 + .disable = s6e63j0x03_disable, 427 + .unprepare = s6e63j0x03_unprepare, 428 + .prepare = s6e63j0x03_prepare, 429 + .enable = s6e63j0x03_enable, 430 + .get_modes = s6e63j0x03_get_modes, 431 + }; 432 + 433 + static int s6e63j0x03_probe(struct mipi_dsi_device *dsi) 434 + { 435 + struct device *dev = &dsi->dev; 436 + struct s6e63j0x03 *ctx; 437 + int ret; 438 + 439 + ctx = devm_kzalloc(dev, sizeof(struct s6e63j0x03), GFP_KERNEL); 440 + if (!ctx) 441 + return -ENOMEM; 442 + 443 + mipi_dsi_set_drvdata(dsi, ctx); 444 + 445 + ctx->dev = dev; 446 + 447 + dsi->lanes = 1; 448 + dsi->format = MIPI_DSI_FMT_RGB888; 449 + dsi->mode_flags = MIPI_DSI_MODE_EOT_PACKET; 450 + 451 + ctx->supplies[0].supply = "vdd3"; 452 + ctx->supplies[1].supply = "vci"; 453 + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies), 454 + ctx->supplies); 455 + if (ret < 0) { 456 + dev_err(dev, "failed to get regulators: %d\n", ret); 457 + return ret; 458 + } 459 + 460 + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 461 + if (IS_ERR(ctx->reset_gpio)) { 462 + dev_err(dev, "cannot get reset-gpio: %ld\n", 463 + PTR_ERR(ctx->reset_gpio)); 464 + return PTR_ERR(ctx->reset_gpio); 465 + } 466 + 467 + drm_panel_init(&ctx->panel); 468 + ctx->panel.dev = dev; 469 + ctx->panel.funcs = &s6e63j0x03_funcs; 470 + 471 + ctx->bl_dev = backlight_device_register("s6e63j0x03", dev, ctx, 472 + &s6e63j0x03_bl_ops, NULL); 473 + if (IS_ERR(ctx->bl_dev)) { 474 + dev_err(dev, "failed to register backlight device\n"); 475 + return PTR_ERR(ctx->bl_dev); 476 + } 477 + 478 + ctx->bl_dev->props.max_brightness = MAX_BRIGHTNESS; 479 + ctx->bl_dev->props.brightness = DEFAULT_BRIGHTNESS; 480 + ctx->bl_dev->props.power = FB_BLANK_POWERDOWN; 481 + 482 + ret = drm_panel_add(&ctx->panel); 483 + if (ret < 0) 484 + goto unregister_backlight; 485 + 486 + ret = mipi_dsi_attach(dsi); 487 + if (ret < 0) 488 + goto remove_panel; 489 + 490 + return ret; 491 + 492 + remove_panel: 493 + drm_panel_remove(&ctx->panel); 494 + 495 + unregister_backlight: 496 + backlight_device_unregister(ctx->bl_dev); 497 + 498 + return ret; 499 + } 500 + 501 + static int s6e63j0x03_remove(struct mipi_dsi_device *dsi) 502 + { 503 + struct s6e63j0x03 *ctx = mipi_dsi_get_drvdata(dsi); 504 + 505 + mipi_dsi_detach(dsi); 506 + drm_panel_remove(&ctx->panel); 507 + 508 + backlight_device_unregister(ctx->bl_dev); 509 + 510 + return 0; 511 + } 512 + 513 + static const struct of_device_id s6e63j0x03_of_match[] = { 514 + { .compatible = "samsung,s6e63j0x03" }, 515 + { } 516 + }; 517 + MODULE_DEVICE_TABLE(of, s6e63j0x03_of_match); 518 + 519 + static struct mipi_dsi_driver s6e63j0x03_driver = { 520 + .probe = s6e63j0x03_probe, 521 + .remove = s6e63j0x03_remove, 522 + .driver = { 523 + .name = "panel_samsung_s6e63j0x03", 524 + .of_match_table = s6e63j0x03_of_match, 525 + }, 526 + }; 527 + module_mipi_dsi_driver(s6e63j0x03_driver); 528 + 529 + MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); 530 + MODULE_AUTHOR("Hoegeun Kwon <hoegeun.kwon@samsung.com>"); 531 + MODULE_DESCRIPTION("MIPI-DSI based s6e63j0x03 AMOLED LCD Panel Driver"); 532 + MODULE_LICENSE("GPL v2");