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"); 907