linux/drivers/video/omap2/displays/panel-taal.c
<<
>>
Prefs
   1/*
   2 * Taal DSI command mode panel
   3 *
   4 * Copyright (C) 2009 Nokia Corporation
   5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of the GNU General Public License version 2 as published by
   9 * the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  14 * more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along with
  17 * this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20/*#define DEBUG*/
  21
  22#include <linux/module.h>
  23#include <linux/delay.h>
  24#include <linux/err.h>
  25#include <linux/jiffies.h>
  26#include <linux/sched.h>
  27#include <linux/backlight.h>
  28#include <linux/fb.h>
  29#include <linux/interrupt.h>
  30#include <linux/gpio.h>
  31#include <linux/workqueue.h>
  32#include <linux/slab.h>
  33#include <linux/mutex.h>
  34
  35#include <video/omapdss.h>
  36#include <video/omap-panel-data.h>
  37#include <video/mipi_display.h>
  38
  39/* DSI Virtual channel. Hardcoded for now. */
  40#define TCH 0
  41
  42#define DCS_READ_NUM_ERRORS     0x05
  43#define DCS_BRIGHTNESS          0x51
  44#define DCS_CTRL_DISPLAY        0x53
  45#define DCS_WRITE_CABC          0x55
  46#define DCS_READ_CABC           0x56
  47#define DCS_GET_ID1             0xda
  48#define DCS_GET_ID2             0xdb
  49#define DCS_GET_ID3             0xdc
  50
  51static irqreturn_t taal_te_isr(int irq, void *data);
  52static void taal_te_timeout_work_callback(struct work_struct *work);
  53static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
  54
  55static int taal_panel_reset(struct omap_dss_device *dssdev);
  56
  57struct taal_data {
  58        struct mutex lock;
  59
  60        struct backlight_device *bldev;
  61
  62        unsigned long   hw_guard_end;   /* next value of jiffies when we can
  63                                         * issue the next sleep in/out command
  64                                         */
  65        unsigned long   hw_guard_wait;  /* max guard time in jiffies */
  66
  67        struct omap_dss_device *dssdev;
  68
  69        /* panel HW configuration from DT or platform data */
  70        int reset_gpio;
  71        int ext_te_gpio;
  72
  73        bool use_dsi_backlight;
  74
  75        struct omap_dsi_pin_config pin_config;
  76
  77        /* runtime variables */
  78        bool enabled;
  79
  80        bool te_enabled;
  81
  82        atomic_t do_update;
  83        int channel;
  84
  85        struct delayed_work te_timeout_work;
  86
  87        bool cabc_broken;
  88        unsigned cabc_mode;
  89
  90        bool intro_printed;
  91
  92        struct workqueue_struct *workqueue;
  93
  94        struct delayed_work esd_work;
  95        unsigned esd_interval;
  96
  97        bool ulps_enabled;
  98        unsigned ulps_timeout;
  99        struct delayed_work ulps_work;
 100};
 101
 102static void taal_esd_work(struct work_struct *work);
 103static void taal_ulps_work(struct work_struct *work);
 104
 105static void hw_guard_start(struct taal_data *td, int guard_msec)
 106{
 107        td->hw_guard_wait = msecs_to_jiffies(guard_msec);
 108        td->hw_guard_end = jiffies + td->hw_guard_wait;
 109}
 110
 111static void hw_guard_wait(struct taal_data *td)
 112{
 113        unsigned long wait = td->hw_guard_end - jiffies;
 114
 115        if ((long)wait > 0 && wait <= td->hw_guard_wait) {
 116                set_current_state(TASK_UNINTERRUPTIBLE);
 117                schedule_timeout(wait);
 118        }
 119}
 120
 121static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
 122{
 123        int r;
 124        u8 buf[1];
 125
 126        r = dsi_vc_dcs_read(td->dssdev, td->channel, dcs_cmd, buf, 1);
 127
 128        if (r < 0)
 129                return r;
 130
 131        *data = buf[0];
 132
 133        return 0;
 134}
 135
 136static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
 137{
 138        return dsi_vc_dcs_write(td->dssdev, td->channel, &dcs_cmd, 1);
 139}
 140
 141static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
 142{
 143        u8 buf[2];
 144        buf[0] = dcs_cmd;
 145        buf[1] = param;
 146        return dsi_vc_dcs_write(td->dssdev, td->channel, buf, 2);
 147}
 148
 149static int taal_sleep_in(struct taal_data *td)
 150
 151{
 152        u8 cmd;
 153        int r;
 154
 155        hw_guard_wait(td);
 156
 157        cmd = MIPI_DCS_ENTER_SLEEP_MODE;
 158        r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
 159        if (r)
 160                return r;
 161
 162        hw_guard_start(td, 120);
 163
 164        msleep(5);
 165
 166        return 0;
 167}
 168
 169static int taal_sleep_out(struct taal_data *td)
 170{
 171        int r;
 172
 173        hw_guard_wait(td);
 174
 175        r = taal_dcs_write_0(td, MIPI_DCS_EXIT_SLEEP_MODE);
 176        if (r)
 177                return r;
 178
 179        hw_guard_start(td, 120);
 180
 181        msleep(5);
 182
 183        return 0;
 184}
 185
 186static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3)
 187{
 188        int r;
 189
 190        r = taal_dcs_read_1(td, DCS_GET_ID1, id1);
 191        if (r)
 192                return r;
 193        r = taal_dcs_read_1(td, DCS_GET_ID2, id2);
 194        if (r)
 195                return r;
 196        r = taal_dcs_read_1(td, DCS_GET_ID3, id3);
 197        if (r)
 198                return r;
 199
 200        return 0;
 201}
 202
 203static int taal_set_update_window(struct taal_data *td,
 204                u16 x, u16 y, u16 w, u16 h)
 205{
 206        int r;
 207        u16 x1 = x;
 208        u16 x2 = x + w - 1;
 209        u16 y1 = y;
 210        u16 y2 = y + h - 1;
 211
 212        u8 buf[5];
 213        buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS;
 214        buf[1] = (x1 >> 8) & 0xff;
 215        buf[2] = (x1 >> 0) & 0xff;
 216        buf[3] = (x2 >> 8) & 0xff;
 217        buf[4] = (x2 >> 0) & 0xff;
 218
 219        r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
 220        if (r)
 221                return r;
 222
 223        buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
 224        buf[1] = (y1 >> 8) & 0xff;
 225        buf[2] = (y1 >> 0) & 0xff;
 226        buf[3] = (y2 >> 8) & 0xff;
 227        buf[4] = (y2 >> 0) & 0xff;
 228
 229        r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
 230        if (r)
 231                return r;
 232
 233        dsi_vc_send_bta_sync(td->dssdev, td->channel);
 234
 235        return r;
 236}
 237
 238static void taal_queue_esd_work(struct omap_dss_device *dssdev)
 239{
 240        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 241
 242        if (td->esd_interval > 0)
 243                queue_delayed_work(td->workqueue, &td->esd_work,
 244                                msecs_to_jiffies(td->esd_interval));
 245}
 246
 247static void taal_cancel_esd_work(struct omap_dss_device *dssdev)
 248{
 249        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 250
 251        cancel_delayed_work(&td->esd_work);
 252}
 253
 254static void taal_queue_ulps_work(struct omap_dss_device *dssdev)
 255{
 256        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 257
 258        if (td->ulps_timeout > 0)
 259                queue_delayed_work(td->workqueue, &td->ulps_work,
 260                                msecs_to_jiffies(td->ulps_timeout));
 261}
 262
 263static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
 264{
 265        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 266
 267        cancel_delayed_work(&td->ulps_work);
 268}
 269
 270static int taal_enter_ulps(struct omap_dss_device *dssdev)
 271{
 272        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 273        int r;
 274
 275        if (td->ulps_enabled)
 276                return 0;
 277
 278        taal_cancel_ulps_work(dssdev);
 279
 280        r = _taal_enable_te(dssdev, false);
 281        if (r)
 282                goto err;
 283
 284        if (gpio_is_valid(td->ext_te_gpio))
 285                disable_irq(gpio_to_irq(td->ext_te_gpio));
 286
 287        omapdss_dsi_display_disable(dssdev, false, true);
 288
 289        td->ulps_enabled = true;
 290
 291        return 0;
 292
 293err:
 294        dev_err(dssdev->dev, "enter ULPS failed");
 295        taal_panel_reset(dssdev);
 296
 297        td->ulps_enabled = false;
 298
 299        taal_queue_ulps_work(dssdev);
 300
 301        return r;
 302}
 303
 304static int taal_exit_ulps(struct omap_dss_device *dssdev)
 305{
 306        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 307        int r;
 308
 309        if (!td->ulps_enabled)
 310                return 0;
 311
 312        r = omapdss_dsi_display_enable(dssdev);
 313        if (r) {
 314                dev_err(dssdev->dev, "failed to enable DSI\n");
 315                goto err1;
 316        }
 317
 318        omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
 319
 320        r = _taal_enable_te(dssdev, true);
 321        if (r) {
 322                dev_err(dssdev->dev, "failed to re-enable TE");
 323                goto err2;
 324        }
 325
 326        if (gpio_is_valid(td->ext_te_gpio))
 327                enable_irq(gpio_to_irq(td->ext_te_gpio));
 328
 329        taal_queue_ulps_work(dssdev);
 330
 331        td->ulps_enabled = false;
 332
 333        return 0;
 334
 335err2:
 336        dev_err(dssdev->dev, "failed to exit ULPS");
 337
 338        r = taal_panel_reset(dssdev);
 339        if (!r) {
 340                if (gpio_is_valid(td->ext_te_gpio))
 341                        enable_irq(gpio_to_irq(td->ext_te_gpio));
 342                td->ulps_enabled = false;
 343        }
 344err1:
 345        taal_queue_ulps_work(dssdev);
 346
 347        return r;
 348}
 349
 350static int taal_wake_up(struct omap_dss_device *dssdev)
 351{
 352        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 353
 354        if (td->ulps_enabled)
 355                return taal_exit_ulps(dssdev);
 356
 357        taal_cancel_ulps_work(dssdev);
 358        taal_queue_ulps_work(dssdev);
 359        return 0;
 360}
 361
 362static int taal_bl_update_status(struct backlight_device *dev)
 363{
 364        struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
 365        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 366        int r;
 367        int level;
 368
 369        if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
 370                        dev->props.power == FB_BLANK_UNBLANK)
 371                level = dev->props.brightness;
 372        else
 373                level = 0;
 374
 375        dev_dbg(dssdev->dev, "update brightness to %d\n", level);
 376
 377        mutex_lock(&td->lock);
 378
 379        if (td->enabled) {
 380                dsi_bus_lock(dssdev);
 381
 382                r = taal_wake_up(dssdev);
 383                if (!r)
 384                        r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
 385
 386                dsi_bus_unlock(dssdev);
 387        } else {
 388                r = 0;
 389        }
 390
 391        mutex_unlock(&td->lock);
 392
 393        return r;
 394}
 395
 396static int taal_bl_get_intensity(struct backlight_device *dev)
 397{
 398        if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
 399                        dev->props.power == FB_BLANK_UNBLANK)
 400                return dev->props.brightness;
 401
 402        return 0;
 403}
 404
 405static const struct backlight_ops taal_bl_ops = {
 406        .get_brightness = taal_bl_get_intensity,
 407        .update_status  = taal_bl_update_status,
 408};
 409
 410static void taal_get_resolution(struct omap_dss_device *dssdev,
 411                u16 *xres, u16 *yres)
 412{
 413        *xres = dssdev->panel.timings.x_res;
 414        *yres = dssdev->panel.timings.y_res;
 415}
 416
 417static ssize_t taal_num_errors_show(struct device *dev,
 418                struct device_attribute *attr, char *buf)
 419{
 420        struct omap_dss_device *dssdev = to_dss_device(dev);
 421        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 422        u8 errors = 0;
 423        int r;
 424
 425        mutex_lock(&td->lock);
 426
 427        if (td->enabled) {
 428                dsi_bus_lock(dssdev);
 429
 430                r = taal_wake_up(dssdev);
 431                if (!r)
 432                        r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
 433
 434                dsi_bus_unlock(dssdev);
 435        } else {
 436                r = -ENODEV;
 437        }
 438
 439        mutex_unlock(&td->lock);
 440
 441        if (r)
 442                return r;
 443
 444        return snprintf(buf, PAGE_SIZE, "%d\n", errors);
 445}
 446
 447static ssize_t taal_hw_revision_show(struct device *dev,
 448                struct device_attribute *attr, char *buf)
 449{
 450        struct omap_dss_device *dssdev = to_dss_device(dev);
 451        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 452        u8 id1, id2, id3;
 453        int r;
 454
 455        mutex_lock(&td->lock);
 456
 457        if (td->enabled) {
 458                dsi_bus_lock(dssdev);
 459
 460                r = taal_wake_up(dssdev);
 461                if (!r)
 462                        r = taal_get_id(td, &id1, &id2, &id3);
 463
 464                dsi_bus_unlock(dssdev);
 465        } else {
 466                r = -ENODEV;
 467        }
 468
 469        mutex_unlock(&td->lock);
 470
 471        if (r)
 472                return r;
 473
 474        return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
 475}
 476
 477static const char *cabc_modes[] = {
 478        "off",          /* used also always when CABC is not supported */
 479        "ui",
 480        "still-image",
 481        "moving-image",
 482};
 483
 484static ssize_t show_cabc_mode(struct device *dev,
 485                struct device_attribute *attr,
 486                char *buf)
 487{
 488        struct omap_dss_device *dssdev = to_dss_device(dev);
 489        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 490        const char *mode_str;
 491        int mode;
 492        int len;
 493
 494        mode = td->cabc_mode;
 495
 496        mode_str = "unknown";
 497        if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes))
 498                mode_str = cabc_modes[mode];
 499        len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str);
 500
 501        return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1;
 502}
 503
 504static ssize_t store_cabc_mode(struct device *dev,
 505                struct device_attribute *attr,
 506                const char *buf, size_t count)
 507{
 508        struct omap_dss_device *dssdev = to_dss_device(dev);
 509        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 510        int i;
 511        int r;
 512
 513        for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
 514                if (sysfs_streq(cabc_modes[i], buf))
 515                        break;
 516        }
 517
 518        if (i == ARRAY_SIZE(cabc_modes))
 519                return -EINVAL;
 520
 521        mutex_lock(&td->lock);
 522
 523        if (td->enabled) {
 524                dsi_bus_lock(dssdev);
 525
 526                if (!td->cabc_broken) {
 527                        r = taal_wake_up(dssdev);
 528                        if (r)
 529                                goto err;
 530
 531                        r = taal_dcs_write_1(td, DCS_WRITE_CABC, i);
 532                        if (r)
 533                                goto err;
 534                }
 535
 536                dsi_bus_unlock(dssdev);
 537        }
 538
 539        td->cabc_mode = i;
 540
 541        mutex_unlock(&td->lock);
 542
 543        return count;
 544err:
 545        dsi_bus_unlock(dssdev);
 546        mutex_unlock(&td->lock);
 547        return r;
 548}
 549
 550static ssize_t show_cabc_available_modes(struct device *dev,
 551                struct device_attribute *attr,
 552                char *buf)
 553{
 554        int len;
 555        int i;
 556
 557        for (i = 0, len = 0;
 558             len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++)
 559                len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s",
 560                        i ? " " : "", cabc_modes[i],
 561                        i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : "");
 562
 563        return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
 564}
 565
 566static ssize_t taal_store_esd_interval(struct device *dev,
 567                struct device_attribute *attr,
 568                const char *buf, size_t count)
 569{
 570        struct omap_dss_device *dssdev = to_dss_device(dev);
 571        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 572
 573        unsigned long t;
 574        int r;
 575
 576        r = kstrtoul(buf, 10, &t);
 577        if (r)
 578                return r;
 579
 580        mutex_lock(&td->lock);
 581        taal_cancel_esd_work(dssdev);
 582        td->esd_interval = t;
 583        if (td->enabled)
 584                taal_queue_esd_work(dssdev);
 585        mutex_unlock(&td->lock);
 586
 587        return count;
 588}
 589
 590static ssize_t taal_show_esd_interval(struct device *dev,
 591                struct device_attribute *attr,
 592                char *buf)
 593{
 594        struct omap_dss_device *dssdev = to_dss_device(dev);
 595        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 596        unsigned t;
 597
 598        mutex_lock(&td->lock);
 599        t = td->esd_interval;
 600        mutex_unlock(&td->lock);
 601
 602        return snprintf(buf, PAGE_SIZE, "%u\n", t);
 603}
 604
 605static ssize_t taal_store_ulps(struct device *dev,
 606                struct device_attribute *attr,
 607                const char *buf, size_t count)
 608{
 609        struct omap_dss_device *dssdev = to_dss_device(dev);
 610        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 611        unsigned long t;
 612        int r;
 613
 614        r = kstrtoul(buf, 10, &t);
 615        if (r)
 616                return r;
 617
 618        mutex_lock(&td->lock);
 619
 620        if (td->enabled) {
 621                dsi_bus_lock(dssdev);
 622
 623                if (t)
 624                        r = taal_enter_ulps(dssdev);
 625                else
 626                        r = taal_wake_up(dssdev);
 627
 628                dsi_bus_unlock(dssdev);
 629        }
 630
 631        mutex_unlock(&td->lock);
 632
 633        if (r)
 634                return r;
 635
 636        return count;
 637}
 638
 639static ssize_t taal_show_ulps(struct device *dev,
 640                struct device_attribute *attr,
 641                char *buf)
 642{
 643        struct omap_dss_device *dssdev = to_dss_device(dev);
 644        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 645        unsigned t;
 646
 647        mutex_lock(&td->lock);
 648        t = td->ulps_enabled;
 649        mutex_unlock(&td->lock);
 650
 651        return snprintf(buf, PAGE_SIZE, "%u\n", t);
 652}
 653
 654static ssize_t taal_store_ulps_timeout(struct device *dev,
 655                struct device_attribute *attr,
 656                const char *buf, size_t count)
 657{
 658        struct omap_dss_device *dssdev = to_dss_device(dev);
 659        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 660        unsigned long t;
 661        int r;
 662
 663        r = kstrtoul(buf, 10, &t);
 664        if (r)
 665                return r;
 666
 667        mutex_lock(&td->lock);
 668        td->ulps_timeout = t;
 669
 670        if (td->enabled) {
 671                /* taal_wake_up will restart the timer */
 672                dsi_bus_lock(dssdev);
 673                r = taal_wake_up(dssdev);
 674                dsi_bus_unlock(dssdev);
 675        }
 676
 677        mutex_unlock(&td->lock);
 678
 679        if (r)
 680                return r;
 681
 682        return count;
 683}
 684
 685static ssize_t taal_show_ulps_timeout(struct device *dev,
 686                struct device_attribute *attr,
 687                char *buf)
 688{
 689        struct omap_dss_device *dssdev = to_dss_device(dev);
 690        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 691        unsigned t;
 692
 693        mutex_lock(&td->lock);
 694        t = td->ulps_timeout;
 695        mutex_unlock(&td->lock);
 696
 697        return snprintf(buf, PAGE_SIZE, "%u\n", t);
 698}
 699
 700static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL);
 701static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL);
 702static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR,
 703                show_cabc_mode, store_cabc_mode);
 704static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
 705                show_cabc_available_modes, NULL);
 706static DEVICE_ATTR(esd_interval, S_IRUGO | S_IWUSR,
 707                taal_show_esd_interval, taal_store_esd_interval);
 708static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,
 709                taal_show_ulps, taal_store_ulps);
 710static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR,
 711                taal_show_ulps_timeout, taal_store_ulps_timeout);
 712
 713static struct attribute *taal_attrs[] = {
 714        &dev_attr_num_dsi_errors.attr,
 715        &dev_attr_hw_revision.attr,
 716        &dev_attr_cabc_mode.attr,
 717        &dev_attr_cabc_available_modes.attr,
 718        &dev_attr_esd_interval.attr,
 719        &dev_attr_ulps.attr,
 720        &dev_attr_ulps_timeout.attr,
 721        NULL,
 722};
 723
 724static struct attribute_group taal_attr_group = {
 725        .attrs = taal_attrs,
 726};
 727
 728static void taal_hw_reset(struct omap_dss_device *dssdev)
 729{
 730        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 731
 732        if (!gpio_is_valid(td->reset_gpio))
 733                return;
 734
 735        gpio_set_value(td->reset_gpio, 1);
 736        udelay(10);
 737        /* reset the panel */
 738        gpio_set_value(td->reset_gpio, 0);
 739        /* assert reset */
 740        udelay(10);
 741        gpio_set_value(td->reset_gpio, 1);
 742        /* wait after releasing reset */
 743        msleep(5);
 744}
 745
 746static void taal_probe_pdata(struct taal_data *td,
 747                const struct nokia_dsi_panel_data *pdata)
 748{
 749        td->reset_gpio = pdata->reset_gpio;
 750
 751        if (pdata->use_ext_te)
 752                td->ext_te_gpio = pdata->ext_te_gpio;
 753        else
 754                td->ext_te_gpio = -1;
 755
 756        td->esd_interval = pdata->esd_interval;
 757        td->ulps_timeout = pdata->ulps_timeout;
 758
 759        td->use_dsi_backlight = pdata->use_dsi_backlight;
 760
 761        td->pin_config = pdata->pin_config;
 762}
 763
 764static int taal_probe(struct omap_dss_device *dssdev)
 765{
 766        struct backlight_properties props;
 767        struct taal_data *td;
 768        struct backlight_device *bldev = NULL;
 769        int r;
 770
 771        dev_dbg(dssdev->dev, "probe\n");
 772
 773        td = devm_kzalloc(dssdev->dev, sizeof(*td), GFP_KERNEL);
 774        if (!td)
 775                return -ENOMEM;
 776
 777        dev_set_drvdata(dssdev->dev, td);
 778        td->dssdev = dssdev;
 779
 780        if (dssdev->data) {
 781                const struct nokia_dsi_panel_data *pdata = dssdev->data;
 782
 783                taal_probe_pdata(td, pdata);
 784        } else {
 785                return -ENODEV;
 786        }
 787
 788        dssdev->panel.timings.x_res = 864;
 789        dssdev->panel.timings.y_res = 480;
 790        dssdev->panel.timings.pixel_clock = DIV_ROUND_UP(864 * 480 * 60, 1000);
 791        dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
 792        dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
 793                OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
 794
 795        mutex_init(&td->lock);
 796
 797        atomic_set(&td->do_update, 0);
 798
 799        if (gpio_is_valid(td->reset_gpio)) {
 800                r = devm_gpio_request_one(dssdev->dev, td->reset_gpio,
 801                                GPIOF_OUT_INIT_LOW, "taal rst");
 802                if (r) {
 803                        dev_err(dssdev->dev, "failed to request reset gpio\n");
 804                        return r;
 805                }
 806        }
 807
 808        if (gpio_is_valid(td->ext_te_gpio)) {
 809                r = devm_gpio_request_one(dssdev->dev, td->ext_te_gpio,
 810                                GPIOF_IN, "taal irq");
 811                if (r) {
 812                        dev_err(dssdev->dev, "GPIO request failed\n");
 813                        return r;
 814                }
 815
 816                r = devm_request_irq(dssdev->dev, gpio_to_irq(td->ext_te_gpio),
 817                                taal_te_isr,
 818                                IRQF_TRIGGER_RISING,
 819                                "taal vsync", dssdev);
 820
 821                if (r) {
 822                        dev_err(dssdev->dev, "IRQ request failed\n");
 823                        return r;
 824                }
 825
 826                INIT_DEFERRABLE_WORK(&td->te_timeout_work,
 827                                        taal_te_timeout_work_callback);
 828
 829                dev_dbg(dssdev->dev, "Using GPIO TE\n");
 830        }
 831
 832        td->workqueue = create_singlethread_workqueue("taal_esd");
 833        if (td->workqueue == NULL) {
 834                dev_err(dssdev->dev, "can't create ESD workqueue\n");
 835                return -ENOMEM;
 836        }
 837        INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work);
 838        INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
 839
 840        taal_hw_reset(dssdev);
 841
 842        if (td->use_dsi_backlight) {
 843                memset(&props, 0, sizeof(struct backlight_properties));
 844                props.max_brightness = 255;
 845
 846                props.type = BACKLIGHT_RAW;
 847                bldev = backlight_device_register(dev_name(dssdev->dev),
 848                                dssdev->dev, dssdev, &taal_bl_ops, &props);
 849                if (IS_ERR(bldev)) {
 850                        r = PTR_ERR(bldev);
 851                        goto err_bl;
 852                }
 853
 854                td->bldev = bldev;
 855
 856                bldev->props.fb_blank = FB_BLANK_UNBLANK;
 857                bldev->props.power = FB_BLANK_UNBLANK;
 858                bldev->props.brightness = 255;
 859
 860                taal_bl_update_status(bldev);
 861        }
 862
 863        r = omap_dsi_request_vc(dssdev, &td->channel);
 864        if (r) {
 865                dev_err(dssdev->dev, "failed to get virtual channel\n");
 866                goto err_req_vc;
 867        }
 868
 869        r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
 870        if (r) {
 871                dev_err(dssdev->dev, "failed to set VC_ID\n");
 872                goto err_vc_id;
 873        }
 874
 875        r = sysfs_create_group(&dssdev->dev->kobj, &taal_attr_group);
 876        if (r) {
 877                dev_err(dssdev->dev, "failed to create sysfs files\n");
 878                goto err_vc_id;
 879        }
 880
 881        return 0;
 882
 883err_vc_id:
 884        omap_dsi_release_vc(dssdev, td->channel);
 885err_req_vc:
 886        if (bldev != NULL)
 887                backlight_device_unregister(bldev);
 888err_bl:
 889        destroy_workqueue(td->workqueue);
 890        return r;
 891}
 892
 893static void __exit taal_remove(struct omap_dss_device *dssdev)
 894{
 895        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 896        struct backlight_device *bldev;
 897
 898        dev_dbg(dssdev->dev, "remove\n");
 899
 900        sysfs_remove_group(&dssdev->dev->kobj, &taal_attr_group);
 901        omap_dsi_release_vc(dssdev, td->channel);
 902
 903        bldev = td->bldev;
 904        if (bldev != NULL) {
 905                bldev->props.power = FB_BLANK_POWERDOWN;
 906                taal_bl_update_status(bldev);
 907                backlight_device_unregister(bldev);
 908        }
 909
 910        taal_cancel_ulps_work(dssdev);
 911        taal_cancel_esd_work(dssdev);
 912        destroy_workqueue(td->workqueue);
 913
 914        /* reset, to be sure that the panel is in a valid state */
 915        taal_hw_reset(dssdev);
 916}
 917
 918static int taal_power_on(struct omap_dss_device *dssdev)
 919{
 920        struct taal_data *td = dev_get_drvdata(dssdev->dev);
 921        u8 id1, id2, id3;
 922        int r;
 923        struct omap_dss_dsi_config dsi_config = {
 924                .mode = OMAP_DSS_DSI_CMD_MODE,
 925                .pixel_format = OMAP_DSS_DSI_FMT_RGB888,
 926                .timings = &dssdev->panel.timings,
 927                .hs_clk_min = 150000000,
 928                .hs_clk_max = 300000000,
 929                .lp_clk_min = 7000000,
 930                .lp_clk_max = 10000000,
 931        };
 932
 933        r = omapdss_dsi_configure_pins(dssdev, &td->pin_config);
 934        if (r) {
 935                dev_err(dssdev->dev, "failed to configure DSI pins\n");
 936                goto err0;
 937        };
 938
 939        r = omapdss_dsi_set_config(dssdev, &dsi_config);
 940        if (r) {
 941                dev_err(dssdev->dev, "failed to configure DSI\n");
 942                goto err0;
 943        }
 944
 945        r = omapdss_dsi_display_enable(dssdev);
 946        if (r) {
 947                dev_err(dssdev->dev, "failed to enable DSI\n");
 948                goto err0;
 949        }
 950
 951        taal_hw_reset(dssdev);
 952
 953        omapdss_dsi_vc_enable_hs(dssdev, td->channel, false);
 954
 955        r = taal_sleep_out(td);
 956        if (r)
 957                goto err;
 958
 959        r = taal_get_id(td, &id1, &id2, &id3);
 960        if (r)
 961                goto err;
 962
 963        /* on early Taal revisions CABC is broken */
 964        if (id2 == 0x00 || id2 == 0xff || id2 == 0x81)
 965                td->cabc_broken = true;
 966
 967        r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff);
 968        if (r)
 969                goto err;
 970
 971        r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY,
 972                        (1<<2) | (1<<5));       /* BL | BCTRL */
 973        if (r)
 974                goto err;
 975
 976        r = taal_dcs_write_1(td, MIPI_DCS_SET_PIXEL_FORMAT,
 977                MIPI_DCS_PIXEL_FMT_24BIT);
 978        if (r)
 979                goto err;
 980
 981        if (!td->cabc_broken) {
 982                r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode);
 983                if (r)
 984                        goto err;
 985        }
 986
 987        r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_ON);
 988        if (r)
 989                goto err;
 990
 991        r = _taal_enable_te(dssdev, td->te_enabled);
 992        if (r)
 993                goto err;
 994
 995        r = dsi_enable_video_output(dssdev, td->channel);
 996        if (r)
 997                goto err;
 998
 999        td->enabled = 1;
1000
1001        if (!td->intro_printed) {
1002                dev_info(dssdev->dev, "panel revision %02x.%02x.%02x\n",
1003                        id1, id2, id3);
1004                if (td->cabc_broken)
1005                        dev_info(dssdev->dev,
1006                                        "old Taal version, CABC disabled\n");
1007                td->intro_printed = true;
1008        }
1009
1010        omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
1011
1012        return 0;
1013err:
1014        dev_err(dssdev->dev, "error while enabling panel, issuing HW reset\n");
1015
1016        taal_hw_reset(dssdev);
1017
1018        omapdss_dsi_display_disable(dssdev, true, false);
1019err0:
1020        return r;
1021}
1022
1023static void taal_power_off(struct omap_dss_device *dssdev)
1024{
1025        struct taal_data *td = dev_get_drvdata(dssdev->dev);
1026        int r;
1027
1028        dsi_disable_video_output(dssdev, td->channel);
1029
1030        r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
1031        if (!r)
1032                r = taal_sleep_in(td);
1033
1034        if (r) {
1035                dev_err(dssdev->dev,
1036                                "error disabling panel, issuing HW reset\n");
1037                taal_hw_reset(dssdev);
1038        }
1039
1040        omapdss_dsi_display_disable(dssdev, true, false);
1041
1042        td->enabled = 0;
1043}
1044
1045static int taal_panel_reset(struct omap_dss_device *dssdev)
1046{
1047        dev_err(dssdev->dev, "performing LCD reset\n");
1048
1049        taal_power_off(dssdev);
1050        taal_hw_reset(dssdev);
1051        return taal_power_on(dssdev);
1052}
1053
1054static int taal_enable(struct omap_dss_device *dssdev)
1055{
1056        struct taal_data *td = dev_get_drvdata(dssdev->dev);
1057        int r;
1058
1059        dev_dbg(dssdev->dev, "enable\n");
1060
1061        mutex_lock(&td->lock);
1062
1063        if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
1064                r = -EINVAL;
1065                goto err;
1066        }
1067
1068        dsi_bus_lock(dssdev);
1069
1070        r = taal_power_on(dssdev);
1071
1072        dsi_bus_unlock(dssdev);
1073
1074        if (r)
1075                goto err;
1076
1077        taal_queue_esd_work(dssdev);
1078
1079        dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1080
1081        mutex_unlock(&td->lock);
1082
1083        return 0;
1084err:
1085        dev_dbg(dssdev->dev, "enable failed\n");
1086        mutex_unlock(&td->lock);
1087        return r;
1088}
1089
1090static void taal_disable(struct omap_dss_device *dssdev)
1091{
1092        struct taal_data *td = dev_get_drvdata(dssdev->dev);
1093
1094        dev_dbg(dssdev->dev, "disable\n");
1095
1096        mutex_lock(&td->lock);
1097
1098        taal_cancel_ulps_work(dssdev);
1099        taal_cancel_esd_work(dssdev);
1100
1101        dsi_bus_lock(dssdev);
1102
1103        if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
1104                int r;
1105
1106                r = taal_wake_up(dssdev);
1107                if (!r)
1108                        taal_power_off(dssdev);
1109        }
1110
1111        dsi_bus_unlock(dssdev);
1112
1113        dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
1114
1115        mutex_unlock(&td->lock);
1116}
1117
1118static void taal_framedone_cb(int err, void *data)
1119{
1120        struct omap_dss_device *dssdev = data;
1121        dev_dbg(dssdev->dev, "framedone, err %d\n", err);
1122        dsi_bus_unlock(dssdev);
1123}
1124
1125static irqreturn_t taal_te_isr(int irq, void *data)
1126{
1127        struct omap_dss_device *dssdev = data;
1128        struct taal_data *td = dev_get_drvdata(dssdev->dev);
1129        int old;
1130        int r;
1131
1132        old = atomic_cmpxchg(&td->do_update, 1, 0);
1133
1134        if (old) {
1135                cancel_delayed_work(&td->te_timeout_work);
1136
1137                r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb,
1138                                dssdev);
1139                if (r)
1140                        goto err;
1141        }
1142
1143        return IRQ_HANDLED;
1144err:
1145        dev_err(dssdev->dev, "start update failed\n");
1146        dsi_bus_unlock(dssdev);
1147        return IRQ_HANDLED;
1148}
1149
1150static void taal_te_timeout_work_callback(struct work_struct *work)
1151{
1152        struct taal_data *td = container_of(work, struct taal_data,
1153                                        te_timeout_work.work);
1154        struct omap_dss_device *dssdev = td->dssdev;
1155
1156        dev_err(dssdev->dev, "TE not received for 250ms!\n");
1157
1158        atomic_set(&td->do_update, 0);
1159        dsi_bus_unlock(dssdev);
1160}
1161
1162static int taal_update(struct omap_dss_device *dssdev,
1163                                    u16 x, u16 y, u16 w, u16 h)
1164{
1165        struct taal_data *td = dev_get_drvdata(dssdev->dev);
1166        int r;
1167
1168        dev_dbg(dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
1169
1170        mutex_lock(&td->lock);
1171        dsi_bus_lock(dssdev);
1172
1173        r = taal_wake_up(dssdev);
1174        if (r)
1175                goto err;
1176
1177        if (!td->enabled) {
1178                r = 0;
1179                goto err;
1180        }
1181
1182        /* XXX no need to send this every frame, but dsi break if not done */
1183        r = taal_set_update_window(td, 0, 0,
1184                        dssdev->panel.timings.x_res,
1185                        dssdev->panel.timings.y_res);
1186        if (r)
1187                goto err;
1188
1189        if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
1190                schedule_delayed_work(&td->te_timeout_work,
1191                                msecs_to_jiffies(250));
1192                atomic_set(&td->do_update, 1);
1193        } else {
1194                r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb,
1195                                dssdev);
1196                if (r)
1197                        goto err;
1198        }
1199
1200        /* note: no bus_unlock here. unlock is in framedone_cb */
1201        mutex_unlock(&td->lock);
1202        return 0;
1203err:
1204        dsi_bus_unlock(dssdev);
1205        mutex_unlock(&td->lock);
1206        return r;
1207}
1208
1209static int taal_sync(struct omap_dss_device *dssdev)
1210{
1211        struct taal_data *td = dev_get_drvdata(dssdev->dev);
1212
1213        dev_dbg(dssdev->dev, "sync\n");
1214
1215        mutex_lock(&td->lock);
1216        dsi_bus_lock(dssdev);
1217        dsi_bus_unlock(dssdev);
1218        mutex_unlock(&td->lock);
1219
1220        dev_dbg(dssdev->dev, "sync done\n");
1221
1222        return 0;
1223}
1224
1225static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1226{
1227        struct taal_data *td = dev_get_drvdata(dssdev->dev);
1228        int r;
1229
1230        if (enable)
1231                r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
1232        else
1233                r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
1234
1235        if (!gpio_is_valid(td->ext_te_gpio))
1236                omapdss_dsi_enable_te(dssdev, enable);
1237
1238        /* possible panel bug */
1239        msleep(100);
1240
1241        return r;
1242}
1243
1244static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1245{
1246        struct taal_data *td = dev_get_drvdata(dssdev->dev);
1247        int r;
1248
1249        mutex_lock(&td->lock);
1250
1251        if (td->te_enabled == enable)
1252                goto end;
1253
1254        dsi_bus_lock(dssdev);
1255
1256        if (td->enabled) {
1257                r = taal_wake_up(dssdev);
1258                if (r)
1259                        goto err;
1260
1261                r = _taal_enable_te(dssdev, enable);
1262                if (r)
1263                        goto err;
1264        }
1265
1266        td->te_enabled = enable;
1267
1268        dsi_bus_unlock(dssdev);
1269end:
1270        mutex_unlock(&td->lock);
1271
1272        return 0;
1273err:
1274        dsi_bus_unlock(dssdev);
1275        mutex_unlock(&td->lock);
1276
1277        return r;
1278}
1279
1280static int taal_get_te(struct omap_dss_device *dssdev)
1281{
1282        struct taal_data *td = dev_get_drvdata(dssdev->dev);
1283        int r;
1284
1285        mutex_lock(&td->lock);
1286        r = td->te_enabled;
1287        mutex_unlock(&td->lock);
1288
1289        return r;
1290}
1291
1292static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1293{
1294        struct taal_data *td = dev_get_drvdata(dssdev->dev);
1295        u8 id1, id2, id3;
1296        int r;
1297
1298        mutex_lock(&td->lock);
1299
1300        if (!td->enabled) {
1301                r = -ENODEV;
1302                goto err1;
1303        }
1304
1305        dsi_bus_lock(dssdev);
1306
1307        r = taal_wake_up(dssdev);
1308        if (r)
1309                goto err2;
1310
1311        r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
1312        if (r)
1313                goto err2;
1314        r = taal_dcs_read_1(td, DCS_GET_ID2, &id2);
1315        if (r)
1316                goto err2;
1317        r = taal_dcs_read_1(td, DCS_GET_ID3, &id3);
1318        if (r)
1319                goto err2;
1320
1321        dsi_bus_unlock(dssdev);
1322        mutex_unlock(&td->lock);
1323        return 0;
1324err2:
1325        dsi_bus_unlock(dssdev);
1326err1:
1327        mutex_unlock(&td->lock);
1328        return r;
1329}
1330
1331static int taal_memory_read(struct omap_dss_device *dssdev,
1332                void *buf, size_t size,
1333                u16 x, u16 y, u16 w, u16 h)
1334{
1335        int r;
1336        int first = 1;
1337        int plen;
1338        unsigned buf_used = 0;
1339        struct taal_data *td = dev_get_drvdata(dssdev->dev);
1340
1341        if (size < w * h * 3)
1342                return -ENOMEM;
1343
1344        mutex_lock(&td->lock);
1345
1346        if (!td->enabled) {
1347                r = -ENODEV;
1348                goto err1;
1349        }
1350
1351        size = min(w * h * 3,
1352                        dssdev->panel.timings.x_res *
1353                        dssdev->panel.timings.y_res * 3);
1354
1355        dsi_bus_lock(dssdev);
1356
1357        r = taal_wake_up(dssdev);
1358        if (r)
1359                goto err2;
1360
1361        /* plen 1 or 2 goes into short packet. until checksum error is fixed,
1362         * use short packets. plen 32 works, but bigger packets seem to cause
1363         * an error. */
1364        if (size % 2)
1365                plen = 1;
1366        else
1367                plen = 2;
1368
1369        taal_set_update_window(td, x, y, w, h);
1370
1371        r = dsi_vc_set_max_rx_packet_size(dssdev, td->channel, plen);
1372        if (r)
1373                goto err2;
1374
1375        while (buf_used < size) {
1376                u8 dcs_cmd = first ? 0x2e : 0x3e;
1377                first = 0;
1378
1379                r = dsi_vc_dcs_read(dssdev, td->channel, dcs_cmd,
1380                                buf + buf_used, size - buf_used);
1381
1382                if (r < 0) {
1383                        dev_err(dssdev->dev, "read error\n");
1384                        goto err3;
1385                }
1386
1387                buf_used += r;
1388
1389                if (r < plen) {
1390                        dev_err(dssdev->dev, "short read\n");
1391                        break;
1392                }
1393
1394                if (signal_pending(current)) {
1395                        dev_err(dssdev->dev, "signal pending, "
1396                                        "aborting memory read\n");
1397                        r = -ERESTARTSYS;
1398                        goto err3;
1399                }
1400        }
1401
1402        r = buf_used;
1403
1404err3:
1405        dsi_vc_set_max_rx_packet_size(dssdev, td->channel, 1);
1406err2:
1407        dsi_bus_unlock(dssdev);
1408err1:
1409        mutex_unlock(&td->lock);
1410        return r;
1411}
1412
1413static void taal_ulps_work(struct work_struct *work)
1414{
1415        struct taal_data *td = container_of(work, struct taal_data,
1416                        ulps_work.work);
1417        struct omap_dss_device *dssdev = td->dssdev;
1418
1419        mutex_lock(&td->lock);
1420
1421        if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !td->enabled) {
1422                mutex_unlock(&td->lock);
1423                return;
1424        }
1425
1426        dsi_bus_lock(dssdev);
1427
1428        taal_enter_ulps(dssdev);
1429
1430        dsi_bus_unlock(dssdev);
1431        mutex_unlock(&td->lock);
1432}
1433
1434static void taal_esd_work(struct work_struct *work)
1435{
1436        struct taal_data *td = container_of(work, struct taal_data,
1437                        esd_work.work);
1438        struct omap_dss_device *dssdev = td->dssdev;
1439        u8 state1, state2;
1440        int r;
1441
1442        mutex_lock(&td->lock);
1443
1444        if (!td->enabled) {
1445                mutex_unlock(&td->lock);
1446                return;
1447        }
1448
1449        dsi_bus_lock(dssdev);
1450
1451        r = taal_wake_up(dssdev);
1452        if (r) {
1453                dev_err(dssdev->dev, "failed to exit ULPS\n");
1454                goto err;
1455        }
1456
1457        r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1);
1458        if (r) {
1459                dev_err(dssdev->dev, "failed to read Taal status\n");
1460                goto err;
1461        }
1462
1463        /* Run self diagnostics */
1464        r = taal_sleep_out(td);
1465        if (r) {
1466                dev_err(dssdev->dev, "failed to run Taal self-diagnostics\n");
1467                goto err;
1468        }
1469
1470        r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2);
1471        if (r) {
1472                dev_err(dssdev->dev, "failed to read Taal status\n");
1473                goto err;
1474        }
1475
1476        /* Each sleep out command will trigger a self diagnostic and flip
1477         * Bit6 if the test passes.
1478         */
1479        if (!((state1 ^ state2) & (1 << 6))) {
1480                dev_err(dssdev->dev, "LCD self diagnostics failed\n");
1481                goto err;
1482        }
1483        /* Self-diagnostics result is also shown on TE GPIO line. We need
1484         * to re-enable TE after self diagnostics */
1485        if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
1486                r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
1487                if (r)
1488                        goto err;
1489        }
1490
1491        dsi_bus_unlock(dssdev);
1492
1493        taal_queue_esd_work(dssdev);
1494
1495        mutex_unlock(&td->lock);
1496        return;
1497err:
1498        dev_err(dssdev->dev, "performing LCD reset\n");
1499
1500        taal_panel_reset(dssdev);
1501
1502        dsi_bus_unlock(dssdev);
1503
1504        taal_queue_esd_work(dssdev);
1505
1506        mutex_unlock(&td->lock);
1507}
1508
1509static struct omap_dss_driver taal_driver = {
1510        .probe          = taal_probe,
1511        .remove         = __exit_p(taal_remove),
1512
1513        .enable         = taal_enable,
1514        .disable        = taal_disable,
1515
1516        .update         = taal_update,
1517        .sync           = taal_sync,
1518
1519        .get_resolution = taal_get_resolution,
1520        .get_recommended_bpp = omapdss_default_get_recommended_bpp,
1521
1522        .enable_te      = taal_enable_te,
1523        .get_te         = taal_get_te,
1524
1525        .run_test       = taal_run_test,
1526        .memory_read    = taal_memory_read,
1527
1528        .driver         = {
1529                .name   = "taal",
1530                .owner  = THIS_MODULE,
1531        },
1532};
1533
1534static int __init taal_init(void)
1535{
1536        omap_dss_register_driver(&taal_driver);
1537
1538        return 0;
1539}
1540
1541static void __exit taal_exit(void)
1542{
1543        omap_dss_unregister_driver(&taal_driver);
1544}
1545
1546module_init(taal_init);
1547module_exit(taal_exit);
1548
1549MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
1550MODULE_DESCRIPTION("Taal Driver");
1551MODULE_LICENSE("GPL");
1552