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/regulator/consumer.h>
  34#include <linux/mutex.h>
  35
  36#include <video/omapdss.h>
  37#include <video/omap-panel-nokia-dsi.h>
  38#include <video/mipi_display.h>
  39
  40/* DSI Virtual channel. Hardcoded for now. */
  41#define TCH 0
  42
  43#define DCS_READ_NUM_ERRORS     0x05
  44#define DCS_BRIGHTNESS          0x51
  45#define DCS_CTRL_DISPLAY        0x53
  46#define DCS_WRITE_CABC          0x55
  47#define DCS_READ_CABC           0x56
  48#define DCS_GET_ID1             0xda
  49#define DCS_GET_ID2             0xdb
  50#define DCS_GET_ID3             0xdc
  51
  52static irqreturn_t taal_te_isr(int irq, void *data);
  53static void taal_te_timeout_work_callback(struct work_struct *work);
  54static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
  55
  56static int taal_panel_reset(struct omap_dss_device *dssdev);
  57
  58struct panel_regulator {
  59        struct regulator *regulator;
  60        const char *name;
  61        int min_uV;
  62        int max_uV;
  63};
  64
  65static void free_regulators(struct panel_regulator *regulators, int n)
  66{
  67        int i;
  68
  69        for (i = 0; i < n; i++) {
  70                /* disable/put in reverse order */
  71                regulator_disable(regulators[n - i - 1].regulator);
  72                regulator_put(regulators[n - i - 1].regulator);
  73        }
  74}
  75
  76static int init_regulators(struct omap_dss_device *dssdev,
  77                        struct panel_regulator *regulators, int n)
  78{
  79        int r, i, v;
  80
  81        for (i = 0; i < n; i++) {
  82                struct regulator *reg;
  83
  84                reg = regulator_get(&dssdev->dev, regulators[i].name);
  85                if (IS_ERR(reg)) {
  86                        dev_err(&dssdev->dev, "failed to get regulator %s\n",
  87                                regulators[i].name);
  88                        r = PTR_ERR(reg);
  89                        goto err;
  90                }
  91
  92                /* FIXME: better handling of fixed vs. variable regulators */
  93                v = regulator_get_voltage(reg);
  94                if (v < regulators[i].min_uV || v > regulators[i].max_uV) {
  95                        r = regulator_set_voltage(reg, regulators[i].min_uV,
  96                                                regulators[i].max_uV);
  97                        if (r) {
  98                                dev_err(&dssdev->dev,
  99                                        "failed to set regulator %s voltage\n",
 100                                        regulators[i].name);
 101                                regulator_put(reg);
 102                                goto err;
 103                        }
 104                }
 105
 106                r = regulator_enable(reg);
 107                if (r) {
 108                        dev_err(&dssdev->dev, "failed to enable regulator %s\n",
 109                                regulators[i].name);
 110                        regulator_put(reg);
 111                        goto err;
 112                }
 113
 114                regulators[i].regulator = reg;
 115        }
 116
 117        return 0;
 118
 119err:
 120        free_regulators(regulators, i);
 121
 122        return r;
 123}
 124
 125/**
 126 * struct panel_config - panel configuration
 127 * @name: panel name
 128 * @type: panel type
 129 * @timings: panel resolution
 130 * @sleep: various panel specific delays, passed to msleep() if non-zero
 131 * @reset_sequence: reset sequence timings, passed to udelay() if non-zero
 132 * @regulators: array of panel regulators
 133 * @num_regulators: number of regulators in the array
 134 */
 135struct panel_config {
 136        const char *name;
 137        int type;
 138
 139        struct omap_video_timings timings;
 140
 141        struct {
 142                unsigned int sleep_in;
 143                unsigned int sleep_out;
 144                unsigned int hw_reset;
 145                unsigned int enable_te;
 146        } sleep;
 147
 148        struct {
 149                unsigned int high;
 150                unsigned int low;
 151        } reset_sequence;
 152
 153        struct panel_regulator *regulators;
 154        int num_regulators;
 155};
 156
 157enum {
 158        PANEL_TAAL,
 159};
 160
 161static struct panel_config panel_configs[] = {
 162        {
 163                .name           = "taal",
 164                .type           = PANEL_TAAL,
 165                .timings        = {
 166                        .x_res          = 864,
 167                        .y_res          = 480,
 168                },
 169                .sleep          = {
 170                        .sleep_in       = 5,
 171                        .sleep_out      = 5,
 172                        .hw_reset       = 5,
 173                        .enable_te      = 100, /* possible panel bug */
 174                },
 175                .reset_sequence = {
 176                        .high           = 10,
 177                        .low            = 10,
 178                },
 179        },
 180};
 181
 182struct taal_data {
 183        struct mutex lock;
 184
 185        struct backlight_device *bldev;
 186
 187        unsigned long   hw_guard_end;   /* next value of jiffies when we can
 188                                         * issue the next sleep in/out command
 189                                         */
 190        unsigned long   hw_guard_wait;  /* max guard time in jiffies */
 191
 192        struct omap_dss_device *dssdev;
 193
 194        bool enabled;
 195        u8 rotate;
 196        bool mirror;
 197
 198        bool te_enabled;
 199
 200        atomic_t do_update;
 201        struct {
 202                u16 x;
 203                u16 y;
 204                u16 w;
 205                u16 h;
 206        } update_region;
 207        int channel;
 208
 209        struct delayed_work te_timeout_work;
 210
 211        bool cabc_broken;
 212        unsigned cabc_mode;
 213
 214        bool intro_printed;
 215
 216        struct workqueue_struct *workqueue;
 217
 218        struct delayed_work esd_work;
 219        unsigned esd_interval;
 220
 221        bool ulps_enabled;
 222        unsigned ulps_timeout;
 223        struct delayed_work ulps_work;
 224
 225        struct panel_config *panel_config;
 226};
 227
 228static inline struct nokia_dsi_panel_data
 229*get_panel_data(const struct omap_dss_device *dssdev)
 230{
 231        return (struct nokia_dsi_panel_data *) dssdev->data;
 232}
 233
 234static void taal_esd_work(struct work_struct *work);
 235static void taal_ulps_work(struct work_struct *work);
 236
 237static void hw_guard_start(struct taal_data *td, int guard_msec)
 238{
 239        td->hw_guard_wait = msecs_to_jiffies(guard_msec);
 240        td->hw_guard_end = jiffies + td->hw_guard_wait;
 241}
 242
 243static void hw_guard_wait(struct taal_data *td)
 244{
 245        unsigned long wait = td->hw_guard_end - jiffies;
 246
 247        if ((long)wait > 0 && wait <= td->hw_guard_wait) {
 248                set_current_state(TASK_UNINTERRUPTIBLE);
 249                schedule_timeout(wait);
 250        }
 251}
 252
 253static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
 254{
 255        int r;
 256        u8 buf[1];
 257
 258        r = dsi_vc_dcs_read(td->dssdev, td->channel, dcs_cmd, buf, 1);
 259
 260        if (r < 0)
 261                return r;
 262
 263        *data = buf[0];
 264
 265        return 0;
 266}
 267
 268static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
 269{
 270        return dsi_vc_dcs_write(td->dssdev, td->channel, &dcs_cmd, 1);
 271}
 272
 273static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
 274{
 275        u8 buf[2];
 276        buf[0] = dcs_cmd;
 277        buf[1] = param;
 278        return dsi_vc_dcs_write(td->dssdev, td->channel, buf, 2);
 279}
 280
 281static int taal_sleep_in(struct taal_data *td)
 282
 283{
 284        u8 cmd;
 285        int r;
 286
 287        hw_guard_wait(td);
 288
 289        cmd = MIPI_DCS_ENTER_SLEEP_MODE;
 290        r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
 291        if (r)
 292                return r;
 293
 294        hw_guard_start(td, 120);
 295
 296        if (td->panel_config->sleep.sleep_in)
 297                msleep(td->panel_config->sleep.sleep_in);
 298
 299        return 0;
 300}
 301
 302static int taal_sleep_out(struct taal_data *td)
 303{
 304        int r;
 305
 306        hw_guard_wait(td);
 307
 308        r = taal_dcs_write_0(td, MIPI_DCS_EXIT_SLEEP_MODE);
 309        if (r)
 310                return r;
 311
 312        hw_guard_start(td, 120);
 313
 314        if (td->panel_config->sleep.sleep_out)
 315                msleep(td->panel_config->sleep.sleep_out);
 316
 317        return 0;
 318}
 319
 320static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3)
 321{
 322        int r;
 323
 324        r = taal_dcs_read_1(td, DCS_GET_ID1, id1);
 325        if (r)
 326                return r;
 327        r = taal_dcs_read_1(td, DCS_GET_ID2, id2);
 328        if (r)
 329                return r;
 330        r = taal_dcs_read_1(td, DCS_GET_ID3, id3);
 331        if (r)
 332                return r;
 333
 334        return 0;
 335}
 336
 337static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
 338{
 339        int r;
 340        u8 mode;
 341        int b5, b6, b7;
 342
 343        r = taal_dcs_read_1(td, MIPI_DCS_GET_ADDRESS_MODE, &mode);
 344        if (r)
 345                return r;
 346
 347        switch (rotate) {
 348        default:
 349        case 0:
 350                b7 = 0;
 351                b6 = 0;
 352                b5 = 0;
 353                break;
 354        case 1:
 355                b7 = 0;
 356                b6 = 1;
 357                b5 = 1;
 358                break;
 359        case 2:
 360                b7 = 1;
 361                b6 = 1;
 362                b5 = 0;
 363                break;
 364        case 3:
 365                b7 = 1;
 366                b6 = 0;
 367                b5 = 1;
 368                break;
 369        }
 370
 371        if (mirror)
 372                b6 = !b6;
 373
 374        mode &= ~((1<<7) | (1<<6) | (1<<5));
 375        mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
 376
 377        return taal_dcs_write_1(td, MIPI_DCS_SET_ADDRESS_MODE, mode);
 378}
 379
 380static int taal_set_update_window(struct taal_data *td,
 381                u16 x, u16 y, u16 w, u16 h)
 382{
 383        int r;
 384        u16 x1 = x;
 385        u16 x2 = x + w - 1;
 386        u16 y1 = y;
 387        u16 y2 = y + h - 1;
 388
 389        u8 buf[5];
 390        buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS;
 391        buf[1] = (x1 >> 8) & 0xff;
 392        buf[2] = (x1 >> 0) & 0xff;
 393        buf[3] = (x2 >> 8) & 0xff;
 394        buf[4] = (x2 >> 0) & 0xff;
 395
 396        r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
 397        if (r)
 398                return r;
 399
 400        buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
 401        buf[1] = (y1 >> 8) & 0xff;
 402        buf[2] = (y1 >> 0) & 0xff;
 403        buf[3] = (y2 >> 8) & 0xff;
 404        buf[4] = (y2 >> 0) & 0xff;
 405
 406        r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
 407        if (r)
 408                return r;
 409
 410        dsi_vc_send_bta_sync(td->dssdev, td->channel);
 411
 412        return r;
 413}
 414
 415static void taal_queue_esd_work(struct omap_dss_device *dssdev)
 416{
 417        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 418
 419        if (td->esd_interval > 0)
 420                queue_delayed_work(td->workqueue, &td->esd_work,
 421                                msecs_to_jiffies(td->esd_interval));
 422}
 423
 424static void taal_cancel_esd_work(struct omap_dss_device *dssdev)
 425{
 426        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 427
 428        cancel_delayed_work(&td->esd_work);
 429}
 430
 431static void taal_queue_ulps_work(struct omap_dss_device *dssdev)
 432{
 433        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 434
 435        if (td->ulps_timeout > 0)
 436                queue_delayed_work(td->workqueue, &td->ulps_work,
 437                                msecs_to_jiffies(td->ulps_timeout));
 438}
 439
 440static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
 441{
 442        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 443
 444        cancel_delayed_work(&td->ulps_work);
 445}
 446
 447static int taal_enter_ulps(struct omap_dss_device *dssdev)
 448{
 449        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 450        struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 451        int r;
 452
 453        if (td->ulps_enabled)
 454                return 0;
 455
 456        taal_cancel_ulps_work(dssdev);
 457
 458        r = _taal_enable_te(dssdev, false);
 459        if (r)
 460                goto err;
 461
 462        disable_irq(gpio_to_irq(panel_data->ext_te_gpio));
 463
 464        omapdss_dsi_display_disable(dssdev, false, true);
 465
 466        td->ulps_enabled = true;
 467
 468        return 0;
 469
 470err:
 471        dev_err(&dssdev->dev, "enter ULPS failed");
 472        taal_panel_reset(dssdev);
 473
 474        td->ulps_enabled = false;
 475
 476        taal_queue_ulps_work(dssdev);
 477
 478        return r;
 479}
 480
 481static int taal_exit_ulps(struct omap_dss_device *dssdev)
 482{
 483        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 484        struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 485        int r;
 486
 487        if (!td->ulps_enabled)
 488                return 0;
 489
 490        r = omapdss_dsi_display_enable(dssdev);
 491        if (r) {
 492                dev_err(&dssdev->dev, "failed to enable DSI\n");
 493                goto err1;
 494        }
 495
 496        omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
 497
 498        r = _taal_enable_te(dssdev, true);
 499        if (r) {
 500                dev_err(&dssdev->dev, "failed to re-enable TE");
 501                goto err2;
 502        }
 503
 504        enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
 505
 506        taal_queue_ulps_work(dssdev);
 507
 508        td->ulps_enabled = false;
 509
 510        return 0;
 511
 512err2:
 513        dev_err(&dssdev->dev, "failed to exit ULPS");
 514
 515        r = taal_panel_reset(dssdev);
 516        if (!r) {
 517                enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
 518                td->ulps_enabled = false;
 519        }
 520err1:
 521        taal_queue_ulps_work(dssdev);
 522
 523        return r;
 524}
 525
 526static int taal_wake_up(struct omap_dss_device *dssdev)
 527{
 528        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 529
 530        if (td->ulps_enabled)
 531                return taal_exit_ulps(dssdev);
 532
 533        taal_cancel_ulps_work(dssdev);
 534        taal_queue_ulps_work(dssdev);
 535        return 0;
 536}
 537
 538static int taal_bl_update_status(struct backlight_device *dev)
 539{
 540        struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
 541        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 542        int r;
 543        int level;
 544
 545        if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
 546                        dev->props.power == FB_BLANK_UNBLANK)
 547                level = dev->props.brightness;
 548        else
 549                level = 0;
 550
 551        dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
 552
 553        mutex_lock(&td->lock);
 554
 555        if (td->enabled) {
 556                dsi_bus_lock(dssdev);
 557
 558                r = taal_wake_up(dssdev);
 559                if (!r)
 560                        r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
 561
 562                dsi_bus_unlock(dssdev);
 563        } else {
 564                r = 0;
 565        }
 566
 567        mutex_unlock(&td->lock);
 568
 569        return r;
 570}
 571
 572static int taal_bl_get_intensity(struct backlight_device *dev)
 573{
 574        if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
 575                        dev->props.power == FB_BLANK_UNBLANK)
 576                return dev->props.brightness;
 577
 578        return 0;
 579}
 580
 581static const struct backlight_ops taal_bl_ops = {
 582        .get_brightness = taal_bl_get_intensity,
 583        .update_status  = taal_bl_update_status,
 584};
 585
 586static void taal_get_timings(struct omap_dss_device *dssdev,
 587                        struct omap_video_timings *timings)
 588{
 589        *timings = dssdev->panel.timings;
 590}
 591
 592static void taal_get_resolution(struct omap_dss_device *dssdev,
 593                u16 *xres, u16 *yres)
 594{
 595        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 596
 597        if (td->rotate == 0 || td->rotate == 2) {
 598                *xres = dssdev->panel.timings.x_res;
 599                *yres = dssdev->panel.timings.y_res;
 600        } else {
 601                *yres = dssdev->panel.timings.x_res;
 602                *xres = dssdev->panel.timings.y_res;
 603        }
 604}
 605
 606static ssize_t taal_num_errors_show(struct device *dev,
 607                struct device_attribute *attr, char *buf)
 608{
 609        struct omap_dss_device *dssdev = to_dss_device(dev);
 610        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 611        u8 errors;
 612        int r;
 613
 614        mutex_lock(&td->lock);
 615
 616        if (td->enabled) {
 617                dsi_bus_lock(dssdev);
 618
 619                r = taal_wake_up(dssdev);
 620                if (!r)
 621                        r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
 622
 623                dsi_bus_unlock(dssdev);
 624        } else {
 625                r = -ENODEV;
 626        }
 627
 628        mutex_unlock(&td->lock);
 629
 630        if (r)
 631                return r;
 632
 633        return snprintf(buf, PAGE_SIZE, "%d\n", errors);
 634}
 635
 636static ssize_t taal_hw_revision_show(struct device *dev,
 637                struct device_attribute *attr, char *buf)
 638{
 639        struct omap_dss_device *dssdev = to_dss_device(dev);
 640        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 641        u8 id1, id2, id3;
 642        int r;
 643
 644        mutex_lock(&td->lock);
 645
 646        if (td->enabled) {
 647                dsi_bus_lock(dssdev);
 648
 649                r = taal_wake_up(dssdev);
 650                if (!r)
 651                        r = taal_get_id(td, &id1, &id2, &id3);
 652
 653                dsi_bus_unlock(dssdev);
 654        } else {
 655                r = -ENODEV;
 656        }
 657
 658        mutex_unlock(&td->lock);
 659
 660        if (r)
 661                return r;
 662
 663        return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
 664}
 665
 666static const char *cabc_modes[] = {
 667        "off",          /* used also always when CABC is not supported */
 668        "ui",
 669        "still-image",
 670        "moving-image",
 671};
 672
 673static ssize_t show_cabc_mode(struct device *dev,
 674                struct device_attribute *attr,
 675                char *buf)
 676{
 677        struct omap_dss_device *dssdev = to_dss_device(dev);
 678        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 679        const char *mode_str;
 680        int mode;
 681        int len;
 682
 683        mode = td->cabc_mode;
 684
 685        mode_str = "unknown";
 686        if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes))
 687                mode_str = cabc_modes[mode];
 688        len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str);
 689
 690        return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1;
 691}
 692
 693static ssize_t store_cabc_mode(struct device *dev,
 694                struct device_attribute *attr,
 695                const char *buf, size_t count)
 696{
 697        struct omap_dss_device *dssdev = to_dss_device(dev);
 698        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 699        int i;
 700        int r;
 701
 702        for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
 703                if (sysfs_streq(cabc_modes[i], buf))
 704                        break;
 705        }
 706
 707        if (i == ARRAY_SIZE(cabc_modes))
 708                return -EINVAL;
 709
 710        mutex_lock(&td->lock);
 711
 712        if (td->enabled) {
 713                dsi_bus_lock(dssdev);
 714
 715                if (!td->cabc_broken) {
 716                        r = taal_wake_up(dssdev);
 717                        if (r)
 718                                goto err;
 719
 720                        r = taal_dcs_write_1(td, DCS_WRITE_CABC, i);
 721                        if (r)
 722                                goto err;
 723                }
 724
 725                dsi_bus_unlock(dssdev);
 726        }
 727
 728        td->cabc_mode = i;
 729
 730        mutex_unlock(&td->lock);
 731
 732        return count;
 733err:
 734        dsi_bus_unlock(dssdev);
 735        mutex_unlock(&td->lock);
 736        return r;
 737}
 738
 739static ssize_t show_cabc_available_modes(struct device *dev,
 740                struct device_attribute *attr,
 741                char *buf)
 742{
 743        int len;
 744        int i;
 745
 746        for (i = 0, len = 0;
 747             len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++)
 748                len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s",
 749                        i ? " " : "", cabc_modes[i],
 750                        i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : "");
 751
 752        return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
 753}
 754
 755static ssize_t taal_store_esd_interval(struct device *dev,
 756                struct device_attribute *attr,
 757                const char *buf, size_t count)
 758{
 759        struct omap_dss_device *dssdev = to_dss_device(dev);
 760        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 761
 762        unsigned long t;
 763        int r;
 764
 765        r = strict_strtoul(buf, 10, &t);
 766        if (r)
 767                return r;
 768
 769        mutex_lock(&td->lock);
 770        taal_cancel_esd_work(dssdev);
 771        td->esd_interval = t;
 772        if (td->enabled)
 773                taal_queue_esd_work(dssdev);
 774        mutex_unlock(&td->lock);
 775
 776        return count;
 777}
 778
 779static ssize_t taal_show_esd_interval(struct device *dev,
 780                struct device_attribute *attr,
 781                char *buf)
 782{
 783        struct omap_dss_device *dssdev = to_dss_device(dev);
 784        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 785        unsigned t;
 786
 787        mutex_lock(&td->lock);
 788        t = td->esd_interval;
 789        mutex_unlock(&td->lock);
 790
 791        return snprintf(buf, PAGE_SIZE, "%u\n", t);
 792}
 793
 794static ssize_t taal_store_ulps(struct device *dev,
 795                struct device_attribute *attr,
 796                const char *buf, size_t count)
 797{
 798        struct omap_dss_device *dssdev = to_dss_device(dev);
 799        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 800        unsigned long t;
 801        int r;
 802
 803        r = strict_strtoul(buf, 10, &t);
 804        if (r)
 805                return r;
 806
 807        mutex_lock(&td->lock);
 808
 809        if (td->enabled) {
 810                dsi_bus_lock(dssdev);
 811
 812                if (t)
 813                        r = taal_enter_ulps(dssdev);
 814                else
 815                        r = taal_wake_up(dssdev);
 816
 817                dsi_bus_unlock(dssdev);
 818        }
 819
 820        mutex_unlock(&td->lock);
 821
 822        if (r)
 823                return r;
 824
 825        return count;
 826}
 827
 828static ssize_t taal_show_ulps(struct device *dev,
 829                struct device_attribute *attr,
 830                char *buf)
 831{
 832        struct omap_dss_device *dssdev = to_dss_device(dev);
 833        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 834        unsigned t;
 835
 836        mutex_lock(&td->lock);
 837        t = td->ulps_enabled;
 838        mutex_unlock(&td->lock);
 839
 840        return snprintf(buf, PAGE_SIZE, "%u\n", t);
 841}
 842
 843static ssize_t taal_store_ulps_timeout(struct device *dev,
 844                struct device_attribute *attr,
 845                const char *buf, size_t count)
 846{
 847        struct omap_dss_device *dssdev = to_dss_device(dev);
 848        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 849        unsigned long t;
 850        int r;
 851
 852        r = strict_strtoul(buf, 10, &t);
 853        if (r)
 854                return r;
 855
 856        mutex_lock(&td->lock);
 857        td->ulps_timeout = t;
 858
 859        if (td->enabled) {
 860                /* taal_wake_up will restart the timer */
 861                dsi_bus_lock(dssdev);
 862                r = taal_wake_up(dssdev);
 863                dsi_bus_unlock(dssdev);
 864        }
 865
 866        mutex_unlock(&td->lock);
 867
 868        if (r)
 869                return r;
 870
 871        return count;
 872}
 873
 874static ssize_t taal_show_ulps_timeout(struct device *dev,
 875                struct device_attribute *attr,
 876                char *buf)
 877{
 878        struct omap_dss_device *dssdev = to_dss_device(dev);
 879        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 880        unsigned t;
 881
 882        mutex_lock(&td->lock);
 883        t = td->ulps_timeout;
 884        mutex_unlock(&td->lock);
 885
 886        return snprintf(buf, PAGE_SIZE, "%u\n", t);
 887}
 888
 889static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL);
 890static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL);
 891static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR,
 892                show_cabc_mode, store_cabc_mode);
 893static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
 894                show_cabc_available_modes, NULL);
 895static DEVICE_ATTR(esd_interval, S_IRUGO | S_IWUSR,
 896                taal_show_esd_interval, taal_store_esd_interval);
 897static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,
 898                taal_show_ulps, taal_store_ulps);
 899static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR,
 900                taal_show_ulps_timeout, taal_store_ulps_timeout);
 901
 902static struct attribute *taal_attrs[] = {
 903        &dev_attr_num_dsi_errors.attr,
 904        &dev_attr_hw_revision.attr,
 905        &dev_attr_cabc_mode.attr,
 906        &dev_attr_cabc_available_modes.attr,
 907        &dev_attr_esd_interval.attr,
 908        &dev_attr_ulps.attr,
 909        &dev_attr_ulps_timeout.attr,
 910        NULL,
 911};
 912
 913static struct attribute_group taal_attr_group = {
 914        .attrs = taal_attrs,
 915};
 916
 917static void taal_hw_reset(struct omap_dss_device *dssdev)
 918{
 919        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 920        struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 921
 922        if (panel_data->reset_gpio == -1)
 923                return;
 924
 925        gpio_set_value(panel_data->reset_gpio, 1);
 926        if (td->panel_config->reset_sequence.high)
 927                udelay(td->panel_config->reset_sequence.high);
 928        /* reset the panel */
 929        gpio_set_value(panel_data->reset_gpio, 0);
 930        /* assert reset */
 931        if (td->panel_config->reset_sequence.low)
 932                udelay(td->panel_config->reset_sequence.low);
 933        gpio_set_value(panel_data->reset_gpio, 1);
 934        /* wait after releasing reset */
 935        if (td->panel_config->sleep.hw_reset)
 936                msleep(td->panel_config->sleep.hw_reset);
 937}
 938
 939static int taal_probe(struct omap_dss_device *dssdev)
 940{
 941        struct backlight_properties props;
 942        struct taal_data *td;
 943        struct backlight_device *bldev = NULL;
 944        struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 945        struct panel_config *panel_config = NULL;
 946        int r, i;
 947
 948        dev_dbg(&dssdev->dev, "probe\n");
 949
 950        if (!panel_data || !panel_data->name) {
 951                r = -EINVAL;
 952                goto err;
 953        }
 954
 955        for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
 956                if (strcmp(panel_data->name, panel_configs[i].name) == 0) {
 957                        panel_config = &panel_configs[i];
 958                        break;
 959                }
 960        }
 961
 962        if (!panel_config) {
 963                r = -EINVAL;
 964                goto err;
 965        }
 966
 967        dssdev->panel.config = OMAP_DSS_LCD_TFT;
 968        dssdev->panel.timings = panel_config->timings;
 969        dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
 970
 971        td = kzalloc(sizeof(*td), GFP_KERNEL);
 972        if (!td) {
 973                r = -ENOMEM;
 974                goto err;
 975        }
 976        td->dssdev = dssdev;
 977        td->panel_config = panel_config;
 978        td->esd_interval = panel_data->esd_interval;
 979        td->ulps_enabled = false;
 980        td->ulps_timeout = panel_data->ulps_timeout;
 981
 982        mutex_init(&td->lock);
 983
 984        atomic_set(&td->do_update, 0);
 985
 986        r = init_regulators(dssdev, panel_config->regulators,
 987                        panel_config->num_regulators);
 988        if (r)
 989                goto err_reg;
 990
 991        td->workqueue = create_singlethread_workqueue("taal_esd");
 992        if (td->workqueue == NULL) {
 993                dev_err(&dssdev->dev, "can't create ESD workqueue\n");
 994                r = -ENOMEM;
 995                goto err_wq;
 996        }
 997        INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
 998        INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
 999
1000        dev_set_drvdata(&dssdev->dev, td);
1001
1002        taal_hw_reset(dssdev);
1003
1004        if (panel_data->use_dsi_backlight) {
1005                memset(&props, 0, sizeof(struct backlight_properties));
1006                props.max_brightness = 255;
1007
1008                props.type = BACKLIGHT_RAW;
1009                bldev = backlight_device_register(dev_name(&dssdev->dev),
1010                                &dssdev->dev, dssdev, &taal_bl_ops, &props);
1011                if (IS_ERR(bldev)) {
1012                        r = PTR_ERR(bldev);
1013                        goto err_bl;
1014                }
1015
1016                td->bldev = bldev;
1017
1018                bldev->props.fb_blank = FB_BLANK_UNBLANK;
1019                bldev->props.power = FB_BLANK_UNBLANK;
1020                bldev->props.brightness = 255;
1021
1022                taal_bl_update_status(bldev);
1023        }
1024
1025        if (panel_data->use_ext_te) {
1026                int gpio = panel_data->ext_te_gpio;
1027
1028                r = gpio_request(gpio, "taal irq");
1029                if (r) {
1030                        dev_err(&dssdev->dev, "GPIO request failed\n");
1031                        goto err_gpio;
1032                }
1033
1034                gpio_direction_input(gpio);
1035
1036                r = request_irq(gpio_to_irq(gpio), taal_te_isr,
1037                                IRQF_TRIGGER_RISING,
1038                                "taal vsync", dssdev);
1039
1040                if (r) {
1041                        dev_err(&dssdev->dev, "IRQ request failed\n");
1042                        gpio_free(gpio);
1043                        goto err_irq;
1044                }
1045
1046                INIT_DELAYED_WORK_DEFERRABLE(&td->te_timeout_work,
1047                                        taal_te_timeout_work_callback);
1048
1049                dev_dbg(&dssdev->dev, "Using GPIO TE\n");
1050        }
1051
1052        r = omap_dsi_request_vc(dssdev, &td->channel);
1053        if (r) {
1054                dev_err(&dssdev->dev, "failed to get virtual channel\n");
1055                goto err_req_vc;
1056        }
1057
1058        r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
1059        if (r) {
1060                dev_err(&dssdev->dev, "failed to set VC_ID\n");
1061                goto err_vc_id;
1062        }
1063
1064        r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
1065        if (r) {
1066                dev_err(&dssdev->dev, "failed to create sysfs files\n");
1067                goto err_vc_id;
1068        }
1069
1070        return 0;
1071
1072err_vc_id:
1073        omap_dsi_release_vc(dssdev, td->channel);
1074err_req_vc:
1075        if (panel_data->use_ext_te)
1076                free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
1077err_irq:
1078        if (panel_data->use_ext_te)
1079                gpio_free(panel_data->ext_te_gpio);
1080err_gpio:
1081        if (bldev != NULL)
1082                backlight_device_unregister(bldev);
1083err_bl:
1084        destroy_workqueue(td->workqueue);
1085err_wq:
1086        free_regulators(panel_config->regulators, panel_config->num_regulators);
1087err_reg:
1088        kfree(td);
1089err:
1090        return r;
1091}
1092
1093static void __exit taal_remove(struct omap_dss_device *dssdev)
1094{
1095        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1096        struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1097        struct backlight_device *bldev;
1098
1099        dev_dbg(&dssdev->dev, "remove\n");
1100
1101        sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
1102        omap_dsi_release_vc(dssdev, td->channel);
1103
1104        if (panel_data->use_ext_te) {
1105                int gpio = panel_data->ext_te_gpio;
1106                free_irq(gpio_to_irq(gpio), dssdev);
1107                gpio_free(gpio);
1108        }
1109
1110        bldev = td->bldev;
1111        if (bldev != NULL) {
1112                bldev->props.power = FB_BLANK_POWERDOWN;
1113                taal_bl_update_status(bldev);
1114                backlight_device_unregister(bldev);
1115        }
1116
1117        taal_cancel_ulps_work(dssdev);
1118        taal_cancel_esd_work(dssdev);
1119        destroy_workqueue(td->workqueue);
1120
1121        /* reset, to be sure that the panel is in a valid state */
1122        taal_hw_reset(dssdev);
1123
1124        free_regulators(td->panel_config->regulators,
1125                        td->panel_config->num_regulators);
1126
1127        kfree(td);
1128}
1129
1130static int taal_power_on(struct omap_dss_device *dssdev)
1131{
1132        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1133        u8 id1, id2, id3;
1134        int r;
1135
1136        r = omapdss_dsi_display_enable(dssdev);
1137        if (r) {
1138                dev_err(&dssdev->dev, "failed to enable DSI\n");
1139                goto err0;
1140        }
1141
1142        taal_hw_reset(dssdev);
1143
1144        omapdss_dsi_vc_enable_hs(dssdev, td->channel, false);
1145
1146        r = taal_sleep_out(td);
1147        if (r)
1148                goto err;
1149
1150        r = taal_get_id(td, &id1, &id2, &id3);
1151        if (r)
1152                goto err;
1153
1154        /* on early Taal revisions CABC is broken */
1155        if (td->panel_config->type == PANEL_TAAL &&
1156                (id2 == 0x00 || id2 == 0xff || id2 == 0x81))
1157                td->cabc_broken = true;
1158
1159        r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff);
1160        if (r)
1161                goto err;
1162
1163        r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY,
1164                        (1<<2) | (1<<5));       /* BL | BCTRL */
1165        if (r)
1166                goto err;
1167
1168        r = taal_dcs_write_1(td, MIPI_DCS_SET_PIXEL_FORMAT,
1169                MIPI_DCS_PIXEL_FMT_24BIT);
1170        if (r)
1171                goto err;
1172
1173        r = taal_set_addr_mode(td, td->rotate, td->mirror);
1174        if (r)
1175                goto err;
1176
1177        if (!td->cabc_broken) {
1178                r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode);
1179                if (r)
1180                        goto err;
1181        }
1182
1183        r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_ON);
1184        if (r)
1185                goto err;
1186
1187        r = _taal_enable_te(dssdev, td->te_enabled);
1188        if (r)
1189                goto err;
1190
1191        td->enabled = 1;
1192
1193        if (!td->intro_printed) {
1194                dev_info(&dssdev->dev, "%s panel revision %02x.%02x.%02x\n",
1195                        td->panel_config->name, id1, id2, id3);
1196                if (td->cabc_broken)
1197                        dev_info(&dssdev->dev,
1198                                        "old Taal version, CABC disabled\n");
1199                td->intro_printed = true;
1200        }
1201
1202        omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
1203
1204        return 0;
1205err:
1206        dev_err(&dssdev->dev, "error while enabling panel, issuing HW reset\n");
1207
1208        taal_hw_reset(dssdev);
1209
1210        omapdss_dsi_display_disable(dssdev, true, false);
1211err0:
1212        return r;
1213}
1214
1215static void taal_power_off(struct omap_dss_device *dssdev)
1216{
1217        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1218        int r;
1219
1220        r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
1221        if (!r)
1222                r = taal_sleep_in(td);
1223
1224        if (r) {
1225                dev_err(&dssdev->dev,
1226                                "error disabling panel, issuing HW reset\n");
1227                taal_hw_reset(dssdev);
1228        }
1229
1230        omapdss_dsi_display_disable(dssdev, true, false);
1231
1232        td->enabled = 0;
1233}
1234
1235static int taal_panel_reset(struct omap_dss_device *dssdev)
1236{
1237        dev_err(&dssdev->dev, "performing LCD reset\n");
1238
1239        taal_power_off(dssdev);
1240        taal_hw_reset(dssdev);
1241        return taal_power_on(dssdev);
1242}
1243
1244static int taal_enable(struct omap_dss_device *dssdev)
1245{
1246        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1247        int r;
1248
1249        dev_dbg(&dssdev->dev, "enable\n");
1250
1251        mutex_lock(&td->lock);
1252
1253        if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
1254                r = -EINVAL;
1255                goto err;
1256        }
1257
1258        dsi_bus_lock(dssdev);
1259
1260        r = taal_power_on(dssdev);
1261
1262        dsi_bus_unlock(dssdev);
1263
1264        if (r)
1265                goto err;
1266
1267        taal_queue_esd_work(dssdev);
1268
1269        dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1270
1271        mutex_unlock(&td->lock);
1272
1273        return 0;
1274err:
1275        dev_dbg(&dssdev->dev, "enable failed\n");
1276        mutex_unlock(&td->lock);
1277        return r;
1278}
1279
1280static void taal_disable(struct omap_dss_device *dssdev)
1281{
1282        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1283
1284        dev_dbg(&dssdev->dev, "disable\n");
1285
1286        mutex_lock(&td->lock);
1287
1288        taal_cancel_ulps_work(dssdev);
1289        taal_cancel_esd_work(dssdev);
1290
1291        dsi_bus_lock(dssdev);
1292
1293        if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
1294                int r;
1295
1296                r = taal_wake_up(dssdev);
1297                if (!r)
1298                        taal_power_off(dssdev);
1299        }
1300
1301        dsi_bus_unlock(dssdev);
1302
1303        dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
1304
1305        mutex_unlock(&td->lock);
1306}
1307
1308static int taal_suspend(struct omap_dss_device *dssdev)
1309{
1310        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1311        int r;
1312
1313        dev_dbg(&dssdev->dev, "suspend\n");
1314
1315        mutex_lock(&td->lock);
1316
1317        if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
1318                r = -EINVAL;
1319                goto err;
1320        }
1321
1322        taal_cancel_ulps_work(dssdev);
1323        taal_cancel_esd_work(dssdev);
1324
1325        dsi_bus_lock(dssdev);
1326
1327        r = taal_wake_up(dssdev);
1328        if (!r)
1329                taal_power_off(dssdev);
1330
1331        dsi_bus_unlock(dssdev);
1332
1333        dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
1334
1335        mutex_unlock(&td->lock);
1336
1337        return 0;
1338err:
1339        mutex_unlock(&td->lock);
1340        return r;
1341}
1342
1343static int taal_resume(struct omap_dss_device *dssdev)
1344{
1345        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1346        int r;
1347
1348        dev_dbg(&dssdev->dev, "resume\n");
1349
1350        mutex_lock(&td->lock);
1351
1352        if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
1353                r = -EINVAL;
1354                goto err;
1355        }
1356
1357        dsi_bus_lock(dssdev);
1358
1359        r = taal_power_on(dssdev);
1360
1361        dsi_bus_unlock(dssdev);
1362
1363        if (r) {
1364                dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
1365        } else {
1366                dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1367                taal_queue_esd_work(dssdev);
1368        }
1369
1370        mutex_unlock(&td->lock);
1371
1372        return r;
1373err:
1374        mutex_unlock(&td->lock);
1375        return r;
1376}
1377
1378static void taal_framedone_cb(int err, void *data)
1379{
1380        struct omap_dss_device *dssdev = data;
1381        dev_dbg(&dssdev->dev, "framedone, err %d\n", err);
1382        dsi_bus_unlock(dssdev);
1383}
1384
1385static irqreturn_t taal_te_isr(int irq, void *data)
1386{
1387        struct omap_dss_device *dssdev = data;
1388        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1389        int old;
1390        int r;
1391
1392        old = atomic_cmpxchg(&td->do_update, 1, 0);
1393
1394        if (old) {
1395                cancel_delayed_work(&td->te_timeout_work);
1396
1397                r = omap_dsi_update(dssdev, td->channel,
1398                                td->update_region.x,
1399                                td->update_region.y,
1400                                td->update_region.w,
1401                                td->update_region.h,
1402                                taal_framedone_cb, dssdev);
1403                if (r)
1404                        goto err;
1405        }
1406
1407        return IRQ_HANDLED;
1408err:
1409        dev_err(&dssdev->dev, "start update failed\n");
1410        dsi_bus_unlock(dssdev);
1411        return IRQ_HANDLED;
1412}
1413
1414static void taal_te_timeout_work_callback(struct work_struct *work)
1415{
1416        struct taal_data *td = container_of(work, struct taal_data,
1417                                        te_timeout_work.work);
1418        struct omap_dss_device *dssdev = td->dssdev;
1419
1420        dev_err(&dssdev->dev, "TE not received for 250ms!\n");
1421
1422        atomic_set(&td->do_update, 0);
1423        dsi_bus_unlock(dssdev);
1424}
1425
1426static int taal_update(struct omap_dss_device *dssdev,
1427                                    u16 x, u16 y, u16 w, u16 h)
1428{
1429        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1430        struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1431        int r;
1432
1433        dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
1434
1435        mutex_lock(&td->lock);
1436        dsi_bus_lock(dssdev);
1437
1438        r = taal_wake_up(dssdev);
1439        if (r)
1440                goto err;
1441
1442        if (!td->enabled) {
1443                r = 0;
1444                goto err;
1445        }
1446
1447        r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h, true);
1448        if (r)
1449                goto err;
1450
1451        r = taal_set_update_window(td, x, y, w, h);
1452        if (r)
1453                goto err;
1454
1455        if (td->te_enabled && panel_data->use_ext_te) {
1456                td->update_region.x = x;
1457                td->update_region.y = y;
1458                td->update_region.w = w;
1459                td->update_region.h = h;
1460                barrier();
1461                schedule_delayed_work(&td->te_timeout_work,
1462                                msecs_to_jiffies(250));
1463                atomic_set(&td->do_update, 1);
1464        } else {
1465                r = omap_dsi_update(dssdev, td->channel, x, y, w, h,
1466                                taal_framedone_cb, dssdev);
1467                if (r)
1468                        goto err;
1469        }
1470
1471        /* note: no bus_unlock here. unlock is in framedone_cb */
1472        mutex_unlock(&td->lock);
1473        return 0;
1474err:
1475        dsi_bus_unlock(dssdev);
1476        mutex_unlock(&td->lock);
1477        return r;
1478}
1479
1480static int taal_sync(struct omap_dss_device *dssdev)
1481{
1482        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1483
1484        dev_dbg(&dssdev->dev, "sync\n");
1485
1486        mutex_lock(&td->lock);
1487        dsi_bus_lock(dssdev);
1488        dsi_bus_unlock(dssdev);
1489        mutex_unlock(&td->lock);
1490
1491        dev_dbg(&dssdev->dev, "sync done\n");
1492
1493        return 0;
1494}
1495
1496static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1497{
1498        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1499        struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1500        int r;
1501
1502        if (enable)
1503                r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
1504        else
1505                r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
1506
1507        if (!panel_data->use_ext_te)
1508                omapdss_dsi_enable_te(dssdev, enable);
1509
1510        if (td->panel_config->sleep.enable_te)
1511                msleep(td->panel_config->sleep.enable_te);
1512
1513        return r;
1514}
1515
1516static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1517{
1518        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1519        int r;
1520
1521        mutex_lock(&td->lock);
1522
1523        if (td->te_enabled == enable)
1524                goto end;
1525
1526        dsi_bus_lock(dssdev);
1527
1528        if (td->enabled) {
1529                r = taal_wake_up(dssdev);
1530                if (r)
1531                        goto err;
1532
1533                r = _taal_enable_te(dssdev, enable);
1534                if (r)
1535                        goto err;
1536        }
1537
1538        td->te_enabled = enable;
1539
1540        dsi_bus_unlock(dssdev);
1541end:
1542        mutex_unlock(&td->lock);
1543
1544        return 0;
1545err:
1546        dsi_bus_unlock(dssdev);
1547        mutex_unlock(&td->lock);
1548
1549        return r;
1550}
1551
1552static int taal_get_te(struct omap_dss_device *dssdev)
1553{
1554        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1555        int r;
1556
1557        mutex_lock(&td->lock);
1558        r = td->te_enabled;
1559        mutex_unlock(&td->lock);
1560
1561        return r;
1562}
1563
1564static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
1565{
1566        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1567        int r;
1568
1569        dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
1570
1571        mutex_lock(&td->lock);
1572
1573        if (td->rotate == rotate)
1574                goto end;
1575
1576        dsi_bus_lock(dssdev);
1577
1578        if (td->enabled) {
1579                r = taal_wake_up(dssdev);
1580                if (r)
1581                        goto err;
1582
1583                r = taal_set_addr_mode(td, rotate, td->mirror);
1584                if (r)
1585                        goto err;
1586        }
1587
1588        td->rotate = rotate;
1589
1590        dsi_bus_unlock(dssdev);
1591end:
1592        mutex_unlock(&td->lock);
1593        return 0;
1594err:
1595        dsi_bus_unlock(dssdev);
1596        mutex_unlock(&td->lock);
1597        return r;
1598}
1599
1600static u8 taal_get_rotate(struct omap_dss_device *dssdev)
1601{
1602        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1603        int r;
1604
1605        mutex_lock(&td->lock);
1606        r = td->rotate;
1607        mutex_unlock(&td->lock);
1608
1609        return r;
1610}
1611
1612static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1613{
1614        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1615        int r;
1616
1617        dev_dbg(&dssdev->dev, "mirror %d\n", enable);
1618
1619        mutex_lock(&td->lock);
1620
1621        if (td->mirror == enable)
1622                goto end;
1623
1624        dsi_bus_lock(dssdev);
1625        if (td->enabled) {
1626                r = taal_wake_up(dssdev);
1627                if (r)
1628                        goto err;
1629
1630                r = taal_set_addr_mode(td, td->rotate, enable);
1631                if (r)
1632                        goto err;
1633        }
1634
1635        td->mirror = enable;
1636
1637        dsi_bus_unlock(dssdev);
1638end:
1639        mutex_unlock(&td->lock);
1640        return 0;
1641err:
1642        dsi_bus_unlock(dssdev);
1643        mutex_unlock(&td->lock);
1644        return r;
1645}
1646
1647static bool taal_get_mirror(struct omap_dss_device *dssdev)
1648{
1649        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1650        int r;
1651
1652        mutex_lock(&td->lock);
1653        r = td->mirror;
1654        mutex_unlock(&td->lock);
1655
1656        return r;
1657}
1658
1659static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1660{
1661        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1662        u8 id1, id2, id3;
1663        int r;
1664
1665        mutex_lock(&td->lock);
1666
1667        if (!td->enabled) {
1668                r = -ENODEV;
1669                goto err1;
1670        }
1671
1672        dsi_bus_lock(dssdev);
1673
1674        r = taal_wake_up(dssdev);
1675        if (r)
1676                goto err2;
1677
1678        r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
1679        if (r)
1680                goto err2;
1681        r = taal_dcs_read_1(td, DCS_GET_ID2, &id2);
1682        if (r)
1683                goto err2;
1684        r = taal_dcs_read_1(td, DCS_GET_ID3, &id3);
1685        if (r)
1686                goto err2;
1687
1688        dsi_bus_unlock(dssdev);
1689        mutex_unlock(&td->lock);
1690        return 0;
1691err2:
1692        dsi_bus_unlock(dssdev);
1693err1:
1694        mutex_unlock(&td->lock);
1695        return r;
1696}
1697
1698static int taal_memory_read(struct omap_dss_device *dssdev,
1699                void *buf, size_t size,
1700                u16 x, u16 y, u16 w, u16 h)
1701{
1702        int r;
1703        int first = 1;
1704        int plen;
1705        unsigned buf_used = 0;
1706        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1707
1708        if (size < w * h * 3)
1709                return -ENOMEM;
1710
1711        mutex_lock(&td->lock);
1712
1713        if (!td->enabled) {
1714                r = -ENODEV;
1715                goto err1;
1716        }
1717
1718        size = min(w * h * 3,
1719                        dssdev->panel.timings.x_res *
1720                        dssdev->panel.timings.y_res * 3);
1721
1722        dsi_bus_lock(dssdev);
1723
1724        r = taal_wake_up(dssdev);
1725        if (r)
1726                goto err2;
1727
1728        /* plen 1 or 2 goes into short packet. until checksum error is fixed,
1729         * use short packets. plen 32 works, but bigger packets seem to cause
1730         * an error. */
1731        if (size % 2)
1732                plen = 1;
1733        else
1734                plen = 2;
1735
1736        taal_set_update_window(td, x, y, w, h);
1737
1738        r = dsi_vc_set_max_rx_packet_size(dssdev, td->channel, plen);
1739        if (r)
1740                goto err2;
1741
1742        while (buf_used < size) {
1743                u8 dcs_cmd = first ? 0x2e : 0x3e;
1744                first = 0;
1745
1746                r = dsi_vc_dcs_read(dssdev, td->channel, dcs_cmd,
1747                                buf + buf_used, size - buf_used);
1748
1749                if (r < 0) {
1750                        dev_err(&dssdev->dev, "read error\n");
1751                        goto err3;
1752                }
1753
1754                buf_used += r;
1755
1756                if (r < plen) {
1757                        dev_err(&dssdev->dev, "short read\n");
1758                        break;
1759                }
1760
1761                if (signal_pending(current)) {
1762                        dev_err(&dssdev->dev, "signal pending, "
1763                                        "aborting memory read\n");
1764                        r = -ERESTARTSYS;
1765                        goto err3;
1766                }
1767        }
1768
1769        r = buf_used;
1770
1771err3:
1772        dsi_vc_set_max_rx_packet_size(dssdev, td->channel, 1);
1773err2:
1774        dsi_bus_unlock(dssdev);
1775err1:
1776        mutex_unlock(&td->lock);
1777        return r;
1778}
1779
1780static void taal_ulps_work(struct work_struct *work)
1781{
1782        struct taal_data *td = container_of(work, struct taal_data,
1783                        ulps_work.work);
1784        struct omap_dss_device *dssdev = td->dssdev;
1785
1786        mutex_lock(&td->lock);
1787
1788        if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !td->enabled) {
1789                mutex_unlock(&td->lock);
1790                return;
1791        }
1792
1793        dsi_bus_lock(dssdev);
1794
1795        taal_enter_ulps(dssdev);
1796
1797        dsi_bus_unlock(dssdev);
1798        mutex_unlock(&td->lock);
1799}
1800
1801static void taal_esd_work(struct work_struct *work)
1802{
1803        struct taal_data *td = container_of(work, struct taal_data,
1804                        esd_work.work);
1805        struct omap_dss_device *dssdev = td->dssdev;
1806        struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1807        u8 state1, state2;
1808        int r;
1809
1810        mutex_lock(&td->lock);
1811
1812        if (!td->enabled) {
1813                mutex_unlock(&td->lock);
1814                return;
1815        }
1816
1817        dsi_bus_lock(dssdev);
1818
1819        r = taal_wake_up(dssdev);
1820        if (r) {
1821                dev_err(&dssdev->dev, "failed to exit ULPS\n");
1822                goto err;
1823        }
1824
1825        r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1);
1826        if (r) {
1827                dev_err(&dssdev->dev, "failed to read Taal status\n");
1828                goto err;
1829        }
1830
1831        /* Run self diagnostics */
1832        r = taal_sleep_out(td);
1833        if (r) {
1834                dev_err(&dssdev->dev, "failed to run Taal self-diagnostics\n");
1835                goto err;
1836        }
1837
1838        r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2);
1839        if (r) {
1840                dev_err(&dssdev->dev, "failed to read Taal status\n");
1841                goto err;
1842        }
1843
1844        /* Each sleep out command will trigger a self diagnostic and flip
1845         * Bit6 if the test passes.
1846         */
1847        if (!((state1 ^ state2) & (1 << 6))) {
1848                dev_err(&dssdev->dev, "LCD self diagnostics failed\n");
1849                goto err;
1850        }
1851        /* Self-diagnostics result is also shown on TE GPIO line. We need
1852         * to re-enable TE after self diagnostics */
1853        if (td->te_enabled && panel_data->use_ext_te) {
1854                r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
1855                if (r)
1856                        goto err;
1857        }
1858
1859        dsi_bus_unlock(dssdev);
1860
1861        taal_queue_esd_work(dssdev);
1862
1863        mutex_unlock(&td->lock);
1864        return;
1865err:
1866        dev_err(&dssdev->dev, "performing LCD reset\n");
1867
1868        taal_panel_reset(dssdev);
1869
1870        dsi_bus_unlock(dssdev);
1871
1872        taal_queue_esd_work(dssdev);
1873
1874        mutex_unlock(&td->lock);
1875}
1876
1877static struct omap_dss_driver taal_driver = {
1878        .probe          = taal_probe,
1879        .remove         = __exit_p(taal_remove),
1880
1881        .enable         = taal_enable,
1882        .disable        = taal_disable,
1883        .suspend        = taal_suspend,
1884        .resume         = taal_resume,
1885
1886        .update         = taal_update,
1887        .sync           = taal_sync,
1888
1889        .get_resolution = taal_get_resolution,
1890        .get_recommended_bpp = omapdss_default_get_recommended_bpp,
1891
1892        .enable_te      = taal_enable_te,
1893        .get_te         = taal_get_te,
1894
1895        .set_rotate     = taal_rotate,
1896        .get_rotate     = taal_get_rotate,
1897        .set_mirror     = taal_mirror,
1898        .get_mirror     = taal_get_mirror,
1899        .run_test       = taal_run_test,
1900        .memory_read    = taal_memory_read,
1901
1902        .get_timings    = taal_get_timings,
1903
1904        .driver         = {
1905                .name   = "taal",
1906                .owner  = THIS_MODULE,
1907        },
1908};
1909
1910static int __init taal_init(void)
1911{
1912        omap_dss_register_driver(&taal_driver);
1913
1914        return 0;
1915}
1916
1917static void __exit taal_exit(void)
1918{
1919        omap_dss_unregister_driver(&taal_driver);
1920}
1921
1922module_init(taal_init);
1923module_exit(taal_exit);
1924
1925MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
1926MODULE_DESCRIPTION("Taal Driver");
1927MODULE_LICENSE("GPL");
1928