root/drivers/video/fbdev/omap2/omapfb/displays/panel-sony-acx565akm.c

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

DEFINITIONS

This source file includes following definitions.
  1. acx565akm_transfer
  2. acx565akm_cmd
  3. acx565akm_write
  4. acx565akm_read
  5. hw_guard_start
  6. hw_guard_wait
  7. set_sleep_mode
  8. set_display_state
  9. panel_enabled
  10. panel_detect
  11. enable_backlight_ctrl
  12. set_cabc_mode
  13. get_cabc_mode
  14. get_hw_cabc_mode
  15. acx565akm_set_brightness
  16. acx565akm_get_actual_brightness
  17. acx565akm_bl_update_status
  18. acx565akm_bl_get_intensity
  19. acx565akm_bl_update_status_locked
  20. acx565akm_bl_get_intensity_locked
  21. show_cabc_mode
  22. store_cabc_mode
  23. show_cabc_available_modes
  24. acx565akm_connect
  25. acx565akm_disconnect
  26. acx565akm_panel_power_on
  27. acx565akm_panel_power_off
  28. acx565akm_enable
  29. acx565akm_disable
  30. acx565akm_set_timings
  31. acx565akm_get_timings
  32. acx565akm_check_timings
  33. acx565akm_probe_pdata
  34. acx565akm_probe_of
  35. acx565akm_probe
  36. acx565akm_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Sony ACX565AKM LCD Panel driver
   4  *
   5  * Copyright (C) 2010 Nokia Corporation
   6  *
   7  * Original Driver Author: Imre Deak <imre.deak@nokia.com>
   8  * Based on panel-generic.c by Tomi Valkeinen <tomi.valkeinen@nokia.com>
   9  * Adapted to new DSS2 framework: Roger Quadros <roger.quadros@nokia.com>
  10  */
  11 
  12 #include <linux/kernel.h>
  13 #include <linux/module.h>
  14 #include <linux/platform_device.h>
  15 #include <linux/delay.h>
  16 #include <linux/spi/spi.h>
  17 #include <linux/jiffies.h>
  18 #include <linux/sched.h>
  19 #include <linux/backlight.h>
  20 #include <linux/fb.h>
  21 #include <linux/gpio.h>
  22 #include <linux/of.h>
  23 #include <linux/of_gpio.h>
  24 
  25 #include <video/omapfb_dss.h>
  26 #include <video/omap-panel-data.h>
  27 
  28 #define MIPID_CMD_READ_DISP_ID          0x04
  29 #define MIPID_CMD_READ_RED              0x06
  30 #define MIPID_CMD_READ_GREEN            0x07
  31 #define MIPID_CMD_READ_BLUE             0x08
  32 #define MIPID_CMD_READ_DISP_STATUS      0x09
  33 #define MIPID_CMD_RDDSDR                0x0F
  34 #define MIPID_CMD_SLEEP_IN              0x10
  35 #define MIPID_CMD_SLEEP_OUT             0x11
  36 #define MIPID_CMD_DISP_OFF              0x28
  37 #define MIPID_CMD_DISP_ON               0x29
  38 #define MIPID_CMD_WRITE_DISP_BRIGHTNESS 0x51
  39 #define MIPID_CMD_READ_DISP_BRIGHTNESS  0x52
  40 #define MIPID_CMD_WRITE_CTRL_DISP       0x53
  41 
  42 #define CTRL_DISP_BRIGHTNESS_CTRL_ON    (1 << 5)
  43 #define CTRL_DISP_AMBIENT_LIGHT_CTRL_ON (1 << 4)
  44 #define CTRL_DISP_BACKLIGHT_ON          (1 << 2)
  45 #define CTRL_DISP_AUTO_BRIGHTNESS_ON    (1 << 1)
  46 
  47 #define MIPID_CMD_READ_CTRL_DISP        0x54
  48 #define MIPID_CMD_WRITE_CABC            0x55
  49 #define MIPID_CMD_READ_CABC             0x56
  50 
  51 #define MIPID_VER_LPH8923               3
  52 #define MIPID_VER_LS041Y3               4
  53 #define MIPID_VER_L4F00311              8
  54 #define MIPID_VER_ACX565AKM             9
  55 
  56 struct panel_drv_data {
  57         struct omap_dss_device  dssdev;
  58         struct omap_dss_device *in;
  59 
  60         int reset_gpio;
  61         int datapairs;
  62 
  63         struct omap_video_timings videomode;
  64 
  65         char            *name;
  66         int             enabled;
  67         int             model;
  68         int             revision;
  69         u8              display_id[3];
  70         unsigned        has_bc:1;
  71         unsigned        has_cabc:1;
  72         unsigned        cabc_mode;
  73         unsigned long   hw_guard_end;           /* next value of jiffies
  74                                                    when we can issue the
  75                                                    next sleep in/out command */
  76         unsigned long   hw_guard_wait;          /* max guard time in jiffies */
  77 
  78         struct spi_device       *spi;
  79         struct mutex            mutex;
  80 
  81         struct backlight_device *bl_dev;
  82 };
  83 
  84 static const struct omap_video_timings acx565akm_panel_timings = {
  85         .x_res          = 800,
  86         .y_res          = 480,
  87         .pixelclock     = 24000000,
  88         .hfp            = 28,
  89         .hsw            = 4,
  90         .hbp            = 24,
  91         .vfp            = 3,
  92         .vsw            = 3,
  93         .vbp            = 4,
  94 
  95         .vsync_level    = OMAPDSS_SIG_ACTIVE_LOW,
  96         .hsync_level    = OMAPDSS_SIG_ACTIVE_LOW,
  97 
  98         .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
  99         .de_level       = OMAPDSS_SIG_ACTIVE_HIGH,
 100         .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
 101 };
 102 
 103 #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
 104 
 105 static void acx565akm_transfer(struct panel_drv_data *ddata, int cmd,
 106                               const u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 107 {
 108         struct spi_message      m;
 109         struct spi_transfer     *x, xfer[5];
 110         int                     r;
 111 
 112         BUG_ON(ddata->spi == NULL);
 113 
 114         spi_message_init(&m);
 115 
 116         memset(xfer, 0, sizeof(xfer));
 117         x = &xfer[0];
 118 
 119         cmd &=  0xff;
 120         x->tx_buf = &cmd;
 121         x->bits_per_word = 9;
 122         x->len = 2;
 123 
 124         if (rlen > 1 && wlen == 0) {
 125                 /*
 126                  * Between the command and the response data there is a
 127                  * dummy clock cycle. Add an extra bit after the command
 128                  * word to account for this.
 129                  */
 130                 x->bits_per_word = 10;
 131                 cmd <<= 1;
 132         }
 133         spi_message_add_tail(x, &m);
 134 
 135         if (wlen) {
 136                 x++;
 137                 x->tx_buf = wbuf;
 138                 x->len = wlen;
 139                 x->bits_per_word = 9;
 140                 spi_message_add_tail(x, &m);
 141         }
 142 
 143         if (rlen) {
 144                 x++;
 145                 x->rx_buf       = rbuf;
 146                 x->len          = rlen;
 147                 spi_message_add_tail(x, &m);
 148         }
 149 
 150         r = spi_sync(ddata->spi, &m);
 151         if (r < 0)
 152                 dev_dbg(&ddata->spi->dev, "spi_sync %d\n", r);
 153 }
 154 
 155 static inline void acx565akm_cmd(struct panel_drv_data *ddata, int cmd)
 156 {
 157         acx565akm_transfer(ddata, cmd, NULL, 0, NULL, 0);
 158 }
 159 
 160 static inline void acx565akm_write(struct panel_drv_data *ddata,
 161                                int reg, const u8 *buf, int len)
 162 {
 163         acx565akm_transfer(ddata, reg, buf, len, NULL, 0);
 164 }
 165 
 166 static inline void acx565akm_read(struct panel_drv_data *ddata,
 167                               int reg, u8 *buf, int len)
 168 {
 169         acx565akm_transfer(ddata, reg, NULL, 0, buf, len);
 170 }
 171 
 172 static void hw_guard_start(struct panel_drv_data *ddata, int guard_msec)
 173 {
 174         ddata->hw_guard_wait = msecs_to_jiffies(guard_msec);
 175         ddata->hw_guard_end = jiffies + ddata->hw_guard_wait;
 176 }
 177 
 178 static void hw_guard_wait(struct panel_drv_data *ddata)
 179 {
 180         unsigned long wait = ddata->hw_guard_end - jiffies;
 181 
 182         if ((long)wait > 0 && wait <= ddata->hw_guard_wait) {
 183                 set_current_state(TASK_UNINTERRUPTIBLE);
 184                 schedule_timeout(wait);
 185         }
 186 }
 187 
 188 static void set_sleep_mode(struct panel_drv_data *ddata, int on)
 189 {
 190         int cmd;
 191 
 192         if (on)
 193                 cmd = MIPID_CMD_SLEEP_IN;
 194         else
 195                 cmd = MIPID_CMD_SLEEP_OUT;
 196         /*
 197          * We have to keep 120msec between sleep in/out commands.
 198          * (8.2.15, 8.2.16).
 199          */
 200         hw_guard_wait(ddata);
 201         acx565akm_cmd(ddata, cmd);
 202         hw_guard_start(ddata, 120);
 203 }
 204 
 205 static void set_display_state(struct panel_drv_data *ddata, int enabled)
 206 {
 207         int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF;
 208 
 209         acx565akm_cmd(ddata, cmd);
 210 }
 211 
 212 static int panel_enabled(struct panel_drv_data *ddata)
 213 {
 214         u32 disp_status;
 215         int enabled;
 216 
 217         acx565akm_read(ddata, MIPID_CMD_READ_DISP_STATUS,
 218                         (u8 *)&disp_status, 4);
 219         disp_status = __be32_to_cpu(disp_status);
 220         enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10));
 221         dev_dbg(&ddata->spi->dev,
 222                 "LCD panel %senabled by bootloader (status 0x%04x)\n",
 223                 enabled ? "" : "not ", disp_status);
 224         return enabled;
 225 }
 226 
 227 static int panel_detect(struct panel_drv_data *ddata)
 228 {
 229         acx565akm_read(ddata, MIPID_CMD_READ_DISP_ID, ddata->display_id, 3);
 230         dev_dbg(&ddata->spi->dev, "MIPI display ID: %02x%02x%02x\n",
 231                 ddata->display_id[0],
 232                 ddata->display_id[1],
 233                 ddata->display_id[2]);
 234 
 235         switch (ddata->display_id[0]) {
 236         case 0x10:
 237                 ddata->model = MIPID_VER_ACX565AKM;
 238                 ddata->name = "acx565akm";
 239                 ddata->has_bc = 1;
 240                 ddata->has_cabc = 1;
 241                 break;
 242         case 0x29:
 243                 ddata->model = MIPID_VER_L4F00311;
 244                 ddata->name = "l4f00311";
 245                 break;
 246         case 0x45:
 247                 ddata->model = MIPID_VER_LPH8923;
 248                 ddata->name = "lph8923";
 249                 break;
 250         case 0x83:
 251                 ddata->model = MIPID_VER_LS041Y3;
 252                 ddata->name = "ls041y3";
 253                 break;
 254         default:
 255                 ddata->name = "unknown";
 256                 dev_err(&ddata->spi->dev, "invalid display ID\n");
 257                 return -ENODEV;
 258         }
 259 
 260         ddata->revision = ddata->display_id[1];
 261 
 262         dev_info(&ddata->spi->dev, "omapfb: %s rev %02x LCD detected\n",
 263                         ddata->name, ddata->revision);
 264 
 265         return 0;
 266 }
 267 
 268 /*----------------------Backlight Control-------------------------*/
 269 
 270 static void enable_backlight_ctrl(struct panel_drv_data *ddata, int enable)
 271 {
 272         u16 ctrl;
 273 
 274         acx565akm_read(ddata, MIPID_CMD_READ_CTRL_DISP, (u8 *)&ctrl, 1);
 275         if (enable) {
 276                 ctrl |= CTRL_DISP_BRIGHTNESS_CTRL_ON |
 277                         CTRL_DISP_BACKLIGHT_ON;
 278         } else {
 279                 ctrl &= ~(CTRL_DISP_BRIGHTNESS_CTRL_ON |
 280                           CTRL_DISP_BACKLIGHT_ON);
 281         }
 282 
 283         ctrl |= 1 << 8;
 284         acx565akm_write(ddata, MIPID_CMD_WRITE_CTRL_DISP, (u8 *)&ctrl, 2);
 285 }
 286 
 287 static void set_cabc_mode(struct panel_drv_data *ddata, unsigned mode)
 288 {
 289         u16 cabc_ctrl;
 290 
 291         ddata->cabc_mode = mode;
 292         if (!ddata->enabled)
 293                 return;
 294         cabc_ctrl = 0;
 295         acx565akm_read(ddata, MIPID_CMD_READ_CABC, (u8 *)&cabc_ctrl, 1);
 296         cabc_ctrl &= ~3;
 297         cabc_ctrl |= (1 << 8) | (mode & 3);
 298         acx565akm_write(ddata, MIPID_CMD_WRITE_CABC, (u8 *)&cabc_ctrl, 2);
 299 }
 300 
 301 static unsigned get_cabc_mode(struct panel_drv_data *ddata)
 302 {
 303         return ddata->cabc_mode;
 304 }
 305 
 306 static unsigned get_hw_cabc_mode(struct panel_drv_data *ddata)
 307 {
 308         u8 cabc_ctrl;
 309 
 310         acx565akm_read(ddata, MIPID_CMD_READ_CABC, &cabc_ctrl, 1);
 311         return cabc_ctrl & 3;
 312 }
 313 
 314 static void acx565akm_set_brightness(struct panel_drv_data *ddata, int level)
 315 {
 316         int bv;
 317 
 318         bv = level | (1 << 8);
 319         acx565akm_write(ddata, MIPID_CMD_WRITE_DISP_BRIGHTNESS, (u8 *)&bv, 2);
 320 
 321         if (level)
 322                 enable_backlight_ctrl(ddata, 1);
 323         else
 324                 enable_backlight_ctrl(ddata, 0);
 325 }
 326 
 327 static int acx565akm_get_actual_brightness(struct panel_drv_data *ddata)
 328 {
 329         u8 bv;
 330 
 331         acx565akm_read(ddata, MIPID_CMD_READ_DISP_BRIGHTNESS, &bv, 1);
 332 
 333         return bv;
 334 }
 335 
 336 
 337 static int acx565akm_bl_update_status(struct backlight_device *dev)
 338 {
 339         struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
 340         int level;
 341 
 342         dev_dbg(&ddata->spi->dev, "%s\n", __func__);
 343 
 344         if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
 345                         dev->props.power == FB_BLANK_UNBLANK)
 346                 level = dev->props.brightness;
 347         else
 348                 level = 0;
 349 
 350         if (ddata->has_bc)
 351                 acx565akm_set_brightness(ddata, level);
 352         else
 353                 return -ENODEV;
 354 
 355         return 0;
 356 }
 357 
 358 static int acx565akm_bl_get_intensity(struct backlight_device *dev)
 359 {
 360         struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
 361 
 362         dev_dbg(&dev->dev, "%s\n", __func__);
 363 
 364         if (!ddata->has_bc)
 365                 return -ENODEV;
 366 
 367         if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
 368                         dev->props.power == FB_BLANK_UNBLANK) {
 369                 if (ddata->has_bc)
 370                         return acx565akm_get_actual_brightness(ddata);
 371                 else
 372                         return dev->props.brightness;
 373         }
 374 
 375         return 0;
 376 }
 377 
 378 static int acx565akm_bl_update_status_locked(struct backlight_device *dev)
 379 {
 380         struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
 381         int r;
 382 
 383         mutex_lock(&ddata->mutex);
 384         r = acx565akm_bl_update_status(dev);
 385         mutex_unlock(&ddata->mutex);
 386 
 387         return r;
 388 }
 389 
 390 static int acx565akm_bl_get_intensity_locked(struct backlight_device *dev)
 391 {
 392         struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
 393         int r;
 394 
 395         mutex_lock(&ddata->mutex);
 396         r = acx565akm_bl_get_intensity(dev);
 397         mutex_unlock(&ddata->mutex);
 398 
 399         return r;
 400 }
 401 
 402 static const struct backlight_ops acx565akm_bl_ops = {
 403         .get_brightness = acx565akm_bl_get_intensity_locked,
 404         .update_status  = acx565akm_bl_update_status_locked,
 405 };
 406 
 407 /*--------------------Auto Brightness control via Sysfs---------------------*/
 408 
 409 static const char * const cabc_modes[] = {
 410         "off",          /* always used when CABC is not supported */
 411         "ui",
 412         "still-image",
 413         "moving-image",
 414 };
 415 
 416 static ssize_t show_cabc_mode(struct device *dev,
 417                 struct device_attribute *attr,
 418                 char *buf)
 419 {
 420         struct panel_drv_data *ddata = dev_get_drvdata(dev);
 421         const char *mode_str;
 422         int mode;
 423         int len;
 424 
 425         if (!ddata->has_cabc)
 426                 mode = 0;
 427         else
 428                 mode = get_cabc_mode(ddata);
 429         mode_str = "unknown";
 430         if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes))
 431                 mode_str = cabc_modes[mode];
 432         len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str);
 433 
 434         return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1;
 435 }
 436 
 437 static ssize_t store_cabc_mode(struct device *dev,
 438                 struct device_attribute *attr,
 439                 const char *buf, size_t count)
 440 {
 441         struct panel_drv_data *ddata = dev_get_drvdata(dev);
 442         int i;
 443 
 444         for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
 445                 const char *mode_str = cabc_modes[i];
 446                 int cmp_len = strlen(mode_str);
 447 
 448                 if (count > 0 && buf[count - 1] == '\n')
 449                         count--;
 450                 if (count != cmp_len)
 451                         continue;
 452 
 453                 if (strncmp(buf, mode_str, cmp_len) == 0)
 454                         break;
 455         }
 456 
 457         if (i == ARRAY_SIZE(cabc_modes))
 458                 return -EINVAL;
 459 
 460         if (!ddata->has_cabc && i != 0)
 461                 return -EINVAL;
 462 
 463         mutex_lock(&ddata->mutex);
 464         set_cabc_mode(ddata, i);
 465         mutex_unlock(&ddata->mutex);
 466 
 467         return count;
 468 }
 469 
 470 static ssize_t show_cabc_available_modes(struct device *dev,
 471                 struct device_attribute *attr,
 472                 char *buf)
 473 {
 474         struct panel_drv_data *ddata = dev_get_drvdata(dev);
 475         int len;
 476         int i;
 477 
 478         if (!ddata->has_cabc)
 479                 return snprintf(buf, PAGE_SIZE, "%s\n", cabc_modes[0]);
 480 
 481         for (i = 0, len = 0;
 482              len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++)
 483                 len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s",
 484                         i ? " " : "", cabc_modes[i],
 485                         i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : "");
 486 
 487         return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
 488 }
 489 
 490 static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR,
 491                 show_cabc_mode, store_cabc_mode);
 492 static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
 493                 show_cabc_available_modes, NULL);
 494 
 495 static struct attribute *bldev_attrs[] = {
 496         &dev_attr_cabc_mode.attr,
 497         &dev_attr_cabc_available_modes.attr,
 498         NULL,
 499 };
 500 
 501 static const struct attribute_group bldev_attr_group = {
 502         .attrs = bldev_attrs,
 503 };
 504 
 505 static int acx565akm_connect(struct omap_dss_device *dssdev)
 506 {
 507         struct panel_drv_data *ddata = to_panel_data(dssdev);
 508         struct omap_dss_device *in = ddata->in;
 509         int r;
 510 
 511         if (omapdss_device_is_connected(dssdev))
 512                 return 0;
 513 
 514         r = in->ops.sdi->connect(in, dssdev);
 515         if (r)
 516                 return r;
 517 
 518         return 0;
 519 }
 520 
 521 static void acx565akm_disconnect(struct omap_dss_device *dssdev)
 522 {
 523         struct panel_drv_data *ddata = to_panel_data(dssdev);
 524         struct omap_dss_device *in = ddata->in;
 525 
 526         if (!omapdss_device_is_connected(dssdev))
 527                 return;
 528 
 529         in->ops.sdi->disconnect(in, dssdev);
 530 }
 531 
 532 static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
 533 {
 534         struct panel_drv_data *ddata = to_panel_data(dssdev);
 535         struct omap_dss_device *in = ddata->in;
 536         int r;
 537 
 538         dev_dbg(&ddata->spi->dev, "%s\n", __func__);
 539 
 540         in->ops.sdi->set_timings(in, &ddata->videomode);
 541 
 542         if (ddata->datapairs > 0)
 543                 in->ops.sdi->set_datapairs(in, ddata->datapairs);
 544 
 545         r = in->ops.sdi->enable(in);
 546         if (r) {
 547                 pr_err("%s sdi enable failed\n", __func__);
 548                 return r;
 549         }
 550 
 551         /*FIXME tweak me */
 552         msleep(50);
 553 
 554         if (gpio_is_valid(ddata->reset_gpio))
 555                 gpio_set_value(ddata->reset_gpio, 1);
 556 
 557         if (ddata->enabled) {
 558                 dev_dbg(&ddata->spi->dev, "panel already enabled\n");
 559                 return 0;
 560         }
 561 
 562         /*
 563          * We have to meet all the following delay requirements:
 564          * 1. tRW: reset pulse width 10usec (7.12.1)
 565          * 2. tRT: reset cancel time 5msec (7.12.1)
 566          * 3. Providing PCLK,HS,VS signals for 2 frames = ~50msec worst
 567          *    case (7.6.2)
 568          * 4. 120msec before the sleep out command (7.12.1)
 569          */
 570         msleep(120);
 571 
 572         set_sleep_mode(ddata, 0);
 573         ddata->enabled = 1;
 574 
 575         /* 5msec between sleep out and the next command. (8.2.16) */
 576         usleep_range(5000, 10000);
 577         set_display_state(ddata, 1);
 578         set_cabc_mode(ddata, ddata->cabc_mode);
 579 
 580         return acx565akm_bl_update_status(ddata->bl_dev);
 581 }
 582 
 583 static void acx565akm_panel_power_off(struct omap_dss_device *dssdev)
 584 {
 585         struct panel_drv_data *ddata = to_panel_data(dssdev);
 586         struct omap_dss_device *in = ddata->in;
 587 
 588         dev_dbg(dssdev->dev, "%s\n", __func__);
 589 
 590         if (!ddata->enabled)
 591                 return;
 592 
 593         set_display_state(ddata, 0);
 594         set_sleep_mode(ddata, 1);
 595         ddata->enabled = 0;
 596         /*
 597          * We have to provide PCLK,HS,VS signals for 2 frames (worst case
 598          * ~50msec) after sending the sleep in command and asserting the
 599          * reset signal. We probably could assert the reset w/o the delay
 600          * but we still delay to avoid possible artifacts. (7.6.1)
 601          */
 602         msleep(50);
 603 
 604         if (gpio_is_valid(ddata->reset_gpio))
 605                 gpio_set_value(ddata->reset_gpio, 0);
 606 
 607         /* FIXME need to tweak this delay */
 608         msleep(100);
 609 
 610         in->ops.sdi->disable(in);
 611 }
 612 
 613 static int acx565akm_enable(struct omap_dss_device *dssdev)
 614 {
 615         struct panel_drv_data *ddata = to_panel_data(dssdev);
 616         int r;
 617 
 618         dev_dbg(dssdev->dev, "%s\n", __func__);
 619 
 620         if (!omapdss_device_is_connected(dssdev))
 621                 return -ENODEV;
 622 
 623         if (omapdss_device_is_enabled(dssdev))
 624                 return 0;
 625 
 626         mutex_lock(&ddata->mutex);
 627         r = acx565akm_panel_power_on(dssdev);
 628         mutex_unlock(&ddata->mutex);
 629         if (r)
 630                 return r;
 631 
 632         dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
 633 
 634         return 0;
 635 }
 636 
 637 static void acx565akm_disable(struct omap_dss_device *dssdev)
 638 {
 639         struct panel_drv_data *ddata = to_panel_data(dssdev);
 640 
 641         dev_dbg(dssdev->dev, "%s\n", __func__);
 642 
 643         if (!omapdss_device_is_enabled(dssdev))
 644                 return;
 645 
 646         mutex_lock(&ddata->mutex);
 647         acx565akm_panel_power_off(dssdev);
 648         mutex_unlock(&ddata->mutex);
 649 
 650         dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 651 }
 652 
 653 static void acx565akm_set_timings(struct omap_dss_device *dssdev,
 654                 struct omap_video_timings *timings)
 655 {
 656         struct panel_drv_data *ddata = to_panel_data(dssdev);
 657         struct omap_dss_device *in = ddata->in;
 658 
 659         ddata->videomode = *timings;
 660         dssdev->panel.timings = *timings;
 661 
 662         in->ops.sdi->set_timings(in, timings);
 663 }
 664 
 665 static void acx565akm_get_timings(struct omap_dss_device *dssdev,
 666                 struct omap_video_timings *timings)
 667 {
 668         struct panel_drv_data *ddata = to_panel_data(dssdev);
 669 
 670         *timings = ddata->videomode;
 671 }
 672 
 673 static int acx565akm_check_timings(struct omap_dss_device *dssdev,
 674                 struct omap_video_timings *timings)
 675 {
 676         struct panel_drv_data *ddata = to_panel_data(dssdev);
 677         struct omap_dss_device *in = ddata->in;
 678 
 679         return in->ops.sdi->check_timings(in, timings);
 680 }
 681 
 682 static struct omap_dss_driver acx565akm_ops = {
 683         .connect        = acx565akm_connect,
 684         .disconnect     = acx565akm_disconnect,
 685 
 686         .enable         = acx565akm_enable,
 687         .disable        = acx565akm_disable,
 688 
 689         .set_timings    = acx565akm_set_timings,
 690         .get_timings    = acx565akm_get_timings,
 691         .check_timings  = acx565akm_check_timings,
 692 
 693         .get_resolution = omapdss_default_get_resolution,
 694 };
 695 
 696 static int acx565akm_probe_pdata(struct spi_device *spi)
 697 {
 698         const struct panel_acx565akm_platform_data *pdata;
 699         struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
 700         struct omap_dss_device *dssdev, *in;
 701 
 702         pdata = dev_get_platdata(&spi->dev);
 703 
 704         ddata->reset_gpio = pdata->reset_gpio;
 705 
 706         in = omap_dss_find_output(pdata->source);
 707         if (in == NULL) {
 708                 dev_err(&spi->dev, "failed to find video source '%s'\n",
 709                                 pdata->source);
 710                 return -EPROBE_DEFER;
 711         }
 712         ddata->in = in;
 713 
 714         ddata->datapairs = pdata->datapairs;
 715 
 716         dssdev = &ddata->dssdev;
 717         dssdev->name = pdata->name;
 718 
 719         return 0;
 720 }
 721 
 722 static int acx565akm_probe_of(struct spi_device *spi)
 723 {
 724         struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
 725         struct device_node *np = spi->dev.of_node;
 726 
 727         ddata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
 728 
 729         ddata->in = omapdss_of_find_source_for_first_ep(np);
 730         if (IS_ERR(ddata->in)) {
 731                 dev_err(&spi->dev, "failed to find video source\n");
 732                 return PTR_ERR(ddata->in);
 733         }
 734 
 735         return 0;
 736 }
 737 
 738 static int acx565akm_probe(struct spi_device *spi)
 739 {
 740         struct panel_drv_data *ddata;
 741         struct omap_dss_device *dssdev;
 742         struct backlight_device *bldev;
 743         int max_brightness, brightness;
 744         struct backlight_properties props;
 745         int r;
 746 
 747         dev_dbg(&spi->dev, "%s\n", __func__);
 748 
 749         spi->mode = SPI_MODE_3;
 750 
 751         ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
 752         if (ddata == NULL)
 753                 return -ENOMEM;
 754 
 755         dev_set_drvdata(&spi->dev, ddata);
 756 
 757         ddata->spi = spi;
 758 
 759         mutex_init(&ddata->mutex);
 760 
 761         if (dev_get_platdata(&spi->dev)) {
 762                 r = acx565akm_probe_pdata(spi);
 763                 if (r)
 764                         return r;
 765         } else if (spi->dev.of_node) {
 766                 r = acx565akm_probe_of(spi);
 767                 if (r)
 768                         return r;
 769         } else {
 770                 dev_err(&spi->dev, "platform data missing!\n");
 771                 return -ENODEV;
 772         }
 773 
 774         if (gpio_is_valid(ddata->reset_gpio)) {
 775                 r = devm_gpio_request_one(&spi->dev, ddata->reset_gpio,
 776                                 GPIOF_OUT_INIT_LOW, "lcd reset");
 777                 if (r)
 778                         goto err_gpio;
 779         }
 780 
 781         if (gpio_is_valid(ddata->reset_gpio))
 782                 gpio_set_value(ddata->reset_gpio, 1);
 783 
 784         /*
 785          * After reset we have to wait 5 msec before the first
 786          * command can be sent.
 787          */
 788         usleep_range(5000, 10000);
 789 
 790         ddata->enabled = panel_enabled(ddata);
 791 
 792         r = panel_detect(ddata);
 793 
 794         if (!ddata->enabled && gpio_is_valid(ddata->reset_gpio))
 795                 gpio_set_value(ddata->reset_gpio, 0);
 796 
 797         if (r) {
 798                 dev_err(&spi->dev, "%s panel detect error\n", __func__);
 799                 goto err_detect;
 800         }
 801 
 802         memset(&props, 0, sizeof(props));
 803         props.fb_blank = FB_BLANK_UNBLANK;
 804         props.power = FB_BLANK_UNBLANK;
 805         props.type = BACKLIGHT_RAW;
 806 
 807         bldev = backlight_device_register("acx565akm", &ddata->spi->dev,
 808                         ddata, &acx565akm_bl_ops, &props);
 809         if (IS_ERR(bldev)) {
 810                 r = PTR_ERR(bldev);
 811                 goto err_reg_bl;
 812         }
 813         ddata->bl_dev = bldev;
 814         if (ddata->has_cabc) {
 815                 r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group);
 816                 if (r) {
 817                         dev_err(&bldev->dev,
 818                                 "%s failed to create sysfs files\n", __func__);
 819                         goto err_sysfs;
 820                 }
 821                 ddata->cabc_mode = get_hw_cabc_mode(ddata);
 822         }
 823 
 824         max_brightness = 255;
 825 
 826         if (ddata->has_bc)
 827                 brightness = acx565akm_get_actual_brightness(ddata);
 828         else
 829                 brightness = 0;
 830 
 831         bldev->props.max_brightness = max_brightness;
 832         bldev->props.brightness = brightness;
 833 
 834         acx565akm_bl_update_status(bldev);
 835 
 836 
 837         ddata->videomode = acx565akm_panel_timings;
 838 
 839         dssdev = &ddata->dssdev;
 840         dssdev->dev = &spi->dev;
 841         dssdev->driver = &acx565akm_ops;
 842         dssdev->type = OMAP_DISPLAY_TYPE_SDI;
 843         dssdev->owner = THIS_MODULE;
 844         dssdev->panel.timings = ddata->videomode;
 845 
 846         r = omapdss_register_display(dssdev);
 847         if (r) {
 848                 dev_err(&spi->dev, "Failed to register panel\n");
 849                 goto err_reg;
 850         }
 851 
 852         return 0;
 853 
 854 err_reg:
 855         sysfs_remove_group(&bldev->dev.kobj, &bldev_attr_group);
 856 err_sysfs:
 857         backlight_device_unregister(bldev);
 858 err_reg_bl:
 859 err_detect:
 860 err_gpio:
 861         omap_dss_put_device(ddata->in);
 862         return r;
 863 }
 864 
 865 static int acx565akm_remove(struct spi_device *spi)
 866 {
 867         struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
 868         struct omap_dss_device *dssdev = &ddata->dssdev;
 869         struct omap_dss_device *in = ddata->in;
 870 
 871         dev_dbg(&ddata->spi->dev, "%s\n", __func__);
 872 
 873         sysfs_remove_group(&ddata->bl_dev->dev.kobj, &bldev_attr_group);
 874         backlight_device_unregister(ddata->bl_dev);
 875 
 876         omapdss_unregister_display(dssdev);
 877 
 878         acx565akm_disable(dssdev);
 879         acx565akm_disconnect(dssdev);
 880 
 881         omap_dss_put_device(in);
 882 
 883         return 0;
 884 }
 885 
 886 static const struct of_device_id acx565akm_of_match[] = {
 887         { .compatible = "omapdss,sony,acx565akm", },
 888         {},
 889 };
 890 MODULE_DEVICE_TABLE(of, acx565akm_of_match);
 891 
 892 static struct spi_driver acx565akm_driver = {
 893         .driver = {
 894                 .name   = "acx565akm",
 895                 .of_match_table = acx565akm_of_match,
 896                 .suppress_bind_attrs = true,
 897         },
 898         .probe  = acx565akm_probe,
 899         .remove = acx565akm_remove,
 900 };
 901 
 902 module_spi_driver(acx565akm_driver);
 903 
 904 MODULE_AUTHOR("Nokia Corporation");
 905 MODULE_DESCRIPTION("acx565akm LCD Driver");
 906 MODULE_LICENSE("GPL");

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