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 510 if (omapdss_device_is_connected(dssdev)) 511 return 0; 512 513 return in->ops.sdi->connect(in, dssdev); 514 } 515 516 static void acx565akm_disconnect(struct omap_dss_device *dssdev) 517 { 518 struct panel_drv_data *ddata = to_panel_data(dssdev); 519 struct omap_dss_device *in = ddata->in; 520 521 if (!omapdss_device_is_connected(dssdev)) 522 return; 523 524 in->ops.sdi->disconnect(in, dssdev); 525 } 526 527 static int acx565akm_panel_power_on(struct omap_dss_device *dssdev) 528 { 529 struct panel_drv_data *ddata = to_panel_data(dssdev); 530 struct omap_dss_device *in = ddata->in; 531 int r; 532 533 dev_dbg(&ddata->spi->dev, "%s\n", __func__); 534 535 in->ops.sdi->set_timings(in, &ddata->videomode); 536 537 if (ddata->datapairs > 0) 538 in->ops.sdi->set_datapairs(in, ddata->datapairs); 539 540 r = in->ops.sdi->enable(in); 541 if (r) { 542 pr_err("%s sdi enable failed\n", __func__); 543 return r; 544 } 545 546 /*FIXME tweak me */ 547 msleep(50); 548 549 if (gpio_is_valid(ddata->reset_gpio)) 550 gpio_set_value(ddata->reset_gpio, 1); 551 552 if (ddata->enabled) { 553 dev_dbg(&ddata->spi->dev, "panel already enabled\n"); 554 return 0; 555 } 556 557 /* 558 * We have to meet all the following delay requirements: 559 * 1. tRW: reset pulse width 10usec (7.12.1) 560 * 2. tRT: reset cancel time 5msec (7.12.1) 561 * 3. Providing PCLK,HS,VS signals for 2 frames = ~50msec worst 562 * case (7.6.2) 563 * 4. 120msec before the sleep out command (7.12.1) 564 */ 565 msleep(120); 566 567 set_sleep_mode(ddata, 0); 568 ddata->enabled = 1; 569 570 /* 5msec between sleep out and the next command. (8.2.16) */ 571 usleep_range(5000, 10000); 572 set_display_state(ddata, 1); 573 set_cabc_mode(ddata, ddata->cabc_mode); 574 575 return acx565akm_bl_update_status(ddata->bl_dev); 576 } 577 578 static void acx565akm_panel_power_off(struct omap_dss_device *dssdev) 579 { 580 struct panel_drv_data *ddata = to_panel_data(dssdev); 581 struct omap_dss_device *in = ddata->in; 582 583 dev_dbg(dssdev->dev, "%s\n", __func__); 584 585 if (!ddata->enabled) 586 return; 587 588 set_display_state(ddata, 0); 589 set_sleep_mode(ddata, 1); 590 ddata->enabled = 0; 591 /* 592 * We have to provide PCLK,HS,VS signals for 2 frames (worst case 593 * ~50msec) after sending the sleep in command and asserting the 594 * reset signal. We probably could assert the reset w/o the delay 595 * but we still delay to avoid possible artifacts. (7.6.1) 596 */ 597 msleep(50); 598 599 if (gpio_is_valid(ddata->reset_gpio)) 600 gpio_set_value(ddata->reset_gpio, 0); 601 602 /* FIXME need to tweak this delay */ 603 msleep(100); 604 605 in->ops.sdi->disable(in); 606 } 607 608 static int acx565akm_enable(struct omap_dss_device *dssdev) 609 { 610 struct panel_drv_data *ddata = to_panel_data(dssdev); 611 int r; 612 613 dev_dbg(dssdev->dev, "%s\n", __func__); 614 615 if (!omapdss_device_is_connected(dssdev)) 616 return -ENODEV; 617 618 if (omapdss_device_is_enabled(dssdev)) 619 return 0; 620 621 mutex_lock(&ddata->mutex); 622 r = acx565akm_panel_power_on(dssdev); 623 mutex_unlock(&ddata->mutex); 624 if (r) 625 return r; 626 627 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 628 629 return 0; 630 } 631 632 static void acx565akm_disable(struct omap_dss_device *dssdev) 633 { 634 struct panel_drv_data *ddata = to_panel_data(dssdev); 635 636 dev_dbg(dssdev->dev, "%s\n", __func__); 637 638 if (!omapdss_device_is_enabled(dssdev)) 639 return; 640 641 mutex_lock(&ddata->mutex); 642 acx565akm_panel_power_off(dssdev); 643 mutex_unlock(&ddata->mutex); 644 645 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 646 } 647 648 static void acx565akm_set_timings(struct omap_dss_device *dssdev, 649 struct omap_video_timings *timings) 650 { 651 struct panel_drv_data *ddata = to_panel_data(dssdev); 652 struct omap_dss_device *in = ddata->in; 653 654 ddata->videomode = *timings; 655 dssdev->panel.timings = *timings; 656 657 in->ops.sdi->set_timings(in, timings); 658 } 659 660 static void acx565akm_get_timings(struct omap_dss_device *dssdev, 661 struct omap_video_timings *timings) 662 { 663 struct panel_drv_data *ddata = to_panel_data(dssdev); 664 665 *timings = ddata->videomode; 666 } 667 668 static int acx565akm_check_timings(struct omap_dss_device *dssdev, 669 struct omap_video_timings *timings) 670 { 671 struct panel_drv_data *ddata = to_panel_data(dssdev); 672 struct omap_dss_device *in = ddata->in; 673 674 return in->ops.sdi->check_timings(in, timings); 675 } 676 677 static struct omap_dss_driver acx565akm_ops = { 678 .connect = acx565akm_connect, 679 .disconnect = acx565akm_disconnect, 680 681 .enable = acx565akm_enable, 682 .disable = acx565akm_disable, 683 684 .set_timings = acx565akm_set_timings, 685 .get_timings = acx565akm_get_timings, 686 .check_timings = acx565akm_check_timings, 687 688 .get_resolution = omapdss_default_get_resolution, 689 }; 690 691 static int acx565akm_probe_pdata(struct spi_device *spi) 692 { 693 const struct panel_acx565akm_platform_data *pdata; 694 struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); 695 struct omap_dss_device *dssdev, *in; 696 697 pdata = dev_get_platdata(&spi->dev); 698 699 ddata->reset_gpio = pdata->reset_gpio; 700 701 in = omap_dss_find_output(pdata->source); 702 if (in == NULL) { 703 dev_err(&spi->dev, "failed to find video source '%s'\n", 704 pdata->source); 705 return -EPROBE_DEFER; 706 } 707 ddata->in = in; 708 709 ddata->datapairs = pdata->datapairs; 710 711 dssdev = &ddata->dssdev; 712 dssdev->name = pdata->name; 713 714 return 0; 715 } 716 717 static int acx565akm_probe_of(struct spi_device *spi) 718 { 719 struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); 720 struct device_node *np = spi->dev.of_node; 721 722 ddata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); 723 724 ddata->in = omapdss_of_find_source_for_first_ep(np); 725 if (IS_ERR(ddata->in)) { 726 dev_err(&spi->dev, "failed to find video source\n"); 727 return PTR_ERR(ddata->in); 728 } 729 730 return 0; 731 } 732 733 static int acx565akm_probe(struct spi_device *spi) 734 { 735 struct panel_drv_data *ddata; 736 struct omap_dss_device *dssdev; 737 struct backlight_device *bldev; 738 int max_brightness, brightness; 739 struct backlight_properties props; 740 int r; 741 742 dev_dbg(&spi->dev, "%s\n", __func__); 743 744 spi->mode = SPI_MODE_3; 745 746 ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL); 747 if (ddata == NULL) 748 return -ENOMEM; 749 750 dev_set_drvdata(&spi->dev, ddata); 751 752 ddata->spi = spi; 753 754 mutex_init(&ddata->mutex); 755 756 if (dev_get_platdata(&spi->dev)) { 757 r = acx565akm_probe_pdata(spi); 758 if (r) 759 return r; 760 } else if (spi->dev.of_node) { 761 r = acx565akm_probe_of(spi); 762 if (r) 763 return r; 764 } else { 765 dev_err(&spi->dev, "platform data missing!\n"); 766 return -ENODEV; 767 } 768 769 if (gpio_is_valid(ddata->reset_gpio)) { 770 r = devm_gpio_request_one(&spi->dev, ddata->reset_gpio, 771 GPIOF_OUT_INIT_LOW, "lcd reset"); 772 if (r) 773 goto err_gpio; 774 } 775 776 if (gpio_is_valid(ddata->reset_gpio)) 777 gpio_set_value(ddata->reset_gpio, 1); 778 779 /* 780 * After reset we have to wait 5 msec before the first 781 * command can be sent. 782 */ 783 usleep_range(5000, 10000); 784 785 ddata->enabled = panel_enabled(ddata); 786 787 r = panel_detect(ddata); 788 789 if (!ddata->enabled && gpio_is_valid(ddata->reset_gpio)) 790 gpio_set_value(ddata->reset_gpio, 0); 791 792 if (r) { 793 dev_err(&spi->dev, "%s panel detect error\n", __func__); 794 goto err_detect; 795 } 796 797 memset(&props, 0, sizeof(props)); 798 props.fb_blank = FB_BLANK_UNBLANK; 799 props.power = FB_BLANK_UNBLANK; 800 props.type = BACKLIGHT_RAW; 801 802 bldev = backlight_device_register("acx565akm", &ddata->spi->dev, 803 ddata, &acx565akm_bl_ops, &props); 804 if (IS_ERR(bldev)) { 805 r = PTR_ERR(bldev); 806 goto err_reg_bl; 807 } 808 ddata->bl_dev = bldev; 809 if (ddata->has_cabc) { 810 r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group); 811 if (r) { 812 dev_err(&bldev->dev, 813 "%s failed to create sysfs files\n", __func__); 814 goto err_sysfs; 815 } 816 ddata->cabc_mode = get_hw_cabc_mode(ddata); 817 } 818 819 max_brightness = 255; 820 821 if (ddata->has_bc) 822 brightness = acx565akm_get_actual_brightness(ddata); 823 else 824 brightness = 0; 825 826 bldev->props.max_brightness = max_brightness; 827 bldev->props.brightness = brightness; 828 829 acx565akm_bl_update_status(bldev); 830 831 832 ddata->videomode = acx565akm_panel_timings; 833 834 dssdev = &ddata->dssdev; 835 dssdev->dev = &spi->dev; 836 dssdev->driver = &acx565akm_ops; 837 dssdev->type = OMAP_DISPLAY_TYPE_SDI; 838 dssdev->owner = THIS_MODULE; 839 dssdev->panel.timings = ddata->videomode; 840 841 r = omapdss_register_display(dssdev); 842 if (r) { 843 dev_err(&spi->dev, "Failed to register panel\n"); 844 goto err_reg; 845 } 846 847 return 0; 848 849 err_reg: 850 sysfs_remove_group(&bldev->dev.kobj, &bldev_attr_group); 851 err_sysfs: 852 backlight_device_unregister(bldev); 853 err_reg_bl: 854 err_detect: 855 err_gpio: 856 omap_dss_put_device(ddata->in); 857 return r; 858 } 859 860 static int acx565akm_remove(struct spi_device *spi) 861 { 862 struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); 863 struct omap_dss_device *dssdev = &ddata->dssdev; 864 struct omap_dss_device *in = ddata->in; 865 866 dev_dbg(&ddata->spi->dev, "%s\n", __func__); 867 868 sysfs_remove_group(&ddata->bl_dev->dev.kobj, &bldev_attr_group); 869 backlight_device_unregister(ddata->bl_dev); 870 871 omapdss_unregister_display(dssdev); 872 873 acx565akm_disable(dssdev); 874 acx565akm_disconnect(dssdev); 875 876 omap_dss_put_device(in); 877 878 return 0; 879 } 880 881 static const struct of_device_id acx565akm_of_match[] = { 882 { .compatible = "omapdss,sony,acx565akm", }, 883 {}, 884 }; 885 MODULE_DEVICE_TABLE(of, acx565akm_of_match); 886 887 static struct spi_driver acx565akm_driver = { 888 .driver = { 889 .name = "acx565akm", 890 .of_match_table = acx565akm_of_match, 891 .suppress_bind_attrs = true, 892 }, 893 .probe = acx565akm_probe, 894 .remove = acx565akm_remove, 895 }; 896 897 module_spi_driver(acx565akm_driver); 898 899 MODULE_AUTHOR("Nokia Corporation"); 900 MODULE_DESCRIPTION("acx565akm LCD Driver"); 901 MODULE_LICENSE("GPL"); 902