root/drivers/gpu/drm/panel/panel-raydium-rm67191.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_rad_panel
  2. rad_panel_push_cmd_list
  3. color_format_from_dsi_format
  4. rad_panel_prepare
  5. rad_panel_unprepare
  6. rad_panel_enable
  7. rad_panel_disable
  8. rad_panel_get_modes
  9. rad_bl_get_brightness
  10. rad_bl_update_status
  11. rad_init_regulators
  12. rad_panel_probe
  13. rad_panel_remove
  14. rad_panel_shutdown

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Raydium RM67191 MIPI-DSI panel driver
   4  *
   5  * Copyright 2019 NXP
   6  */
   7 
   8 #include <linux/backlight.h>
   9 #include <linux/delay.h>
  10 #include <linux/gpio/consumer.h>
  11 #include <linux/module.h>
  12 #include <linux/of.h>
  13 #include <linux/regulator/consumer.h>
  14 
  15 #include <video/mipi_display.h>
  16 #include <video/of_videomode.h>
  17 #include <video/videomode.h>
  18 
  19 #include <drm/drm_crtc.h>
  20 #include <drm/drm_mipi_dsi.h>
  21 #include <drm/drm_panel.h>
  22 #include <drm/drm_print.h>
  23 
  24 /* Panel specific color-format bits */
  25 #define COL_FMT_16BPP 0x55
  26 #define COL_FMT_18BPP 0x66
  27 #define COL_FMT_24BPP 0x77
  28 
  29 /* Write Manufacture Command Set Control */
  30 #define WRMAUCCTR 0xFE
  31 
  32 /* Manufacturer Command Set pages (CMD2) */
  33 struct cmd_set_entry {
  34         u8 cmd;
  35         u8 param;
  36 };
  37 
  38 /*
  39  * There is no description in the Reference Manual about these commands.
  40  * We received them from vendor, so just use them as is.
  41  */
  42 static const struct cmd_set_entry manufacturer_cmd_set[] = {
  43         {0xFE, 0x0B},
  44         {0x28, 0x40},
  45         {0x29, 0x4F},
  46         {0xFE, 0x0E},
  47         {0x4B, 0x00},
  48         {0x4C, 0x0F},
  49         {0x4D, 0x20},
  50         {0x4E, 0x40},
  51         {0x4F, 0x60},
  52         {0x50, 0xA0},
  53         {0x51, 0xC0},
  54         {0x52, 0xE0},
  55         {0x53, 0xFF},
  56         {0xFE, 0x0D},
  57         {0x18, 0x08},
  58         {0x42, 0x00},
  59         {0x08, 0x41},
  60         {0x46, 0x02},
  61         {0x72, 0x09},
  62         {0xFE, 0x0A},
  63         {0x24, 0x17},
  64         {0x04, 0x07},
  65         {0x1A, 0x0C},
  66         {0x0F, 0x44},
  67         {0xFE, 0x04},
  68         {0x00, 0x0C},
  69         {0x05, 0x08},
  70         {0x06, 0x08},
  71         {0x08, 0x08},
  72         {0x09, 0x08},
  73         {0x0A, 0xE6},
  74         {0x0B, 0x8C},
  75         {0x1A, 0x12},
  76         {0x1E, 0xE0},
  77         {0x29, 0x93},
  78         {0x2A, 0x93},
  79         {0x2F, 0x02},
  80         {0x31, 0x02},
  81         {0x33, 0x05},
  82         {0x37, 0x2D},
  83         {0x38, 0x2D},
  84         {0x3A, 0x1E},
  85         {0x3B, 0x1E},
  86         {0x3D, 0x27},
  87         {0x3F, 0x80},
  88         {0x40, 0x40},
  89         {0x41, 0xE0},
  90         {0x4F, 0x2F},
  91         {0x50, 0x1E},
  92         {0xFE, 0x06},
  93         {0x00, 0xCC},
  94         {0x05, 0x05},
  95         {0x07, 0xA2},
  96         {0x08, 0xCC},
  97         {0x0D, 0x03},
  98         {0x0F, 0xA2},
  99         {0x32, 0xCC},
 100         {0x37, 0x05},
 101         {0x39, 0x83},
 102         {0x3A, 0xCC},
 103         {0x41, 0x04},
 104         {0x43, 0x83},
 105         {0x44, 0xCC},
 106         {0x49, 0x05},
 107         {0x4B, 0xA2},
 108         {0x4C, 0xCC},
 109         {0x51, 0x03},
 110         {0x53, 0xA2},
 111         {0x75, 0xCC},
 112         {0x7A, 0x03},
 113         {0x7C, 0x83},
 114         {0x7D, 0xCC},
 115         {0x82, 0x02},
 116         {0x84, 0x83},
 117         {0x85, 0xEC},
 118         {0x86, 0x0F},
 119         {0x87, 0xFF},
 120         {0x88, 0x00},
 121         {0x8A, 0x02},
 122         {0x8C, 0xA2},
 123         {0x8D, 0xEA},
 124         {0x8E, 0x01},
 125         {0x8F, 0xE8},
 126         {0xFE, 0x06},
 127         {0x90, 0x0A},
 128         {0x92, 0x06},
 129         {0x93, 0xA0},
 130         {0x94, 0xA8},
 131         {0x95, 0xEC},
 132         {0x96, 0x0F},
 133         {0x97, 0xFF},
 134         {0x98, 0x00},
 135         {0x9A, 0x02},
 136         {0x9C, 0xA2},
 137         {0xAC, 0x04},
 138         {0xFE, 0x06},
 139         {0xB1, 0x12},
 140         {0xB2, 0x17},
 141         {0xB3, 0x17},
 142         {0xB4, 0x17},
 143         {0xB5, 0x17},
 144         {0xB6, 0x11},
 145         {0xB7, 0x08},
 146         {0xB8, 0x09},
 147         {0xB9, 0x06},
 148         {0xBA, 0x07},
 149         {0xBB, 0x17},
 150         {0xBC, 0x17},
 151         {0xBD, 0x17},
 152         {0xBE, 0x17},
 153         {0xBF, 0x17},
 154         {0xC0, 0x17},
 155         {0xC1, 0x17},
 156         {0xC2, 0x17},
 157         {0xC3, 0x17},
 158         {0xC4, 0x0F},
 159         {0xC5, 0x0E},
 160         {0xC6, 0x00},
 161         {0xC7, 0x01},
 162         {0xC8, 0x10},
 163         {0xFE, 0x06},
 164         {0x95, 0xEC},
 165         {0x8D, 0xEE},
 166         {0x44, 0xEC},
 167         {0x4C, 0xEC},
 168         {0x32, 0xEC},
 169         {0x3A, 0xEC},
 170         {0x7D, 0xEC},
 171         {0x75, 0xEC},
 172         {0x00, 0xEC},
 173         {0x08, 0xEC},
 174         {0x85, 0xEC},
 175         {0xA6, 0x21},
 176         {0xA7, 0x05},
 177         {0xA9, 0x06},
 178         {0x82, 0x06},
 179         {0x41, 0x06},
 180         {0x7A, 0x07},
 181         {0x37, 0x07},
 182         {0x05, 0x06},
 183         {0x49, 0x06},
 184         {0x0D, 0x04},
 185         {0x51, 0x04},
 186 };
 187 
 188 static const u32 rad_bus_formats[] = {
 189         MEDIA_BUS_FMT_RGB888_1X24,
 190         MEDIA_BUS_FMT_RGB666_1X18,
 191         MEDIA_BUS_FMT_RGB565_1X16,
 192 };
 193 
 194 static const u32 rad_bus_flags = DRM_BUS_FLAG_DE_LOW |
 195                                  DRM_BUS_FLAG_PIXDATA_NEGEDGE;
 196 
 197 struct rad_panel {
 198         struct drm_panel panel;
 199         struct mipi_dsi_device *dsi;
 200 
 201         struct gpio_desc *reset;
 202         struct backlight_device *backlight;
 203 
 204         struct regulator_bulk_data *supplies;
 205         unsigned int num_supplies;
 206 
 207         bool prepared;
 208         bool enabled;
 209 };
 210 
 211 static const struct drm_display_mode default_mode = {
 212         .clock = 132000,
 213         .hdisplay = 1080,
 214         .hsync_start = 1080 + 20,
 215         .hsync_end = 1080 + 20 + 2,
 216         .htotal = 1080 + 20 + 2 + 34,
 217         .vdisplay = 1920,
 218         .vsync_start = 1920 + 10,
 219         .vsync_end = 1920 + 10 + 2,
 220         .vtotal = 1920 + 10 + 2 + 4,
 221         .vrefresh = 60,
 222         .width_mm = 68,
 223         .height_mm = 121,
 224         .flags = DRM_MODE_FLAG_NHSYNC |
 225                  DRM_MODE_FLAG_NVSYNC,
 226 };
 227 
 228 static inline struct rad_panel *to_rad_panel(struct drm_panel *panel)
 229 {
 230         return container_of(panel, struct rad_panel, panel);
 231 }
 232 
 233 static int rad_panel_push_cmd_list(struct mipi_dsi_device *dsi)
 234 {
 235         size_t i;
 236         size_t count = ARRAY_SIZE(manufacturer_cmd_set);
 237         int ret = 0;
 238 
 239         for (i = 0; i < count; i++) {
 240                 const struct cmd_set_entry *entry = &manufacturer_cmd_set[i];
 241                 u8 buffer[2] = { entry->cmd, entry->param };
 242 
 243                 ret = mipi_dsi_generic_write(dsi, &buffer, sizeof(buffer));
 244                 if (ret < 0)
 245                         return ret;
 246         }
 247 
 248         return ret;
 249 };
 250 
 251 static int color_format_from_dsi_format(enum mipi_dsi_pixel_format format)
 252 {
 253         switch (format) {
 254         case MIPI_DSI_FMT_RGB565:
 255                 return COL_FMT_16BPP;
 256         case MIPI_DSI_FMT_RGB666:
 257         case MIPI_DSI_FMT_RGB666_PACKED:
 258                 return COL_FMT_18BPP;
 259         case MIPI_DSI_FMT_RGB888:
 260                 return COL_FMT_24BPP;
 261         default:
 262                 return COL_FMT_24BPP; /* for backward compatibility */
 263         }
 264 };
 265 
 266 static int rad_panel_prepare(struct drm_panel *panel)
 267 {
 268         struct rad_panel *rad = to_rad_panel(panel);
 269         int ret;
 270 
 271         if (rad->prepared)
 272                 return 0;
 273 
 274         ret = regulator_bulk_enable(rad->num_supplies, rad->supplies);
 275         if (ret)
 276                 return ret;
 277 
 278         if (rad->reset) {
 279                 gpiod_set_value_cansleep(rad->reset, 1);
 280                 usleep_range(3000, 5000);
 281                 gpiod_set_value_cansleep(rad->reset, 0);
 282                 usleep_range(18000, 20000);
 283         }
 284 
 285         rad->prepared = true;
 286 
 287         return 0;
 288 }
 289 
 290 static int rad_panel_unprepare(struct drm_panel *panel)
 291 {
 292         struct rad_panel *rad = to_rad_panel(panel);
 293         int ret;
 294 
 295         if (!rad->prepared)
 296                 return 0;
 297 
 298         /*
 299          * Right after asserting the reset, we need to release it, so that the
 300          * touch driver can have an active connection with the touch controller
 301          * even after the display is turned off.
 302          */
 303         if (rad->reset) {
 304                 gpiod_set_value_cansleep(rad->reset, 1);
 305                 usleep_range(15000, 17000);
 306                 gpiod_set_value_cansleep(rad->reset, 0);
 307         }
 308 
 309         ret = regulator_bulk_disable(rad->num_supplies, rad->supplies);
 310         if (ret)
 311                 return ret;
 312 
 313         rad->prepared = false;
 314 
 315         return 0;
 316 }
 317 
 318 static int rad_panel_enable(struct drm_panel *panel)
 319 {
 320         struct rad_panel *rad = to_rad_panel(panel);
 321         struct mipi_dsi_device *dsi = rad->dsi;
 322         struct device *dev = &dsi->dev;
 323         int color_format = color_format_from_dsi_format(dsi->format);
 324         int ret;
 325 
 326         if (rad->enabled)
 327                 return 0;
 328 
 329         dsi->mode_flags |= MIPI_DSI_MODE_LPM;
 330 
 331         ret = rad_panel_push_cmd_list(dsi);
 332         if (ret < 0) {
 333                 DRM_DEV_ERROR(dev, "Failed to send MCS (%d)\n", ret);
 334                 goto fail;
 335         }
 336 
 337         /* Select User Command Set table (CMD1) */
 338         ret = mipi_dsi_generic_write(dsi, (u8[]){ WRMAUCCTR, 0x00 }, 2);
 339         if (ret < 0)
 340                 goto fail;
 341 
 342         /* Software reset */
 343         ret = mipi_dsi_dcs_soft_reset(dsi);
 344         if (ret < 0) {
 345                 DRM_DEV_ERROR(dev, "Failed to do Software Reset (%d)\n", ret);
 346                 goto fail;
 347         }
 348 
 349         usleep_range(15000, 17000);
 350 
 351         /* Set DSI mode */
 352         ret = mipi_dsi_generic_write(dsi, (u8[]){ 0xC2, 0x0B }, 2);
 353         if (ret < 0) {
 354                 DRM_DEV_ERROR(dev, "Failed to set DSI mode (%d)\n", ret);
 355                 goto fail;
 356         }
 357         /* Set tear ON */
 358         ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
 359         if (ret < 0) {
 360                 DRM_DEV_ERROR(dev, "Failed to set tear ON (%d)\n", ret);
 361                 goto fail;
 362         }
 363         /* Set tear scanline */
 364         ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0x380);
 365         if (ret < 0) {
 366                 DRM_DEV_ERROR(dev, "Failed to set tear scanline (%d)\n", ret);
 367                 goto fail;
 368         }
 369         /* Set pixel format */
 370         ret = mipi_dsi_dcs_set_pixel_format(dsi, color_format);
 371         DRM_DEV_DEBUG_DRIVER(dev, "Interface color format set to 0x%x\n",
 372                              color_format);
 373         if (ret < 0) {
 374                 DRM_DEV_ERROR(dev, "Failed to set pixel format (%d)\n", ret);
 375                 goto fail;
 376         }
 377         /* Exit sleep mode */
 378         ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
 379         if (ret < 0) {
 380                 DRM_DEV_ERROR(dev, "Failed to exit sleep mode (%d)\n", ret);
 381                 goto fail;
 382         }
 383 
 384         usleep_range(5000, 7000);
 385 
 386         ret = mipi_dsi_dcs_set_display_on(dsi);
 387         if (ret < 0) {
 388                 DRM_DEV_ERROR(dev, "Failed to set display ON (%d)\n", ret);
 389                 goto fail;
 390         }
 391 
 392         backlight_enable(rad->backlight);
 393 
 394         rad->enabled = true;
 395 
 396         return 0;
 397 
 398 fail:
 399         gpiod_set_value_cansleep(rad->reset, 1);
 400 
 401         return ret;
 402 }
 403 
 404 static int rad_panel_disable(struct drm_panel *panel)
 405 {
 406         struct rad_panel *rad = to_rad_panel(panel);
 407         struct mipi_dsi_device *dsi = rad->dsi;
 408         struct device *dev = &dsi->dev;
 409         int ret;
 410 
 411         if (!rad->enabled)
 412                 return 0;
 413 
 414         dsi->mode_flags |= MIPI_DSI_MODE_LPM;
 415 
 416         backlight_disable(rad->backlight);
 417 
 418         usleep_range(10000, 12000);
 419 
 420         ret = mipi_dsi_dcs_set_display_off(dsi);
 421         if (ret < 0) {
 422                 DRM_DEV_ERROR(dev, "Failed to set display OFF (%d)\n", ret);
 423                 return ret;
 424         }
 425 
 426         usleep_range(5000, 10000);
 427 
 428         ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
 429         if (ret < 0) {
 430                 DRM_DEV_ERROR(dev, "Failed to enter sleep mode (%d)\n", ret);
 431                 return ret;
 432         }
 433 
 434         rad->enabled = false;
 435 
 436         return 0;
 437 }
 438 
 439 static int rad_panel_get_modes(struct drm_panel *panel)
 440 {
 441         struct drm_connector *connector = panel->connector;
 442         struct drm_display_mode *mode;
 443 
 444         mode = drm_mode_duplicate(panel->drm, &default_mode);
 445         if (!mode) {
 446                 DRM_DEV_ERROR(panel->dev, "failed to add mode %ux%ux@%u\n",
 447                               default_mode.hdisplay, default_mode.vdisplay,
 448                               default_mode.vrefresh);
 449                 return -ENOMEM;
 450         }
 451 
 452         drm_mode_set_name(mode);
 453         mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
 454         drm_mode_probed_add(panel->connector, mode);
 455 
 456         connector->display_info.width_mm = mode->width_mm;
 457         connector->display_info.height_mm = mode->height_mm;
 458         connector->display_info.bus_flags = rad_bus_flags;
 459 
 460         drm_display_info_set_bus_formats(&connector->display_info,
 461                                          rad_bus_formats,
 462                                          ARRAY_SIZE(rad_bus_formats));
 463         return 1;
 464 }
 465 
 466 static int rad_bl_get_brightness(struct backlight_device *bl)
 467 {
 468         struct mipi_dsi_device *dsi = bl_get_data(bl);
 469         struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
 470         u16 brightness;
 471         int ret;
 472 
 473         if (!rad->prepared)
 474                 return 0;
 475 
 476         dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
 477 
 478         ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness);
 479         if (ret < 0)
 480                 return ret;
 481 
 482         bl->props.brightness = brightness;
 483 
 484         return brightness & 0xff;
 485 }
 486 
 487 static int rad_bl_update_status(struct backlight_device *bl)
 488 {
 489         struct mipi_dsi_device *dsi = bl_get_data(bl);
 490         struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
 491         int ret = 0;
 492 
 493         if (!rad->prepared)
 494                 return 0;
 495 
 496         dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
 497 
 498         ret = mipi_dsi_dcs_set_display_brightness(dsi, bl->props.brightness);
 499         if (ret < 0)
 500                 return ret;
 501 
 502         return 0;
 503 }
 504 
 505 static const struct backlight_ops rad_bl_ops = {
 506         .update_status = rad_bl_update_status,
 507         .get_brightness = rad_bl_get_brightness,
 508 };
 509 
 510 static const struct drm_panel_funcs rad_panel_funcs = {
 511         .prepare = rad_panel_prepare,
 512         .unprepare = rad_panel_unprepare,
 513         .enable = rad_panel_enable,
 514         .disable = rad_panel_disable,
 515         .get_modes = rad_panel_get_modes,
 516 };
 517 
 518 static const char * const rad_supply_names[] = {
 519         "v3p3",
 520         "v1p8",
 521 };
 522 
 523 static int rad_init_regulators(struct rad_panel *rad)
 524 {
 525         struct device *dev = &rad->dsi->dev;
 526         int i;
 527 
 528         rad->num_supplies = ARRAY_SIZE(rad_supply_names);
 529         rad->supplies = devm_kcalloc(dev, rad->num_supplies,
 530                                      sizeof(*rad->supplies), GFP_KERNEL);
 531         if (!rad->supplies)
 532                 return -ENOMEM;
 533 
 534         for (i = 0; i < rad->num_supplies; i++)
 535                 rad->supplies[i].supply = rad_supply_names[i];
 536 
 537         return devm_regulator_bulk_get(dev, rad->num_supplies, rad->supplies);
 538 };
 539 
 540 static int rad_panel_probe(struct mipi_dsi_device *dsi)
 541 {
 542         struct device *dev = &dsi->dev;
 543         struct device_node *np = dev->of_node;
 544         struct rad_panel *panel;
 545         struct backlight_properties bl_props;
 546         int ret;
 547         u32 video_mode;
 548 
 549         panel = devm_kzalloc(&dsi->dev, sizeof(*panel), GFP_KERNEL);
 550         if (!panel)
 551                 return -ENOMEM;
 552 
 553         mipi_dsi_set_drvdata(dsi, panel);
 554 
 555         panel->dsi = dsi;
 556 
 557         dsi->format = MIPI_DSI_FMT_RGB888;
 558         dsi->mode_flags =  MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
 559                            MIPI_DSI_CLOCK_NON_CONTINUOUS;
 560 
 561         ret = of_property_read_u32(np, "video-mode", &video_mode);
 562         if (!ret) {
 563                 switch (video_mode) {
 564                 case 0:
 565                         /* burst mode */
 566                         dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_BURST;
 567                         break;
 568                 case 1:
 569                         /* non-burst mode with sync event */
 570                         break;
 571                 case 2:
 572                         /* non-burst mode with sync pulse */
 573                         dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
 574                         break;
 575                 default:
 576                         dev_warn(dev, "invalid video mode %d\n", video_mode);
 577                         break;
 578                 }
 579         }
 580 
 581         ret = of_property_read_u32(np, "dsi-lanes", &dsi->lanes);
 582         if (ret) {
 583                 dev_err(dev, "Failed to get dsi-lanes property (%d)\n", ret);
 584                 return ret;
 585         }
 586 
 587         panel->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
 588         if (IS_ERR(panel->reset))
 589                 return PTR_ERR(panel->reset);
 590 
 591         memset(&bl_props, 0, sizeof(bl_props));
 592         bl_props.type = BACKLIGHT_RAW;
 593         bl_props.brightness = 255;
 594         bl_props.max_brightness = 255;
 595 
 596         panel->backlight = devm_backlight_device_register(dev, dev_name(dev),
 597                                                           dev, dsi, &rad_bl_ops,
 598                                                           &bl_props);
 599         if (IS_ERR(panel->backlight)) {
 600                 ret = PTR_ERR(panel->backlight);
 601                 dev_err(dev, "Failed to register backlight (%d)\n", ret);
 602                 return ret;
 603         }
 604 
 605         ret = rad_init_regulators(panel);
 606         if (ret)
 607                 return ret;
 608 
 609         drm_panel_init(&panel->panel);
 610         panel->panel.funcs = &rad_panel_funcs;
 611         panel->panel.dev = dev;
 612         dev_set_drvdata(dev, panel);
 613 
 614         ret = drm_panel_add(&panel->panel);
 615         if (ret)
 616                 return ret;
 617 
 618         ret = mipi_dsi_attach(dsi);
 619         if (ret)
 620                 drm_panel_remove(&panel->panel);
 621 
 622         return ret;
 623 }
 624 
 625 static int rad_panel_remove(struct mipi_dsi_device *dsi)
 626 {
 627         struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
 628         struct device *dev = &dsi->dev;
 629         int ret;
 630 
 631         ret = mipi_dsi_detach(dsi);
 632         if (ret)
 633                 DRM_DEV_ERROR(dev, "Failed to detach from host (%d)\n",
 634                               ret);
 635 
 636         drm_panel_remove(&rad->panel);
 637 
 638         return 0;
 639 }
 640 
 641 static void rad_panel_shutdown(struct mipi_dsi_device *dsi)
 642 {
 643         struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
 644 
 645         rad_panel_disable(&rad->panel);
 646         rad_panel_unprepare(&rad->panel);
 647 }
 648 
 649 static const struct of_device_id rad_of_match[] = {
 650         { .compatible = "raydium,rm67191", },
 651         { /* sentinel */ }
 652 };
 653 MODULE_DEVICE_TABLE(of, rad_of_match);
 654 
 655 static struct mipi_dsi_driver rad_panel_driver = {
 656         .driver = {
 657                 .name = "panel-raydium-rm67191",
 658                 .of_match_table = rad_of_match,
 659         },
 660         .probe = rad_panel_probe,
 661         .remove = rad_panel_remove,
 662         .shutdown = rad_panel_shutdown,
 663 };
 664 module_mipi_dsi_driver(rad_panel_driver);
 665 
 666 MODULE_AUTHOR("Robert Chiras <robert.chiras@nxp.com>");
 667 MODULE_DESCRIPTION("DRM Driver for Raydium RM67191 MIPI DSI panel");
 668 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */