root/drivers/video/fbdev/omap/lcd_mipid.c

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

DEFINITIONS

This source file includes following definitions.
  1. mipid_transfer
  2. mipid_cmd
  3. mipid_write
  4. mipid_read
  5. set_data_lines
  6. send_init_string
  7. hw_guard_start
  8. hw_guard_wait
  9. set_sleep_mode
  10. set_display_state
  11. mipid_set_bklight_level
  12. mipid_get_bklight_level
  13. mipid_get_bklight_max
  14. mipid_get_caps
  15. read_first_pixel
  16. mipid_run_test
  17. ls041y3_esd_recover
  18. ls041y3_esd_check_mode1
  19. ls041y3_esd_check_mode2
  20. ls041y3_esd_check
  21. mipid_esd_start_check
  22. mipid_esd_stop_check
  23. mipid_esd_work
  24. mipid_enable
  25. mipid_disable
  26. panel_enabled
  27. mipid_init
  28. mipid_cleanup
  29. mipid_detect
  30. mipid_spi_probe
  31. mipid_spi_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * LCD driver for MIPI DBI-C / DCS compatible LCDs
   4  *
   5  * Copyright (C) 2006 Nokia Corporation
   6  * Author: Imre Deak <imre.deak@nokia.com>
   7  */
   8 #include <linux/device.h>
   9 #include <linux/delay.h>
  10 #include <linux/slab.h>
  11 #include <linux/workqueue.h>
  12 #include <linux/spi/spi.h>
  13 #include <linux/module.h>
  14 
  15 #include <linux/platform_data/lcd-mipid.h>
  16 
  17 #include "omapfb.h"
  18 
  19 #define MIPID_MODULE_NAME               "lcd_mipid"
  20 
  21 #define MIPID_CMD_READ_DISP_ID          0x04
  22 #define MIPID_CMD_READ_RED              0x06
  23 #define MIPID_CMD_READ_GREEN            0x07
  24 #define MIPID_CMD_READ_BLUE             0x08
  25 #define MIPID_CMD_READ_DISP_STATUS      0x09
  26 #define MIPID_CMD_RDDSDR                0x0F
  27 #define MIPID_CMD_SLEEP_IN              0x10
  28 #define MIPID_CMD_SLEEP_OUT             0x11
  29 #define MIPID_CMD_DISP_OFF              0x28
  30 #define MIPID_CMD_DISP_ON               0x29
  31 
  32 #define MIPID_ESD_CHECK_PERIOD          msecs_to_jiffies(5000)
  33 
  34 #define to_mipid_device(p)              container_of(p, struct mipid_device, \
  35                                                 panel)
  36 struct mipid_device {
  37         int             enabled;
  38         int             revision;
  39         unsigned int    saved_bklight_level;
  40         unsigned long   hw_guard_end;           /* next value of jiffies
  41                                                    when we can issue the
  42                                                    next sleep in/out command */
  43         unsigned long   hw_guard_wait;          /* max guard time in jiffies */
  44 
  45         struct omapfb_device    *fbdev;
  46         struct spi_device       *spi;
  47         struct mutex            mutex;
  48         struct lcd_panel        panel;
  49 
  50         struct delayed_work     esd_work;
  51         void                    (*esd_check)(struct mipid_device *m);
  52 };
  53 
  54 static void mipid_transfer(struct mipid_device *md, int cmd, const u8 *wbuf,
  55                            int wlen, u8 *rbuf, int rlen)
  56 {
  57         struct spi_message      m;
  58         struct spi_transfer     *x, xfer[4];
  59         u16                     w;
  60         int                     r;
  61 
  62         BUG_ON(md->spi == NULL);
  63 
  64         spi_message_init(&m);
  65 
  66         memset(xfer, 0, sizeof(xfer));
  67         x = &xfer[0];
  68 
  69         cmd &=  0xff;
  70         x->tx_buf               = &cmd;
  71         x->bits_per_word        = 9;
  72         x->len                  = 2;
  73         spi_message_add_tail(x, &m);
  74 
  75         if (wlen) {
  76                 x++;
  77                 x->tx_buf               = wbuf;
  78                 x->len                  = wlen;
  79                 x->bits_per_word        = 9;
  80                 spi_message_add_tail(x, &m);
  81         }
  82 
  83         if (rlen) {
  84                 x++;
  85                 x->rx_buf       = &w;
  86                 x->len          = 1;
  87                 spi_message_add_tail(x, &m);
  88 
  89                 if (rlen > 1) {
  90                         /* Arrange for the extra clock before the first
  91                          * data bit.
  92                          */
  93                         x->bits_per_word = 9;
  94                         x->len           = 2;
  95 
  96                         x++;
  97                         x->rx_buf        = &rbuf[1];
  98                         x->len           = rlen - 1;
  99                         spi_message_add_tail(x, &m);
 100                 }
 101         }
 102 
 103         r = spi_sync(md->spi, &m);
 104         if (r < 0)
 105                 dev_dbg(&md->spi->dev, "spi_sync %d\n", r);
 106 
 107         if (rlen)
 108                 rbuf[0] = w & 0xff;
 109 }
 110 
 111 static inline void mipid_cmd(struct mipid_device *md, int cmd)
 112 {
 113         mipid_transfer(md, cmd, NULL, 0, NULL, 0);
 114 }
 115 
 116 static inline void mipid_write(struct mipid_device *md,
 117                                int reg, const u8 *buf, int len)
 118 {
 119         mipid_transfer(md, reg, buf, len, NULL, 0);
 120 }
 121 
 122 static inline void mipid_read(struct mipid_device *md,
 123                               int reg, u8 *buf, int len)
 124 {
 125         mipid_transfer(md, reg, NULL, 0, buf, len);
 126 }
 127 
 128 static void set_data_lines(struct mipid_device *md, int data_lines)
 129 {
 130         u16 par;
 131 
 132         switch (data_lines) {
 133         case 16:
 134                 par = 0x150;
 135                 break;
 136         case 18:
 137                 par = 0x160;
 138                 break;
 139         case 24:
 140                 par = 0x170;
 141                 break;
 142         }
 143         mipid_write(md, 0x3a, (u8 *)&par, 2);
 144 }
 145 
 146 static void send_init_string(struct mipid_device *md)
 147 {
 148         u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
 149 
 150         mipid_write(md, 0xc2, (u8 *)initpar, sizeof(initpar));
 151         set_data_lines(md, md->panel.data_lines);
 152 }
 153 
 154 static void hw_guard_start(struct mipid_device *md, int guard_msec)
 155 {
 156         md->hw_guard_wait = msecs_to_jiffies(guard_msec);
 157         md->hw_guard_end = jiffies + md->hw_guard_wait;
 158 }
 159 
 160 static void hw_guard_wait(struct mipid_device *md)
 161 {
 162         unsigned long wait = md->hw_guard_end - jiffies;
 163 
 164         if ((long)wait > 0 && time_before_eq(wait,  md->hw_guard_wait)) {
 165                 set_current_state(TASK_UNINTERRUPTIBLE);
 166                 schedule_timeout(wait);
 167         }
 168 }
 169 
 170 static void set_sleep_mode(struct mipid_device *md, int on)
 171 {
 172         int cmd, sleep_time = 50;
 173 
 174         if (on)
 175                 cmd = MIPID_CMD_SLEEP_IN;
 176         else
 177                 cmd = MIPID_CMD_SLEEP_OUT;
 178         hw_guard_wait(md);
 179         mipid_cmd(md, cmd);
 180         hw_guard_start(md, 120);
 181         /*
 182          * When we enable the panel, it seems we _have_ to sleep
 183          * 120 ms before sending the init string. When disabling the
 184          * panel we'll sleep for the duration of 2 frames, so that the
 185          * controller can still provide the PCLK,HS,VS signals.
 186          */
 187         if (!on)
 188                 sleep_time = 120;
 189         msleep(sleep_time);
 190 }
 191 
 192 static void set_display_state(struct mipid_device *md, int enabled)
 193 {
 194         int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF;
 195 
 196         mipid_cmd(md, cmd);
 197 }
 198 
 199 static int mipid_set_bklight_level(struct lcd_panel *panel, unsigned int level)
 200 {
 201         struct mipid_device *md = to_mipid_device(panel);
 202         struct mipid_platform_data *pd = md->spi->dev.platform_data;
 203 
 204         if (pd->get_bklight_max == NULL || pd->set_bklight_level == NULL)
 205                 return -ENODEV;
 206         if (level > pd->get_bklight_max(pd))
 207                 return -EINVAL;
 208         if (!md->enabled) {
 209                 md->saved_bklight_level = level;
 210                 return 0;
 211         }
 212         pd->set_bklight_level(pd, level);
 213 
 214         return 0;
 215 }
 216 
 217 static unsigned int mipid_get_bklight_level(struct lcd_panel *panel)
 218 {
 219         struct mipid_device *md = to_mipid_device(panel);
 220         struct mipid_platform_data *pd = md->spi->dev.platform_data;
 221 
 222         if (pd->get_bklight_level == NULL)
 223                 return -ENODEV;
 224         return pd->get_bklight_level(pd);
 225 }
 226 
 227 static unsigned int mipid_get_bklight_max(struct lcd_panel *panel)
 228 {
 229         struct mipid_device *md = to_mipid_device(panel);
 230         struct mipid_platform_data *pd = md->spi->dev.platform_data;
 231 
 232         if (pd->get_bklight_max == NULL)
 233                 return -ENODEV;
 234 
 235         return pd->get_bklight_max(pd);
 236 }
 237 
 238 static unsigned long mipid_get_caps(struct lcd_panel *panel)
 239 {
 240         return OMAPFB_CAPS_SET_BACKLIGHT;
 241 }
 242 
 243 static u16 read_first_pixel(struct mipid_device *md)
 244 {
 245         u16 pixel;
 246         u8 red, green, blue;
 247 
 248         mutex_lock(&md->mutex);
 249         mipid_read(md, MIPID_CMD_READ_RED, &red, 1);
 250         mipid_read(md, MIPID_CMD_READ_GREEN, &green, 1);
 251         mipid_read(md, MIPID_CMD_READ_BLUE, &blue, 1);
 252         mutex_unlock(&md->mutex);
 253 
 254         switch (md->panel.data_lines) {
 255         case 16:
 256                 pixel = ((red >> 1) << 11) | (green << 5) | (blue >> 1);
 257                 break;
 258         case 24:
 259                 /* 24 bit -> 16 bit */
 260                 pixel = ((red >> 3) << 11) | ((green >> 2) << 5) |
 261                         (blue >> 3);
 262                 break;
 263         default:
 264                 pixel = 0;
 265                 BUG();
 266         }
 267 
 268         return pixel;
 269 }
 270 
 271 static int mipid_run_test(struct lcd_panel *panel, int test_num)
 272 {
 273         struct mipid_device *md = to_mipid_device(panel);
 274         static const u16 test_values[4] = {
 275                 0x0000, 0xffff, 0xaaaa, 0x5555,
 276         };
 277         int i;
 278 
 279         if (test_num != MIPID_TEST_RGB_LINES)
 280                 return MIPID_TEST_INVALID;
 281 
 282         for (i = 0; i < ARRAY_SIZE(test_values); i++) {
 283                 int delay;
 284                 unsigned long tmo;
 285 
 286                 omapfb_write_first_pixel(md->fbdev, test_values[i]);
 287                 tmo = jiffies + msecs_to_jiffies(100);
 288                 delay = 25;
 289                 while (1) {
 290                         u16 pixel;
 291 
 292                         msleep(delay);
 293                         pixel = read_first_pixel(md);
 294                         if (pixel == test_values[i])
 295                                 break;
 296                         if (time_after(jiffies, tmo)) {
 297                                 dev_err(&md->spi->dev,
 298                                         "MIPI LCD RGB I/F test failed: "
 299                                         "expecting %04x, got %04x\n",
 300                                         test_values[i], pixel);
 301                                 return MIPID_TEST_FAILED;
 302                         }
 303                         delay = 10;
 304                 }
 305         }
 306 
 307         return 0;
 308 }
 309 
 310 static void ls041y3_esd_recover(struct mipid_device *md)
 311 {
 312         dev_err(&md->spi->dev, "performing LCD ESD recovery\n");
 313         set_sleep_mode(md, 1);
 314         set_sleep_mode(md, 0);
 315 }
 316 
 317 static void ls041y3_esd_check_mode1(struct mipid_device *md)
 318 {
 319         u8 state1, state2;
 320 
 321         mipid_read(md, MIPID_CMD_RDDSDR, &state1, 1);
 322         set_sleep_mode(md, 0);
 323         mipid_read(md, MIPID_CMD_RDDSDR, &state2, 1);
 324         dev_dbg(&md->spi->dev, "ESD mode 1 state1 %02x state2 %02x\n",
 325                 state1, state2);
 326         /* Each sleep out command will trigger a self diagnostic and flip
 327         * Bit6 if the test passes.
 328         */
 329         if (!((state1 ^ state2) & (1 << 6)))
 330                 ls041y3_esd_recover(md);
 331 }
 332 
 333 static void ls041y3_esd_check_mode2(struct mipid_device *md)
 334 {
 335         int i;
 336         u8 rbuf[2];
 337         static const struct {
 338                 int     cmd;
 339                 int     wlen;
 340                 u16     wbuf[3];
 341         } *rd, rd_ctrl[7] = {
 342                 { 0xb0, 4, { 0x0101, 0x01fe, } },
 343                 { 0xb1, 4, { 0x01de, 0x0121, } },
 344                 { 0xc2, 4, { 0x0100, 0x0100, } },
 345                 { 0xbd, 2, { 0x0100, } },
 346                 { 0xc2, 4, { 0x01fc, 0x0103, } },
 347                 { 0xb4, 0, },
 348                 { 0x00, 0, },
 349         };
 350 
 351         rd = rd_ctrl;
 352         for (i = 0; i < 3; i++, rd++)
 353                 mipid_write(md, rd->cmd, (u8 *)rd->wbuf, rd->wlen);
 354 
 355         udelay(10);
 356         mipid_read(md, rd->cmd, rbuf, 2);
 357         rd++;
 358 
 359         for (i = 0; i < 3; i++, rd++) {
 360                 udelay(10);
 361                 mipid_write(md, rd->cmd, (u8 *)rd->wbuf, rd->wlen);
 362         }
 363 
 364         dev_dbg(&md->spi->dev, "ESD mode 2 state %02x\n", rbuf[1]);
 365         if (rbuf[1] == 0x00)
 366                 ls041y3_esd_recover(md);
 367 }
 368 
 369 static void ls041y3_esd_check(struct mipid_device *md)
 370 {
 371         ls041y3_esd_check_mode1(md);
 372         if (md->revision >= 0x88)
 373                 ls041y3_esd_check_mode2(md);
 374 }
 375 
 376 static void mipid_esd_start_check(struct mipid_device *md)
 377 {
 378         if (md->esd_check != NULL)
 379                 schedule_delayed_work(&md->esd_work,
 380                                    MIPID_ESD_CHECK_PERIOD);
 381 }
 382 
 383 static void mipid_esd_stop_check(struct mipid_device *md)
 384 {
 385         if (md->esd_check != NULL)
 386                 cancel_delayed_work_sync(&md->esd_work);
 387 }
 388 
 389 static void mipid_esd_work(struct work_struct *work)
 390 {
 391         struct mipid_device *md = container_of(work, struct mipid_device,
 392                                                esd_work.work);
 393 
 394         mutex_lock(&md->mutex);
 395         md->esd_check(md);
 396         mutex_unlock(&md->mutex);
 397         mipid_esd_start_check(md);
 398 }
 399 
 400 static int mipid_enable(struct lcd_panel *panel)
 401 {
 402         struct mipid_device *md = to_mipid_device(panel);
 403 
 404         mutex_lock(&md->mutex);
 405 
 406         if (md->enabled) {
 407                 mutex_unlock(&md->mutex);
 408                 return 0;
 409         }
 410         set_sleep_mode(md, 0);
 411         md->enabled = 1;
 412         send_init_string(md);
 413         set_display_state(md, 1);
 414         mipid_set_bklight_level(panel, md->saved_bklight_level);
 415         mipid_esd_start_check(md);
 416 
 417         mutex_unlock(&md->mutex);
 418         return 0;
 419 }
 420 
 421 static void mipid_disable(struct lcd_panel *panel)
 422 {
 423         struct mipid_device *md = to_mipid_device(panel);
 424 
 425         /*
 426          * A final ESD work might be called before returning,
 427          * so do this without holding the lock.
 428          */
 429         mipid_esd_stop_check(md);
 430         mutex_lock(&md->mutex);
 431 
 432         if (!md->enabled) {
 433                 mutex_unlock(&md->mutex);
 434                 return;
 435         }
 436         md->saved_bklight_level = mipid_get_bklight_level(panel);
 437         mipid_set_bklight_level(panel, 0);
 438         set_display_state(md, 0);
 439         set_sleep_mode(md, 1);
 440         md->enabled = 0;
 441 
 442         mutex_unlock(&md->mutex);
 443 }
 444 
 445 static int panel_enabled(struct mipid_device *md)
 446 {
 447         u32 disp_status;
 448         int enabled;
 449 
 450         mipid_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4);
 451         disp_status = __be32_to_cpu(disp_status);
 452         enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10));
 453         dev_dbg(&md->spi->dev,
 454                 "LCD panel %senabled by bootloader (status 0x%04x)\n",
 455                 enabled ? "" : "not ", disp_status);
 456         return enabled;
 457 }
 458 
 459 static int mipid_init(struct lcd_panel *panel,
 460                             struct omapfb_device *fbdev)
 461 {
 462         struct mipid_device *md = to_mipid_device(panel);
 463 
 464         md->fbdev = fbdev;
 465         INIT_DELAYED_WORK(&md->esd_work, mipid_esd_work);
 466         mutex_init(&md->mutex);
 467 
 468         md->enabled = panel_enabled(md);
 469 
 470         if (md->enabled)
 471                 mipid_esd_start_check(md);
 472         else
 473                 md->saved_bklight_level = mipid_get_bklight_level(panel);
 474 
 475         return 0;
 476 }
 477 
 478 static void mipid_cleanup(struct lcd_panel *panel)
 479 {
 480         struct mipid_device *md = to_mipid_device(panel);
 481 
 482         if (md->enabled)
 483                 mipid_esd_stop_check(md);
 484 }
 485 
 486 static const struct lcd_panel mipid_panel = {
 487         .config         = OMAP_LCDC_PANEL_TFT,
 488 
 489         .bpp            = 16,
 490         .x_res          = 800,
 491         .y_res          = 480,
 492         .pixel_clock    = 21940,
 493         .hsw            = 50,
 494         .hfp            = 20,
 495         .hbp            = 15,
 496         .vsw            = 2,
 497         .vfp            = 1,
 498         .vbp            = 3,
 499 
 500         .init                   = mipid_init,
 501         .cleanup                = mipid_cleanup,
 502         .enable                 = mipid_enable,
 503         .disable                = mipid_disable,
 504         .get_caps               = mipid_get_caps,
 505         .set_bklight_level      = mipid_set_bklight_level,
 506         .get_bklight_level      = mipid_get_bklight_level,
 507         .get_bklight_max        = mipid_get_bklight_max,
 508         .run_test               = mipid_run_test,
 509 };
 510 
 511 static int mipid_detect(struct mipid_device *md)
 512 {
 513         struct mipid_platform_data *pdata;
 514         u8 display_id[3];
 515 
 516         pdata = md->spi->dev.platform_data;
 517         if (pdata == NULL) {
 518                 dev_err(&md->spi->dev, "missing platform data\n");
 519                 return -ENOENT;
 520         }
 521 
 522         mipid_read(md, MIPID_CMD_READ_DISP_ID, display_id, 3);
 523         dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n",
 524                 display_id[0], display_id[1], display_id[2]);
 525 
 526         switch (display_id[0]) {
 527         case 0x45:
 528                 md->panel.name = "lph8923";
 529                 break;
 530         case 0x83:
 531                 md->panel.name = "ls041y3";
 532                 md->esd_check = ls041y3_esd_check;
 533                 break;
 534         default:
 535                 md->panel.name = "unknown";
 536                 dev_err(&md->spi->dev, "invalid display ID\n");
 537                 return -ENODEV;
 538         }
 539 
 540         md->revision = display_id[1];
 541         md->panel.data_lines = pdata->data_lines;
 542         pr_info("omapfb: %s rev %02x LCD detected, %d data lines\n",
 543                         md->panel.name, md->revision, md->panel.data_lines);
 544 
 545         return 0;
 546 }
 547 
 548 static int mipid_spi_probe(struct spi_device *spi)
 549 {
 550         struct mipid_device *md;
 551         int r;
 552 
 553         md = kzalloc(sizeof(*md), GFP_KERNEL);
 554         if (md == NULL) {
 555                 dev_err(&spi->dev, "out of memory\n");
 556                 return -ENOMEM;
 557         }
 558 
 559         spi->mode = SPI_MODE_0;
 560         md->spi = spi;
 561         dev_set_drvdata(&spi->dev, md);
 562         md->panel = mipid_panel;
 563 
 564         r = mipid_detect(md);
 565         if (r < 0)
 566                 return r;
 567 
 568         omapfb_register_panel(&md->panel);
 569 
 570         return 0;
 571 }
 572 
 573 static int mipid_spi_remove(struct spi_device *spi)
 574 {
 575         struct mipid_device *md = dev_get_drvdata(&spi->dev);
 576 
 577         mipid_disable(&md->panel);
 578         kfree(md);
 579 
 580         return 0;
 581 }
 582 
 583 static struct spi_driver mipid_spi_driver = {
 584         .driver = {
 585                 .name   = MIPID_MODULE_NAME,
 586         },
 587         .probe  = mipid_spi_probe,
 588         .remove = mipid_spi_remove,
 589 };
 590 
 591 module_spi_driver(mipid_spi_driver);
 592 
 593 MODULE_DESCRIPTION("MIPI display driver");
 594 MODULE_LICENSE("GPL");

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