.. | .. |
---|
3 | 3 | * Copyright (C) 2017-2018, Bootlin |
---|
4 | 4 | */ |
---|
5 | 5 | |
---|
6 | | -#include <linux/backlight.h> |
---|
7 | 6 | #include <linux/delay.h> |
---|
8 | 7 | #include <linux/device.h> |
---|
9 | 8 | #include <linux/err.h> |
---|
.. | .. |
---|
11 | 10 | #include <linux/fb.h> |
---|
12 | 11 | #include <linux/kernel.h> |
---|
13 | 12 | #include <linux/module.h> |
---|
| 13 | +#include <linux/of_device.h> |
---|
14 | 14 | |
---|
15 | 15 | #include <linux/gpio/consumer.h> |
---|
16 | 16 | #include <linux/regulator/consumer.h> |
---|
.. | .. |
---|
20 | 20 | #include <drm/drm_panel.h> |
---|
21 | 21 | |
---|
22 | 22 | #include <video/mipi_display.h> |
---|
23 | | - |
---|
24 | | -struct ili9881c { |
---|
25 | | - struct drm_panel panel; |
---|
26 | | - struct mipi_dsi_device *dsi; |
---|
27 | | - |
---|
28 | | - struct backlight_device *backlight; |
---|
29 | | - struct regulator *power; |
---|
30 | | - struct gpio_desc *reset; |
---|
31 | | -}; |
---|
32 | 23 | |
---|
33 | 24 | enum ili9881c_op { |
---|
34 | 25 | ILI9881C_SWITCH_PAGE, |
---|
.. | .. |
---|
45 | 36 | } cmd; |
---|
46 | 37 | u8 page; |
---|
47 | 38 | } arg; |
---|
| 39 | +}; |
---|
| 40 | + |
---|
| 41 | +struct ili9881c_desc { |
---|
| 42 | + const struct ili9881c_instr *init; |
---|
| 43 | + const size_t init_length; |
---|
| 44 | + const struct drm_display_mode *mode; |
---|
| 45 | +}; |
---|
| 46 | + |
---|
| 47 | +struct ili9881c { |
---|
| 48 | + struct drm_panel panel; |
---|
| 49 | + struct mipi_dsi_device *dsi; |
---|
| 50 | + const struct ili9881c_desc *desc; |
---|
| 51 | + |
---|
| 52 | + struct regulator *power; |
---|
| 53 | + struct gpio_desc *reset; |
---|
48 | 54 | }; |
---|
49 | 55 | |
---|
50 | 56 | #define ILI9881C_SWITCH_PAGE_INSTR(_page) \ |
---|
.. | .. |
---|
66 | 72 | }, \ |
---|
67 | 73 | } |
---|
68 | 74 | |
---|
69 | | -static const struct ili9881c_instr ili9881c_init[] = { |
---|
| 75 | +static const struct ili9881c_instr lhr050h41_init[] = { |
---|
70 | 76 | ILI9881C_SWITCH_PAGE_INSTR(3), |
---|
71 | 77 | ILI9881C_COMMAND_INSTR(0x01, 0x00), |
---|
72 | 78 | ILI9881C_COMMAND_INSTR(0x02, 0x00), |
---|
.. | .. |
---|
254 | 260 | ILI9881C_COMMAND_INSTR(0xD3, 0x3F), |
---|
255 | 261 | }; |
---|
256 | 262 | |
---|
| 263 | +static const struct ili9881c_instr k101_im2byl02_init[] = { |
---|
| 264 | + ILI9881C_SWITCH_PAGE_INSTR(3), |
---|
| 265 | + ILI9881C_COMMAND_INSTR(0x01, 0x00), |
---|
| 266 | + ILI9881C_COMMAND_INSTR(0x02, 0x00), |
---|
| 267 | + ILI9881C_COMMAND_INSTR(0x03, 0x73), |
---|
| 268 | + ILI9881C_COMMAND_INSTR(0x04, 0x00), |
---|
| 269 | + ILI9881C_COMMAND_INSTR(0x05, 0x00), |
---|
| 270 | + ILI9881C_COMMAND_INSTR(0x06, 0x08), |
---|
| 271 | + ILI9881C_COMMAND_INSTR(0x07, 0x00), |
---|
| 272 | + ILI9881C_COMMAND_INSTR(0x08, 0x00), |
---|
| 273 | + ILI9881C_COMMAND_INSTR(0x09, 0x00), |
---|
| 274 | + ILI9881C_COMMAND_INSTR(0x0A, 0x01), |
---|
| 275 | + ILI9881C_COMMAND_INSTR(0x0B, 0x01), |
---|
| 276 | + ILI9881C_COMMAND_INSTR(0x0C, 0x00), |
---|
| 277 | + ILI9881C_COMMAND_INSTR(0x0D, 0x01), |
---|
| 278 | + ILI9881C_COMMAND_INSTR(0x0E, 0x01), |
---|
| 279 | + ILI9881C_COMMAND_INSTR(0x0F, 0x00), |
---|
| 280 | + ILI9881C_COMMAND_INSTR(0x10, 0x00), |
---|
| 281 | + ILI9881C_COMMAND_INSTR(0x11, 0x00), |
---|
| 282 | + ILI9881C_COMMAND_INSTR(0x12, 0x00), |
---|
| 283 | + ILI9881C_COMMAND_INSTR(0x13, 0x00), |
---|
| 284 | + ILI9881C_COMMAND_INSTR(0x14, 0x00), |
---|
| 285 | + ILI9881C_COMMAND_INSTR(0x15, 0x00), |
---|
| 286 | + ILI9881C_COMMAND_INSTR(0x16, 0x00), |
---|
| 287 | + ILI9881C_COMMAND_INSTR(0x17, 0x00), |
---|
| 288 | + ILI9881C_COMMAND_INSTR(0x18, 0x00), |
---|
| 289 | + ILI9881C_COMMAND_INSTR(0x19, 0x00), |
---|
| 290 | + ILI9881C_COMMAND_INSTR(0x1A, 0x00), |
---|
| 291 | + ILI9881C_COMMAND_INSTR(0x1B, 0x00), |
---|
| 292 | + ILI9881C_COMMAND_INSTR(0x1C, 0x00), |
---|
| 293 | + ILI9881C_COMMAND_INSTR(0x1D, 0x00), |
---|
| 294 | + ILI9881C_COMMAND_INSTR(0x1E, 0x40), |
---|
| 295 | + ILI9881C_COMMAND_INSTR(0x1F, 0xC0), |
---|
| 296 | + ILI9881C_COMMAND_INSTR(0x20, 0x06), |
---|
| 297 | + ILI9881C_COMMAND_INSTR(0x21, 0x01), |
---|
| 298 | + ILI9881C_COMMAND_INSTR(0x22, 0x06), |
---|
| 299 | + ILI9881C_COMMAND_INSTR(0x23, 0x01), |
---|
| 300 | + ILI9881C_COMMAND_INSTR(0x24, 0x88), |
---|
| 301 | + ILI9881C_COMMAND_INSTR(0x25, 0x88), |
---|
| 302 | + ILI9881C_COMMAND_INSTR(0x26, 0x00), |
---|
| 303 | + ILI9881C_COMMAND_INSTR(0x27, 0x00), |
---|
| 304 | + ILI9881C_COMMAND_INSTR(0x28, 0x3B), |
---|
| 305 | + ILI9881C_COMMAND_INSTR(0x29, 0x03), |
---|
| 306 | + ILI9881C_COMMAND_INSTR(0x2A, 0x00), |
---|
| 307 | + ILI9881C_COMMAND_INSTR(0x2B, 0x00), |
---|
| 308 | + ILI9881C_COMMAND_INSTR(0x2C, 0x00), |
---|
| 309 | + ILI9881C_COMMAND_INSTR(0x2D, 0x00), |
---|
| 310 | + ILI9881C_COMMAND_INSTR(0x2E, 0x00), |
---|
| 311 | + ILI9881C_COMMAND_INSTR(0x2F, 0x00), |
---|
| 312 | + ILI9881C_COMMAND_INSTR(0x30, 0x00), |
---|
| 313 | + ILI9881C_COMMAND_INSTR(0x31, 0x00), |
---|
| 314 | + ILI9881C_COMMAND_INSTR(0x32, 0x00), |
---|
| 315 | + ILI9881C_COMMAND_INSTR(0x33, 0x00), |
---|
| 316 | + ILI9881C_COMMAND_INSTR(0x34, 0x00), /* GPWR1/2 non overlap time 2.62us */ |
---|
| 317 | + ILI9881C_COMMAND_INSTR(0x35, 0x00), |
---|
| 318 | + ILI9881C_COMMAND_INSTR(0x36, 0x00), |
---|
| 319 | + ILI9881C_COMMAND_INSTR(0x37, 0x00), |
---|
| 320 | + ILI9881C_COMMAND_INSTR(0x38, 0x00), |
---|
| 321 | + ILI9881C_COMMAND_INSTR(0x39, 0x00), |
---|
| 322 | + ILI9881C_COMMAND_INSTR(0x3A, 0x00), |
---|
| 323 | + ILI9881C_COMMAND_INSTR(0x3B, 0x00), |
---|
| 324 | + ILI9881C_COMMAND_INSTR(0x3C, 0x00), |
---|
| 325 | + ILI9881C_COMMAND_INSTR(0x3D, 0x00), |
---|
| 326 | + ILI9881C_COMMAND_INSTR(0x3E, 0x00), |
---|
| 327 | + ILI9881C_COMMAND_INSTR(0x3F, 0x00), |
---|
| 328 | + ILI9881C_COMMAND_INSTR(0x40, 0x00), |
---|
| 329 | + ILI9881C_COMMAND_INSTR(0x41, 0x00), |
---|
| 330 | + ILI9881C_COMMAND_INSTR(0x42, 0x00), |
---|
| 331 | + ILI9881C_COMMAND_INSTR(0x43, 0x00), |
---|
| 332 | + ILI9881C_COMMAND_INSTR(0x44, 0x00), |
---|
| 333 | + ILI9881C_COMMAND_INSTR(0x50, 0x01), |
---|
| 334 | + ILI9881C_COMMAND_INSTR(0x51, 0x23), |
---|
| 335 | + ILI9881C_COMMAND_INSTR(0x52, 0x45), |
---|
| 336 | + ILI9881C_COMMAND_INSTR(0x53, 0x67), |
---|
| 337 | + ILI9881C_COMMAND_INSTR(0x54, 0x89), |
---|
| 338 | + ILI9881C_COMMAND_INSTR(0x55, 0xAB), |
---|
| 339 | + ILI9881C_COMMAND_INSTR(0x56, 0x01), |
---|
| 340 | + ILI9881C_COMMAND_INSTR(0x57, 0x23), |
---|
| 341 | + ILI9881C_COMMAND_INSTR(0x58, 0x45), |
---|
| 342 | + ILI9881C_COMMAND_INSTR(0x59, 0x67), |
---|
| 343 | + ILI9881C_COMMAND_INSTR(0x5A, 0x89), |
---|
| 344 | + ILI9881C_COMMAND_INSTR(0x5B, 0xAB), |
---|
| 345 | + ILI9881C_COMMAND_INSTR(0x5C, 0xCD), |
---|
| 346 | + ILI9881C_COMMAND_INSTR(0x5D, 0xEF), |
---|
| 347 | + ILI9881C_COMMAND_INSTR(0x5E, 0x00), |
---|
| 348 | + ILI9881C_COMMAND_INSTR(0x5F, 0x01), |
---|
| 349 | + ILI9881C_COMMAND_INSTR(0x60, 0x01), |
---|
| 350 | + ILI9881C_COMMAND_INSTR(0x61, 0x06), |
---|
| 351 | + ILI9881C_COMMAND_INSTR(0x62, 0x06), |
---|
| 352 | + ILI9881C_COMMAND_INSTR(0x63, 0x07), |
---|
| 353 | + ILI9881C_COMMAND_INSTR(0x64, 0x07), |
---|
| 354 | + ILI9881C_COMMAND_INSTR(0x65, 0x00), |
---|
| 355 | + ILI9881C_COMMAND_INSTR(0x66, 0x00), |
---|
| 356 | + ILI9881C_COMMAND_INSTR(0x67, 0x02), |
---|
| 357 | + ILI9881C_COMMAND_INSTR(0x68, 0x02), |
---|
| 358 | + ILI9881C_COMMAND_INSTR(0x69, 0x05), |
---|
| 359 | + ILI9881C_COMMAND_INSTR(0x6A, 0x05), |
---|
| 360 | + ILI9881C_COMMAND_INSTR(0x6B, 0x02), |
---|
| 361 | + ILI9881C_COMMAND_INSTR(0x6C, 0x0D), |
---|
| 362 | + ILI9881C_COMMAND_INSTR(0x6D, 0x0D), |
---|
| 363 | + ILI9881C_COMMAND_INSTR(0x6E, 0x0C), |
---|
| 364 | + ILI9881C_COMMAND_INSTR(0x6F, 0x0C), |
---|
| 365 | + ILI9881C_COMMAND_INSTR(0x70, 0x0F), |
---|
| 366 | + ILI9881C_COMMAND_INSTR(0x71, 0x0F), |
---|
| 367 | + ILI9881C_COMMAND_INSTR(0x72, 0x0E), |
---|
| 368 | + ILI9881C_COMMAND_INSTR(0x73, 0x0E), |
---|
| 369 | + ILI9881C_COMMAND_INSTR(0x74, 0x02), |
---|
| 370 | + ILI9881C_COMMAND_INSTR(0x75, 0x01), |
---|
| 371 | + ILI9881C_COMMAND_INSTR(0x76, 0x01), |
---|
| 372 | + ILI9881C_COMMAND_INSTR(0x77, 0x06), |
---|
| 373 | + ILI9881C_COMMAND_INSTR(0x78, 0x06), |
---|
| 374 | + ILI9881C_COMMAND_INSTR(0x79, 0x07), |
---|
| 375 | + ILI9881C_COMMAND_INSTR(0x7A, 0x07), |
---|
| 376 | + ILI9881C_COMMAND_INSTR(0x7B, 0x00), |
---|
| 377 | + ILI9881C_COMMAND_INSTR(0x7C, 0x00), |
---|
| 378 | + ILI9881C_COMMAND_INSTR(0x7D, 0x02), |
---|
| 379 | + ILI9881C_COMMAND_INSTR(0x7E, 0x02), |
---|
| 380 | + ILI9881C_COMMAND_INSTR(0x7F, 0x05), |
---|
| 381 | + ILI9881C_COMMAND_INSTR(0x80, 0x05), |
---|
| 382 | + ILI9881C_COMMAND_INSTR(0x81, 0x02), |
---|
| 383 | + ILI9881C_COMMAND_INSTR(0x82, 0x0D), |
---|
| 384 | + ILI9881C_COMMAND_INSTR(0x83, 0x0D), |
---|
| 385 | + ILI9881C_COMMAND_INSTR(0x84, 0x0C), |
---|
| 386 | + ILI9881C_COMMAND_INSTR(0x85, 0x0C), |
---|
| 387 | + ILI9881C_COMMAND_INSTR(0x86, 0x0F), |
---|
| 388 | + ILI9881C_COMMAND_INSTR(0x87, 0x0F), |
---|
| 389 | + ILI9881C_COMMAND_INSTR(0x88, 0x0E), |
---|
| 390 | + ILI9881C_COMMAND_INSTR(0x89, 0x0E), |
---|
| 391 | + ILI9881C_COMMAND_INSTR(0x8A, 0x02), |
---|
| 392 | + ILI9881C_SWITCH_PAGE_INSTR(4), |
---|
| 393 | + ILI9881C_COMMAND_INSTR(0x3B, 0xC0), /* ILI4003D sel */ |
---|
| 394 | + ILI9881C_COMMAND_INSTR(0x6C, 0x15), /* Set VCORE voltage = 1.5V */ |
---|
| 395 | + ILI9881C_COMMAND_INSTR(0x6E, 0x2A), /* di_pwr_reg=0 for power mode 2A, VGH clamp 18V */ |
---|
| 396 | + ILI9881C_COMMAND_INSTR(0x6F, 0x33), /* pumping ratio VGH=5x VGL=-3x */ |
---|
| 397 | + ILI9881C_COMMAND_INSTR(0x8D, 0x1B), /* VGL clamp -10V */ |
---|
| 398 | + ILI9881C_COMMAND_INSTR(0x87, 0xBA), /* ESD */ |
---|
| 399 | + ILI9881C_COMMAND_INSTR(0x3A, 0x24), /* POWER SAVING */ |
---|
| 400 | + ILI9881C_COMMAND_INSTR(0x26, 0x76), |
---|
| 401 | + ILI9881C_COMMAND_INSTR(0xB2, 0xD1), |
---|
| 402 | + ILI9881C_SWITCH_PAGE_INSTR(1), |
---|
| 403 | + ILI9881C_COMMAND_INSTR(0x22, 0x0A), /* BGR, SS */ |
---|
| 404 | + ILI9881C_COMMAND_INSTR(0x31, 0x00), /* Zigzag type3 inversion */ |
---|
| 405 | + ILI9881C_COMMAND_INSTR(0x40, 0x53), /* ILI4003D sel */ |
---|
| 406 | + ILI9881C_COMMAND_INSTR(0x43, 0x66), |
---|
| 407 | + ILI9881C_COMMAND_INSTR(0x53, 0x4C), |
---|
| 408 | + ILI9881C_COMMAND_INSTR(0x50, 0x87), |
---|
| 409 | + ILI9881C_COMMAND_INSTR(0x51, 0x82), |
---|
| 410 | + ILI9881C_COMMAND_INSTR(0x60, 0x15), |
---|
| 411 | + ILI9881C_COMMAND_INSTR(0x61, 0x01), |
---|
| 412 | + ILI9881C_COMMAND_INSTR(0x62, 0x0C), |
---|
| 413 | + ILI9881C_COMMAND_INSTR(0x63, 0x00), |
---|
| 414 | + ILI9881C_COMMAND_INSTR(0xA0, 0x00), |
---|
| 415 | + ILI9881C_COMMAND_INSTR(0xA1, 0x13), /* VP251 */ |
---|
| 416 | + ILI9881C_COMMAND_INSTR(0xA2, 0x23), /* VP247 */ |
---|
| 417 | + ILI9881C_COMMAND_INSTR(0xA3, 0x14), /* VP243 */ |
---|
| 418 | + ILI9881C_COMMAND_INSTR(0xA4, 0x16), /* VP239 */ |
---|
| 419 | + ILI9881C_COMMAND_INSTR(0xA5, 0x29), /* VP231 */ |
---|
| 420 | + ILI9881C_COMMAND_INSTR(0xA6, 0x1E), /* VP219 */ |
---|
| 421 | + ILI9881C_COMMAND_INSTR(0xA7, 0x1D), /* VP203 */ |
---|
| 422 | + ILI9881C_COMMAND_INSTR(0xA8, 0x86), /* VP175 */ |
---|
| 423 | + ILI9881C_COMMAND_INSTR(0xA9, 0x1E), /* VP144 */ |
---|
| 424 | + ILI9881C_COMMAND_INSTR(0xAA, 0x29), /* VP111 */ |
---|
| 425 | + ILI9881C_COMMAND_INSTR(0xAB, 0x74), /* VP80 */ |
---|
| 426 | + ILI9881C_COMMAND_INSTR(0xAC, 0x19), /* VP52 */ |
---|
| 427 | + ILI9881C_COMMAND_INSTR(0xAD, 0x17), /* VP36 */ |
---|
| 428 | + ILI9881C_COMMAND_INSTR(0xAE, 0x4B), /* VP24 */ |
---|
| 429 | + ILI9881C_COMMAND_INSTR(0xAF, 0x20), /* VP16 */ |
---|
| 430 | + ILI9881C_COMMAND_INSTR(0xB0, 0x26), /* VP12 */ |
---|
| 431 | + ILI9881C_COMMAND_INSTR(0xB1, 0x4C), /* VP8 */ |
---|
| 432 | + ILI9881C_COMMAND_INSTR(0xB2, 0x5D), /* VP4 */ |
---|
| 433 | + ILI9881C_COMMAND_INSTR(0xB3, 0x3F), /* VP0 */ |
---|
| 434 | + ILI9881C_COMMAND_INSTR(0xC0, 0x00), /* VN255 GAMMA N */ |
---|
| 435 | + ILI9881C_COMMAND_INSTR(0xC1, 0x13), /* VN251 */ |
---|
| 436 | + ILI9881C_COMMAND_INSTR(0xC2, 0x23), /* VN247 */ |
---|
| 437 | + ILI9881C_COMMAND_INSTR(0xC3, 0x14), /* VN243 */ |
---|
| 438 | + ILI9881C_COMMAND_INSTR(0xC4, 0x16), /* VN239 */ |
---|
| 439 | + ILI9881C_COMMAND_INSTR(0xC5, 0x29), /* VN231 */ |
---|
| 440 | + ILI9881C_COMMAND_INSTR(0xC6, 0x1E), /* VN219 */ |
---|
| 441 | + ILI9881C_COMMAND_INSTR(0xC7, 0x1D), /* VN203 */ |
---|
| 442 | + ILI9881C_COMMAND_INSTR(0xC8, 0x86), /* VN175 */ |
---|
| 443 | + ILI9881C_COMMAND_INSTR(0xC9, 0x1E), /* VN144 */ |
---|
| 444 | + ILI9881C_COMMAND_INSTR(0xCA, 0x29), /* VN111 */ |
---|
| 445 | + ILI9881C_COMMAND_INSTR(0xCB, 0x74), /* VN80 */ |
---|
| 446 | + ILI9881C_COMMAND_INSTR(0xCC, 0x19), /* VN52 */ |
---|
| 447 | + ILI9881C_COMMAND_INSTR(0xCD, 0x17), /* VN36 */ |
---|
| 448 | + ILI9881C_COMMAND_INSTR(0xCE, 0x4B), /* VN24 */ |
---|
| 449 | + ILI9881C_COMMAND_INSTR(0xCF, 0x20), /* VN16 */ |
---|
| 450 | + ILI9881C_COMMAND_INSTR(0xD0, 0x26), /* VN12 */ |
---|
| 451 | + ILI9881C_COMMAND_INSTR(0xD1, 0x4C), /* VN8 */ |
---|
| 452 | + ILI9881C_COMMAND_INSTR(0xD2, 0x5D), /* VN4 */ |
---|
| 453 | + ILI9881C_COMMAND_INSTR(0xD3, 0x3F), /* VN0 */ |
---|
| 454 | +}; |
---|
| 455 | + |
---|
257 | 456 | static inline struct ili9881c *panel_to_ili9881c(struct drm_panel *panel) |
---|
258 | 457 | { |
---|
259 | 458 | return container_of(panel, struct ili9881c, panel); |
---|
.. | .. |
---|
313 | 512 | gpiod_set_value(ctx->reset, 0); |
---|
314 | 513 | msleep(20); |
---|
315 | 514 | |
---|
316 | | - for (i = 0; i < ARRAY_SIZE(ili9881c_init); i++) { |
---|
317 | | - const struct ili9881c_instr *instr = &ili9881c_init[i]; |
---|
| 515 | + for (i = 0; i < ctx->desc->init_length; i++) { |
---|
| 516 | + const struct ili9881c_instr *instr = &ctx->desc->init[i]; |
---|
318 | 517 | |
---|
319 | 518 | if (instr->op == ILI9881C_SWITCH_PAGE) |
---|
320 | 519 | ret = ili9881c_switch_page(ctx, instr->arg.page); |
---|
.. | .. |
---|
348 | 547 | msleep(120); |
---|
349 | 548 | |
---|
350 | 549 | mipi_dsi_dcs_set_display_on(ctx->dsi); |
---|
351 | | - backlight_enable(ctx->backlight); |
---|
352 | 550 | |
---|
353 | 551 | return 0; |
---|
354 | 552 | } |
---|
.. | .. |
---|
357 | 555 | { |
---|
358 | 556 | struct ili9881c *ctx = panel_to_ili9881c(panel); |
---|
359 | 557 | |
---|
360 | | - backlight_disable(ctx->backlight); |
---|
361 | 558 | return mipi_dsi_dcs_set_display_off(ctx->dsi); |
---|
362 | 559 | } |
---|
363 | 560 | |
---|
.. | .. |
---|
372 | 569 | return 0; |
---|
373 | 570 | } |
---|
374 | 571 | |
---|
375 | | -static const struct drm_display_mode bananapi_default_mode = { |
---|
| 572 | +static const struct drm_display_mode lhr050h41_default_mode = { |
---|
376 | 573 | .clock = 62000, |
---|
377 | | - .vrefresh = 60, |
---|
378 | 574 | |
---|
379 | 575 | .hdisplay = 720, |
---|
380 | 576 | .hsync_start = 720 + 10, |
---|
.. | .. |
---|
385 | 581 | .vsync_start = 1280 + 10, |
---|
386 | 582 | .vsync_end = 1280 + 10 + 10, |
---|
387 | 583 | .vtotal = 1280 + 10 + 10 + 20, |
---|
| 584 | + |
---|
| 585 | + .width_mm = 62, |
---|
| 586 | + .height_mm = 110, |
---|
388 | 587 | }; |
---|
389 | 588 | |
---|
390 | | -static int ili9881c_get_modes(struct drm_panel *panel) |
---|
| 589 | +static const struct drm_display_mode k101_im2byl02_default_mode = { |
---|
| 590 | + .clock = 69700, |
---|
| 591 | + |
---|
| 592 | + .hdisplay = 800, |
---|
| 593 | + .hsync_start = 800 + 52, |
---|
| 594 | + .hsync_end = 800 + 52 + 8, |
---|
| 595 | + .htotal = 800 + 52 + 8 + 48, |
---|
| 596 | + |
---|
| 597 | + .vdisplay = 1280, |
---|
| 598 | + .vsync_start = 1280 + 16, |
---|
| 599 | + .vsync_end = 1280 + 16 + 6, |
---|
| 600 | + .vtotal = 1280 + 16 + 6 + 15, |
---|
| 601 | + |
---|
| 602 | + .width_mm = 135, |
---|
| 603 | + .height_mm = 217, |
---|
| 604 | +}; |
---|
| 605 | + |
---|
| 606 | +static int ili9881c_get_modes(struct drm_panel *panel, |
---|
| 607 | + struct drm_connector *connector) |
---|
391 | 608 | { |
---|
392 | | - struct drm_connector *connector = panel->connector; |
---|
393 | 609 | struct ili9881c *ctx = panel_to_ili9881c(panel); |
---|
394 | 610 | struct drm_display_mode *mode; |
---|
395 | 611 | |
---|
396 | | - mode = drm_mode_duplicate(panel->drm, &bananapi_default_mode); |
---|
| 612 | + mode = drm_mode_duplicate(connector->dev, ctx->desc->mode); |
---|
397 | 613 | if (!mode) { |
---|
398 | 614 | dev_err(&ctx->dsi->dev, "failed to add mode %ux%ux@%u\n", |
---|
399 | | - bananapi_default_mode.hdisplay, |
---|
400 | | - bananapi_default_mode.vdisplay, |
---|
401 | | - bananapi_default_mode.vrefresh); |
---|
| 615 | + ctx->desc->mode->hdisplay, |
---|
| 616 | + ctx->desc->mode->vdisplay, |
---|
| 617 | + drm_mode_vrefresh(ctx->desc->mode)); |
---|
402 | 618 | return -ENOMEM; |
---|
403 | 619 | } |
---|
404 | 620 | |
---|
.. | .. |
---|
407 | 623 | mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; |
---|
408 | 624 | drm_mode_probed_add(connector, mode); |
---|
409 | 625 | |
---|
410 | | - panel->connector->display_info.width_mm = 62; |
---|
411 | | - panel->connector->display_info.height_mm = 110; |
---|
| 626 | + connector->display_info.width_mm = mode->width_mm; |
---|
| 627 | + connector->display_info.height_mm = mode->height_mm; |
---|
412 | 628 | |
---|
413 | 629 | return 1; |
---|
414 | 630 | } |
---|
.. | .. |
---|
423 | 639 | |
---|
424 | 640 | static int ili9881c_dsi_probe(struct mipi_dsi_device *dsi) |
---|
425 | 641 | { |
---|
426 | | - struct device_node *np; |
---|
427 | 642 | struct ili9881c *ctx; |
---|
428 | 643 | int ret; |
---|
429 | 644 | |
---|
.. | .. |
---|
432 | 647 | return -ENOMEM; |
---|
433 | 648 | mipi_dsi_set_drvdata(dsi, ctx); |
---|
434 | 649 | ctx->dsi = dsi; |
---|
| 650 | + ctx->desc = of_device_get_match_data(&dsi->dev); |
---|
435 | 651 | |
---|
436 | | - drm_panel_init(&ctx->panel); |
---|
437 | | - ctx->panel.dev = &dsi->dev; |
---|
438 | | - ctx->panel.funcs = &ili9881c_funcs; |
---|
| 652 | + drm_panel_init(&ctx->panel, &dsi->dev, &ili9881c_funcs, |
---|
| 653 | + DRM_MODE_CONNECTOR_DSI); |
---|
439 | 654 | |
---|
440 | 655 | ctx->power = devm_regulator_get(&dsi->dev, "power"); |
---|
441 | 656 | if (IS_ERR(ctx->power)) { |
---|
.. | .. |
---|
449 | 664 | return PTR_ERR(ctx->reset); |
---|
450 | 665 | } |
---|
451 | 666 | |
---|
452 | | - np = of_parse_phandle(dsi->dev.of_node, "backlight", 0); |
---|
453 | | - if (np) { |
---|
454 | | - ctx->backlight = of_find_backlight_by_node(np); |
---|
455 | | - of_node_put(np); |
---|
456 | | - |
---|
457 | | - if (!ctx->backlight) |
---|
458 | | - return -EPROBE_DEFER; |
---|
459 | | - } |
---|
460 | | - |
---|
461 | | - ret = drm_panel_add(&ctx->panel); |
---|
462 | | - if (ret < 0) |
---|
| 667 | + ret = drm_panel_of_backlight(&ctx->panel); |
---|
| 668 | + if (ret) |
---|
463 | 669 | return ret; |
---|
| 670 | + |
---|
| 671 | + drm_panel_add(&ctx->panel); |
---|
464 | 672 | |
---|
465 | 673 | dsi->mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE; |
---|
466 | 674 | dsi->format = MIPI_DSI_FMT_RGB888; |
---|
.. | .. |
---|
476 | 684 | mipi_dsi_detach(dsi); |
---|
477 | 685 | drm_panel_remove(&ctx->panel); |
---|
478 | 686 | |
---|
479 | | - if (ctx->backlight) |
---|
480 | | - put_device(&ctx->backlight->dev); |
---|
481 | | - |
---|
482 | 687 | return 0; |
---|
483 | 688 | } |
---|
484 | 689 | |
---|
| 690 | +static const struct ili9881c_desc lhr050h41_desc = { |
---|
| 691 | + .init = lhr050h41_init, |
---|
| 692 | + .init_length = ARRAY_SIZE(lhr050h41_init), |
---|
| 693 | + .mode = &lhr050h41_default_mode, |
---|
| 694 | +}; |
---|
| 695 | + |
---|
| 696 | +static const struct ili9881c_desc k101_im2byl02_desc = { |
---|
| 697 | + .init = k101_im2byl02_init, |
---|
| 698 | + .init_length = ARRAY_SIZE(k101_im2byl02_init), |
---|
| 699 | + .mode = &k101_im2byl02_default_mode, |
---|
| 700 | +}; |
---|
| 701 | + |
---|
485 | 702 | static const struct of_device_id ili9881c_of_match[] = { |
---|
486 | | - { .compatible = "bananapi,lhr050h41" }, |
---|
| 703 | + { .compatible = "bananapi,lhr050h41", .data = &lhr050h41_desc }, |
---|
| 704 | + { .compatible = "feixin,k101-im2byl02", .data = &k101_im2byl02_desc }, |
---|
487 | 705 | { } |
---|
488 | 706 | }; |
---|
489 | 707 | MODULE_DEVICE_TABLE(of, ili9881c_of_match); |
---|