| .. | .. |
|---|
| 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); |
|---|