568 lines · c
1// SPDX-License-Identifier: GPL-2.02 3#include <linux/delay.h>4#include <linux/device.h>5#include <linux/err.h>6#include <linux/errno.h>7#include <linux/gpio/consumer.h>8#include <linux/kernel.h>9#include <linux/mod_devicetable.h>10#include <linux/module.h>11#include <linux/property.h>12#include <linux/regulator/consumer.h>13 14#include <drm/drm_mipi_dsi.h>15#include <drm/drm_modes.h>16#include <drm/drm_panel.h>17#include <drm/drm_probe_helper.h>18 19#include <video/mipi_display.h>20 21struct panel_desc {22 const struct drm_display_mode *display_mode;23 unsigned long mode_flags;24 enum mipi_dsi_pixel_format format;25 unsigned int lanes;26 void (*init_sequence)(struct mipi_dsi_multi_context *ctx);27};28 29struct ili9806e_panel {30 struct drm_panel panel;31 struct mipi_dsi_device *dsi;32 struct gpio_desc *reset_gpio;33 struct regulator_bulk_data supplies[2];34 const struct panel_desc *desc;35 enum drm_panel_orientation orientation;36};37 38static const char * const regulator_names[] = {39 "vdd",40 "vccio",41};42 43static inline struct ili9806e_panel *to_ili9806e_panel(struct drm_panel *panel)44{45 return container_of(panel, struct ili9806e_panel, panel);46}47 48static int ili9806e_power_on(struct ili9806e_panel *ctx)49{50 struct mipi_dsi_device *dsi = ctx->dsi;51 int ret;52 53 gpiod_set_value(ctx->reset_gpio, 1);54 55 ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);56 if (ret < 0) {57 dev_err(&dsi->dev, "regulator bulk enable failed: %d\n", ret);58 return ret;59 }60 61 usleep_range(10000, 20000);62 gpiod_set_value(ctx->reset_gpio, 0);63 usleep_range(10000, 20000);64 65 return 0;66}67 68static int ili9806e_power_off(struct ili9806e_panel *ctx)69{70 struct mipi_dsi_device *dsi = ctx->dsi;71 int ret;72 73 gpiod_set_value(ctx->reset_gpio, 1);74 75 ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);76 if (ret)77 dev_err(&dsi->dev, "regulator bulk disable failed: %d\n", ret);78 79 return ret;80}81 82static int ili9806e_on(struct ili9806e_panel *ili9806e)83{84 struct mipi_dsi_multi_context ctx = { .dsi = ili9806e->dsi };85 86 if (ili9806e->desc->init_sequence)87 ili9806e->desc->init_sequence(&ctx);88 89 mipi_dsi_dcs_exit_sleep_mode_multi(&ctx);90 mipi_dsi_msleep(&ctx, 120);91 mipi_dsi_dcs_set_display_on_multi(&ctx);92 93 return ctx.accum_err;94}95 96static int ili9806e_off(struct ili9806e_panel *panel)97{98 struct mipi_dsi_multi_context ctx = { .dsi = panel->dsi };99 100 mipi_dsi_dcs_set_display_off_multi(&ctx);101 mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);102 mipi_dsi_msleep(&ctx, 120);103 104 return ctx.accum_err;105}106 107static int ili9806e_prepare(struct drm_panel *panel)108{109 struct ili9806e_panel *ctx = to_ili9806e_panel(panel);110 int ret;111 112 ret = ili9806e_power_on(ctx);113 if (ret < 0)114 return ret;115 116 ret = ili9806e_on(ctx);117 if (ret < 0) {118 ili9806e_power_off(ctx);119 return ret;120 }121 122 return 0;123}124 125static int ili9806e_unprepare(struct drm_panel *panel)126{127 struct ili9806e_panel *ctx = to_ili9806e_panel(panel);128 struct mipi_dsi_device *dsi = ctx->dsi;129 int ret;130 131 ili9806e_off(ctx);132 133 ret = ili9806e_power_off(ctx);134 if (ret < 0)135 dev_err(&dsi->dev, "power off failed: %d\n", ret);136 137 return ret;138}139 140static int ili9806e_get_modes(struct drm_panel *panel,141 struct drm_connector *connector)142{143 struct ili9806e_panel *ctx = to_ili9806e_panel(panel);144 const struct drm_display_mode *mode = ctx->desc->display_mode;145 146 return drm_connector_helper_get_modes_fixed(connector, mode);147}148 149static enum drm_panel_orientation ili9806e_get_orientation(struct drm_panel *panel)150{151 struct ili9806e_panel *ctx = to_ili9806e_panel(panel);152 153 return ctx->orientation;154}155 156static const struct drm_panel_funcs ili9806e_funcs = {157 .prepare = ili9806e_prepare,158 .unprepare = ili9806e_unprepare,159 .get_modes = ili9806e_get_modes,160 .get_orientation = ili9806e_get_orientation,161};162 163static int ili9806e_dsi_probe(struct mipi_dsi_device *dsi)164{165 struct device *dev = &dsi->dev;166 struct ili9806e_panel *ctx;167 int i, ret;168 169 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);170 if (!ctx)171 return -ENOMEM;172 173 ctx->desc = device_get_match_data(dev);174 175 for (i = 0; i < ARRAY_SIZE(ctx->supplies); i++)176 ctx->supplies[i].supply = regulator_names[i];177 178 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),179 ctx->supplies);180 if (ret < 0)181 return ret;182 183 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);184 if (IS_ERR(ctx->reset_gpio))185 return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),186 "Failed to get reset-gpios\n");187 188 mipi_dsi_set_drvdata(dsi, ctx);189 ctx->dsi = dsi;190 191 dsi->mode_flags = ctx->desc->mode_flags;192 dsi->format = ctx->desc->format;193 dsi->lanes = ctx->desc->lanes;194 195 drm_panel_init(&ctx->panel, dev, &ili9806e_funcs,196 DRM_MODE_CONNECTOR_DSI);197 198 ret = of_drm_get_panel_orientation(dev->of_node, &ctx->orientation);199 if (ret)200 return dev_err_probe(dev, ret, "Failed to get orientation\n");201 202 ret = drm_panel_of_backlight(&ctx->panel);203 if (ret)204 return dev_err_probe(dev, ret, "Failed to get backlight\n");205 206 ctx->panel.prepare_prev_first = true;207 drm_panel_add(&ctx->panel);208 209 ret = mipi_dsi_attach(dsi);210 if (ret < 0) {211 dev_err_probe(dev, ret, "Failed to attach to DSI host\n");212 drm_panel_remove(&ctx->panel);213 return ret;214 }215 216 return 0;217}218 219static void ili9806e_dsi_remove(struct mipi_dsi_device *dsi)220{221 struct ili9806e_panel *ctx = mipi_dsi_get_drvdata(dsi);222 223 mipi_dsi_detach(dsi);224 drm_panel_remove(&ctx->panel);225}226 227static void com35h3p70ulc_init(struct mipi_dsi_multi_context *ctx)228{229 /* Switch to page 1 */230 mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x01);231 /* Interface Settings */232 mipi_dsi_dcs_write_seq_multi(ctx, 0x08, 0x18);233 mipi_dsi_dcs_write_seq_multi(ctx, 0x21, 0x01);234 /* Panel Settings */235 mipi_dsi_dcs_write_seq_multi(ctx, 0x30, 0x03);236 mipi_dsi_dcs_write_seq_multi(ctx, 0x31, 0x00);237 mipi_dsi_dcs_write_seq_multi(ctx, 0x60, 0x0d);238 mipi_dsi_dcs_write_seq_multi(ctx, 0x61, 0x08);239 mipi_dsi_dcs_write_seq_multi(ctx, 0x62, 0x08);240 mipi_dsi_dcs_write_seq_multi(ctx, 0x63, 0x09);241 /* Power Control */242 mipi_dsi_dcs_write_seq_multi(ctx, 0x40, 0x30);243 mipi_dsi_dcs_write_seq_multi(ctx, 0x41, 0x44);244 mipi_dsi_dcs_write_seq_multi(ctx, 0x42, 0x00);245 mipi_dsi_dcs_write_seq_multi(ctx, 0x43, 0x89);246 mipi_dsi_dcs_write_seq_multi(ctx, 0x44, 0x8e);247 mipi_dsi_dcs_write_seq_multi(ctx, 0x45, 0xd9);248 mipi_dsi_dcs_write_seq_multi(ctx, 0x46, 0x33);249 mipi_dsi_dcs_write_seq_multi(ctx, 0x47, 0x33);250 mipi_dsi_dcs_write_seq_multi(ctx, 0x50, 0x90);251 mipi_dsi_dcs_write_seq_multi(ctx, 0x51, 0x90);252 mipi_dsi_dcs_write_seq_multi(ctx, 0x56, 0x00);253 /* Gamma Settings */254 mipi_dsi_dcs_write_seq_multi(ctx, 0xa0, 0x00);255 mipi_dsi_dcs_write_seq_multi(ctx, 0xa1, 0x0c);256 mipi_dsi_dcs_write_seq_multi(ctx, 0xa2, 0x13);257 mipi_dsi_dcs_write_seq_multi(ctx, 0xa3, 0x0f);258 mipi_dsi_dcs_write_seq_multi(ctx, 0xa4, 0x0a);259 mipi_dsi_dcs_write_seq_multi(ctx, 0xa5, 0x0d);260 mipi_dsi_dcs_write_seq_multi(ctx, 0xa6, 0x0c);261 mipi_dsi_dcs_write_seq_multi(ctx, 0xa7, 0x0b);262 mipi_dsi_dcs_write_seq_multi(ctx, 0xa8, 0x01);263 mipi_dsi_dcs_write_seq_multi(ctx, 0xa9, 0x06);264 mipi_dsi_dcs_write_seq_multi(ctx, 0xaa, 0x15);265 mipi_dsi_dcs_write_seq_multi(ctx, 0xab, 0x07);266 mipi_dsi_dcs_write_seq_multi(ctx, 0xac, 0x12);267 mipi_dsi_dcs_write_seq_multi(ctx, 0xad, 0x28);268 mipi_dsi_dcs_write_seq_multi(ctx, 0xae, 0x20);269 mipi_dsi_dcs_write_seq_multi(ctx, 0xaf, 0x14);270 mipi_dsi_dcs_write_seq_multi(ctx, 0xc0, 0x00);271 mipi_dsi_dcs_write_seq_multi(ctx, 0xc1, 0x0c);272 mipi_dsi_dcs_write_seq_multi(ctx, 0xc2, 0x13);273 mipi_dsi_dcs_write_seq_multi(ctx, 0xc3, 0x0f);274 mipi_dsi_dcs_write_seq_multi(ctx, 0xc4, 0x09);275 mipi_dsi_dcs_write_seq_multi(ctx, 0xc5, 0x0d);276 mipi_dsi_dcs_write_seq_multi(ctx, 0xc6, 0x0c);277 mipi_dsi_dcs_write_seq_multi(ctx, 0xc7, 0x0b);278 mipi_dsi_dcs_write_seq_multi(ctx, 0xc8, 0x01);279 mipi_dsi_dcs_write_seq_multi(ctx, 0xc9, 0x06);280 mipi_dsi_dcs_write_seq_multi(ctx, 0xca, 0x14);281 mipi_dsi_dcs_write_seq_multi(ctx, 0xcb, 0x07);282 mipi_dsi_dcs_write_seq_multi(ctx, 0xcc, 0x0f);283 mipi_dsi_dcs_write_seq_multi(ctx, 0xcd, 0x21);284 mipi_dsi_dcs_write_seq_multi(ctx, 0xce, 0x17);285 mipi_dsi_dcs_write_seq_multi(ctx, 0xcf, 0x0a);286 287 /* Switch to page 7 */288 mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x07);289 /* Power Control */290 mipi_dsi_dcs_write_seq_multi(ctx, 0x06, 0x00);291 mipi_dsi_dcs_write_seq_multi(ctx, 0x18, 0x1d);292 mipi_dsi_dcs_write_seq_multi(ctx, 0x17, 0x32);293 294 /* Switch to page 6 */295 mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x06);296 /* GIP settings */297 mipi_dsi_dcs_write_seq_multi(ctx, 0x00, 0x20);298 mipi_dsi_dcs_write_seq_multi(ctx, 0x01, 0x02);299 mipi_dsi_dcs_write_seq_multi(ctx, 0x02, 0x00);300 mipi_dsi_dcs_write_seq_multi(ctx, 0x03, 0x02);301 mipi_dsi_dcs_write_seq_multi(ctx, 0x04, 0x01);302 mipi_dsi_dcs_write_seq_multi(ctx, 0x05, 0x01);303 mipi_dsi_dcs_write_seq_multi(ctx, 0x06, 0x88);304 mipi_dsi_dcs_write_seq_multi(ctx, 0x07, 0x04);305 mipi_dsi_dcs_write_seq_multi(ctx, 0x08, 0x03);306 mipi_dsi_dcs_write_seq_multi(ctx, 0x09, 0x80);307 mipi_dsi_dcs_write_seq_multi(ctx, 0x0a, 0x00);308 mipi_dsi_dcs_write_seq_multi(ctx, 0x0b, 0x00);309 mipi_dsi_dcs_write_seq_multi(ctx, 0x0c, 0x01);310 mipi_dsi_dcs_write_seq_multi(ctx, 0x0d, 0x01);311 mipi_dsi_dcs_write_seq_multi(ctx, 0x0e, 0x00);312 mipi_dsi_dcs_write_seq_multi(ctx, 0x0f, 0x00);313 mipi_dsi_dcs_write_seq_multi(ctx, 0x10, 0x55);314 mipi_dsi_dcs_write_seq_multi(ctx, 0x11, 0x50);315 mipi_dsi_dcs_write_seq_multi(ctx, 0x12, 0x01);316 mipi_dsi_dcs_write_seq_multi(ctx, 0x13, 0x00);317 mipi_dsi_dcs_write_seq_multi(ctx, 0x14, 0x00);318 mipi_dsi_dcs_write_seq_multi(ctx, 0x15, 0x43);319 mipi_dsi_dcs_write_seq_multi(ctx, 0x16, 0x0b);320 mipi_dsi_dcs_write_seq_multi(ctx, 0x17, 0x00);321 mipi_dsi_dcs_write_seq_multi(ctx, 0x18, 0x00);322 mipi_dsi_dcs_write_seq_multi(ctx, 0x19, 0x10);323 mipi_dsi_dcs_write_seq_multi(ctx, 0x1a, 0x00);324 mipi_dsi_dcs_write_seq_multi(ctx, 0x1b, 0x00);325 mipi_dsi_dcs_write_seq_multi(ctx, 0x1c, 0x00);326 mipi_dsi_dcs_write_seq_multi(ctx, 0x1d, 0x00);327 mipi_dsi_dcs_write_seq_multi(ctx, 0x20, 0x01);328 mipi_dsi_dcs_write_seq_multi(ctx, 0x21, 0x23);329 mipi_dsi_dcs_write_seq_multi(ctx, 0x22, 0x45);330 mipi_dsi_dcs_write_seq_multi(ctx, 0x23, 0x67);331 mipi_dsi_dcs_write_seq_multi(ctx, 0x24, 0x01);332 mipi_dsi_dcs_write_seq_multi(ctx, 0x25, 0x23);333 mipi_dsi_dcs_write_seq_multi(ctx, 0x26, 0x45);334 mipi_dsi_dcs_write_seq_multi(ctx, 0x27, 0x67);335 mipi_dsi_dcs_write_seq_multi(ctx, 0x30, 0x02);336 mipi_dsi_dcs_write_seq_multi(ctx, 0x31, 0x22);337 mipi_dsi_dcs_write_seq_multi(ctx, 0x32, 0x22);338 mipi_dsi_dcs_write_seq_multi(ctx, 0x33, 0x88);339 mipi_dsi_dcs_write_seq_multi(ctx, 0x34, 0xaa);340 mipi_dsi_dcs_write_seq_multi(ctx, 0x35, 0xbb);341 mipi_dsi_dcs_write_seq_multi(ctx, 0x36, 0x66);342 mipi_dsi_dcs_write_seq_multi(ctx, 0x37, 0x22);343 mipi_dsi_dcs_write_seq_multi(ctx, 0x38, 0x22);344 mipi_dsi_dcs_write_seq_multi(ctx, 0x39, 0x22);345 mipi_dsi_dcs_write_seq_multi(ctx, 0x3a, 0x22);346 mipi_dsi_dcs_write_seq_multi(ctx, 0x3b, 0x22);347 mipi_dsi_dcs_write_seq_multi(ctx, 0x3c, 0x22);348 mipi_dsi_dcs_write_seq_multi(ctx, 0x3d, 0x22);349 mipi_dsi_dcs_write_seq_multi(ctx, 0x3e, 0x22);350 mipi_dsi_dcs_write_seq_multi(ctx, 0x3f, 0x22);351 mipi_dsi_dcs_write_seq_multi(ctx, 0x40, 0x22);352 mipi_dsi_dcs_write_seq_multi(ctx, 0x53, 0x12);353 354 /* Switch to page 0 */355 mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x00);356 /* Interface Pixel format */357 mipi_dsi_dcs_write_seq_multi(ctx, 0x3a, 0x60);358};359 360static const struct drm_display_mode com35h3p70ulc_default_mode = {361 .clock = 22400,362 .hdisplay = 480,363 .hsync_start = 480 + 16,364 .hsync_end = 480 + 16 + 16,365 .htotal = 480 + 16 + 16 + 16,366 .vdisplay = 640,367 .vsync_start = 640 + 52,368 .vsync_end = 640 + 52 + 4,369 .vtotal = 640 + 52 + 4 + 16,370 .width_mm = 53,371 .height_mm = 71,372};373 374static const struct panel_desc com35h3p70ulc_desc = {375 .init_sequence = com35h3p70ulc_init,376 .display_mode = &com35h3p70ulc_default_mode,377 .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |378 MIPI_DSI_MODE_LPM,379 .format = MIPI_DSI_FMT_RGB888,380 .lanes = 2,381};382 383static void dmt028vghmcmi_1d_init(struct mipi_dsi_multi_context *ctx)384{385 mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x01);386 mipi_dsi_dcs_write_seq_multi(ctx, 0x08, 0x10);387 mipi_dsi_dcs_write_seq_multi(ctx, 0x21, 0x01);388 mipi_dsi_dcs_write_seq_multi(ctx, 0x30, 0x03);389 mipi_dsi_dcs_write_seq_multi(ctx, 0x31, 0x00);390 mipi_dsi_dcs_write_seq_multi(ctx, 0x60, 0x06);391 mipi_dsi_dcs_write_seq_multi(ctx, 0x61, 0x00);392 mipi_dsi_dcs_write_seq_multi(ctx, 0x62, 0x07);393 mipi_dsi_dcs_write_seq_multi(ctx, 0x63, 0x00);394 mipi_dsi_dcs_write_seq_multi(ctx, 0x40, 0x16);395 mipi_dsi_dcs_write_seq_multi(ctx, 0x41, 0x44);396 mipi_dsi_dcs_write_seq_multi(ctx, 0x42, 0x00);397 mipi_dsi_dcs_write_seq_multi(ctx, 0x43, 0x83);398 mipi_dsi_dcs_write_seq_multi(ctx, 0x44, 0x89);399 mipi_dsi_dcs_write_seq_multi(ctx, 0x45, 0x8a);400 mipi_dsi_dcs_write_seq_multi(ctx, 0x46, 0x44);401 mipi_dsi_dcs_write_seq_multi(ctx, 0x47, 0x44);402 mipi_dsi_dcs_write_seq_multi(ctx, 0x50, 0x78);403 mipi_dsi_dcs_write_seq_multi(ctx, 0x51, 0x78);404 mipi_dsi_dcs_write_seq_multi(ctx, 0x52, 0x00);405 mipi_dsi_dcs_write_seq_multi(ctx, 0x53, 0x6c);406 mipi_dsi_dcs_write_seq_multi(ctx, 0x54, 0x00);407 mipi_dsi_dcs_write_seq_multi(ctx, 0x55, 0x6c);408 mipi_dsi_dcs_write_seq_multi(ctx, 0x56, 0x00);409 /* Gamma settings */410 mipi_dsi_dcs_write_seq_multi(ctx, 0xa0, 0x00);411 mipi_dsi_dcs_write_seq_multi(ctx, 0xa1, 0x09);412 mipi_dsi_dcs_write_seq_multi(ctx, 0xa2, 0x14);413 mipi_dsi_dcs_write_seq_multi(ctx, 0xa3, 0x09);414 mipi_dsi_dcs_write_seq_multi(ctx, 0xa4, 0x05);415 mipi_dsi_dcs_write_seq_multi(ctx, 0xa5, 0x0a);416 mipi_dsi_dcs_write_seq_multi(ctx, 0xa6, 0x07);417 mipi_dsi_dcs_write_seq_multi(ctx, 0xa7, 0x07);418 mipi_dsi_dcs_write_seq_multi(ctx, 0xa8, 0x08);419 mipi_dsi_dcs_write_seq_multi(ctx, 0xa9, 0x0b);420 mipi_dsi_dcs_write_seq_multi(ctx, 0xaa, 0x0c);421 mipi_dsi_dcs_write_seq_multi(ctx, 0xab, 0x05);422 mipi_dsi_dcs_write_seq_multi(ctx, 0xac, 0x0a);423 mipi_dsi_dcs_write_seq_multi(ctx, 0xad, 0x19);424 mipi_dsi_dcs_write_seq_multi(ctx, 0xae, 0x0b);425 mipi_dsi_dcs_write_seq_multi(ctx, 0xaf, 0x00);426 427 mipi_dsi_dcs_write_seq_multi(ctx, 0xc0, 0x00);428 mipi_dsi_dcs_write_seq_multi(ctx, 0xc1, 0x0c);429 mipi_dsi_dcs_write_seq_multi(ctx, 0xc2, 0x14);430 mipi_dsi_dcs_write_seq_multi(ctx, 0xc3, 0x11);431 mipi_dsi_dcs_write_seq_multi(ctx, 0xc4, 0x05);432 mipi_dsi_dcs_write_seq_multi(ctx, 0xc5, 0x0c);433 mipi_dsi_dcs_write_seq_multi(ctx, 0xc6, 0x08);434 mipi_dsi_dcs_write_seq_multi(ctx, 0xc7, 0x03);435 mipi_dsi_dcs_write_seq_multi(ctx, 0xc8, 0x06);436 mipi_dsi_dcs_write_seq_multi(ctx, 0xc9, 0x0a);437 mipi_dsi_dcs_write_seq_multi(ctx, 0xca, 0x10);438 mipi_dsi_dcs_write_seq_multi(ctx, 0xcb, 0x05);439 mipi_dsi_dcs_write_seq_multi(ctx, 0xcc, 0x0d);440 mipi_dsi_dcs_write_seq_multi(ctx, 0xcd, 0x15);441 mipi_dsi_dcs_write_seq_multi(ctx, 0xce, 0x13);442 mipi_dsi_dcs_write_seq_multi(ctx, 0xcf, 0x00);443 444 mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x07);445 mipi_dsi_dcs_write_seq_multi(ctx, 0x17, 0x22);446 mipi_dsi_dcs_write_seq_multi(ctx, 0x18, 0x1d);447 mipi_dsi_dcs_write_seq_multi(ctx, 0x02, 0x77);448 mipi_dsi_dcs_write_seq_multi(ctx, 0xe1, 0x79);449 mipi_dsi_dcs_write_seq_multi(ctx, 0x06, 0x13);450 451 mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x06);452 /* GIP 0 */453 mipi_dsi_dcs_write_seq_multi(ctx, 0x00, 0x21);454 mipi_dsi_dcs_write_seq_multi(ctx, 0x01, 0x0a);455 mipi_dsi_dcs_write_seq_multi(ctx, 0x02, 0x00);456 mipi_dsi_dcs_write_seq_multi(ctx, 0x03, 0x05);457 mipi_dsi_dcs_write_seq_multi(ctx, 0x04, 0x01);458 mipi_dsi_dcs_write_seq_multi(ctx, 0x05, 0x01);459 mipi_dsi_dcs_write_seq_multi(ctx, 0x06, 0x98);460 mipi_dsi_dcs_write_seq_multi(ctx, 0x07, 0x06);461 mipi_dsi_dcs_write_seq_multi(ctx, 0x08, 0x01);462 mipi_dsi_dcs_write_seq_multi(ctx, 0x09, 0x00);463 mipi_dsi_dcs_write_seq_multi(ctx, 0x0a, 0x00);464 mipi_dsi_dcs_write_seq_multi(ctx, 0x0b, 0x00);465 mipi_dsi_dcs_write_seq_multi(ctx, 0x0c, 0x01);466 mipi_dsi_dcs_write_seq_multi(ctx, 0x0d, 0x01);467 mipi_dsi_dcs_write_seq_multi(ctx, 0x0e, 0x00);468 mipi_dsi_dcs_write_seq_multi(ctx, 0x0f, 0x00);469 mipi_dsi_dcs_write_seq_multi(ctx, 0x10, 0xf7);470 mipi_dsi_dcs_write_seq_multi(ctx, 0x11, 0xf0);471 mipi_dsi_dcs_write_seq_multi(ctx, 0x12, 0x00);472 mipi_dsi_dcs_write_seq_multi(ctx, 0x13, 0x00);473 mipi_dsi_dcs_write_seq_multi(ctx, 0x14, 0x00);474 mipi_dsi_dcs_write_seq_multi(ctx, 0x15, 0xc0);475 mipi_dsi_dcs_write_seq_multi(ctx, 0x16, 0x08);476 mipi_dsi_dcs_write_seq_multi(ctx, 0x17, 0x00);477 mipi_dsi_dcs_write_seq_multi(ctx, 0x18, 0x00);478 mipi_dsi_dcs_write_seq_multi(ctx, 0x19, 0x00);479 mipi_dsi_dcs_write_seq_multi(ctx, 0x1a, 0x00);480 mipi_dsi_dcs_write_seq_multi(ctx, 0x1b, 0x00);481 mipi_dsi_dcs_write_seq_multi(ctx, 0x1c, 0x00);482 mipi_dsi_dcs_write_seq_multi(ctx, 0x1d, 0x00);483 /* GIP 1 */484 mipi_dsi_dcs_write_seq_multi(ctx, 0x20, 0x01);485 mipi_dsi_dcs_write_seq_multi(ctx, 0x21, 0x23);486 mipi_dsi_dcs_write_seq_multi(ctx, 0x22, 0x44);487 mipi_dsi_dcs_write_seq_multi(ctx, 0x23, 0x67);488 mipi_dsi_dcs_write_seq_multi(ctx, 0x24, 0x01);489 mipi_dsi_dcs_write_seq_multi(ctx, 0x25, 0x23);490 mipi_dsi_dcs_write_seq_multi(ctx, 0x26, 0x45);491 mipi_dsi_dcs_write_seq_multi(ctx, 0x27, 0x67);492 /* GIP 2 */493 mipi_dsi_dcs_write_seq_multi(ctx, 0x30, 0x01);494 mipi_dsi_dcs_write_seq_multi(ctx, 0x31, 0x22);495 mipi_dsi_dcs_write_seq_multi(ctx, 0x32, 0x22);496 mipi_dsi_dcs_write_seq_multi(ctx, 0x33, 0xbc);497 mipi_dsi_dcs_write_seq_multi(ctx, 0x34, 0xad);498 mipi_dsi_dcs_write_seq_multi(ctx, 0x35, 0xda);499 mipi_dsi_dcs_write_seq_multi(ctx, 0x36, 0xcb);500 mipi_dsi_dcs_write_seq_multi(ctx, 0x37, 0x22);501 mipi_dsi_dcs_write_seq_multi(ctx, 0x38, 0x55);502 mipi_dsi_dcs_write_seq_multi(ctx, 0x39, 0x76);503 mipi_dsi_dcs_write_seq_multi(ctx, 0x3a, 0x67);504 mipi_dsi_dcs_write_seq_multi(ctx, 0x3b, 0x88);505 mipi_dsi_dcs_write_seq_multi(ctx, 0x3c, 0x22);506 mipi_dsi_dcs_write_seq_multi(ctx, 0x3d, 0x11);507 mipi_dsi_dcs_write_seq_multi(ctx, 0x3e, 0x00);508 mipi_dsi_dcs_write_seq_multi(ctx, 0x3f, 0x22);509 mipi_dsi_dcs_write_seq_multi(ctx, 0x40, 0x22);510 511 mipi_dsi_dcs_write_seq_multi(ctx, 0x52, 0x10);512 mipi_dsi_dcs_write_seq_multi(ctx, 0x53, 0x10);513 mipi_dsi_dcs_write_seq_multi(ctx, 0x54, 0x13);514 515 mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x00);516};517 518static const struct drm_display_mode dmt028vghmcmi_1d_default_mode = {519 .clock = 22000,520 521 .hdisplay = 480,522 .hsync_start = 480 + 20,523 .hsync_end = 480 + 20 + 4,524 .htotal = 480 + 20 + 4 + 10,525 526 .vdisplay = 640,527 .vsync_start = 640 + 40,528 .vsync_end = 640 + 40 + 4,529 .vtotal = 640 + 40 + 4 + 20,530 531 .width_mm = 53,532 .height_mm = 79,533 534 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,535 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,536};537 538static const struct panel_desc dmt028vghmcmi_1d_desc = {539 .init_sequence = dmt028vghmcmi_1d_init,540 .display_mode = &dmt028vghmcmi_1d_default_mode,541 .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |542 MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,543 .format = MIPI_DSI_FMT_RGB888,544 .lanes = 2,545};546 547static const struct of_device_id ili9806e_of_match[] = {548 { .compatible = "densitron,dmt028vghmcmi-1d", .data = &dmt028vghmcmi_1d_desc },549 { .compatible = "ortustech,com35h3p70ulc", .data = &com35h3p70ulc_desc },550 { }551};552MODULE_DEVICE_TABLE(of, ili9806e_of_match);553 554static struct mipi_dsi_driver ili9806e_dsi_driver = {555 .driver = {556 .name = "ili9806e-dsi",557 .of_match_table = ili9806e_of_match,558 },559 .probe = ili9806e_dsi_probe,560 .remove = ili9806e_dsi_remove,561};562module_mipi_dsi_driver(ili9806e_dsi_driver);563 564MODULE_AUTHOR("Gunnar Dibbern <gunnar.dibbern@lht.dlh.de>");565MODULE_AUTHOR("Michael Walle <mwalle@kernel.org>");566MODULE_DESCRIPTION("Ilitek ILI9806E Controller Driver");567MODULE_LICENSE("GPL");568