linux/drivers/video/fbdev/omap/lcd_mipid.c
<<
>>
Prefs
   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)
  36struct 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
  54static 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
 111static inline void mipid_cmd(struct mipid_device *md, int cmd)
 112{
 113        mipid_transfer(md, cmd, NULL, 0, NULL, 0);
 114}
 115
 116static 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
 122static 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
 128static 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
 146static 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
 154static 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
 160static 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
 170static 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
 192static 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
 199static 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
 217static 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
 227static 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
 238static unsigned long mipid_get_caps(struct lcd_panel *panel)
 239{
 240        return OMAPFB_CAPS_SET_BACKLIGHT;
 241}
 242
 243static 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
 271static 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
 310static 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
 317static 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
 333static 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
 369static 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
 376static 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
 383static 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
 389static 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
 400static 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
 421static 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
 445static 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
 459static 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
 478static 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
 486static 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
 511static 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
 548static 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
 573static 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
 583static 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
 591module_spi_driver(mipid_spi_driver);
 592
 593MODULE_DESCRIPTION("MIPI display driver");
 594MODULE_LICENSE("GPL");
 595