1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * TPO TD043MTEA1 Panel driver 4 * 5 * Author: Gražvydas Ignotas <notasas@gmail.com> 6 * Converted to new DSS device model: Tomi Valkeinen <tomi.valkeinen@ti.com> 7 */ 8 9 #include <linux/module.h> 10 #include <linux/delay.h> 11 #include <linux/spi/spi.h> 12 #include <linux/regulator/consumer.h> 13 #include <linux/gpio/consumer.h> 14 #include <linux/err.h> 15 #include <linux/slab.h> 16 17 #include <video/omapfb_dss.h> 18 19 #define TPO_R02_MODE(x) ((x) & 7) 20 #define TPO_R02_MODE_800x480 7 21 #define TPO_R02_NCLK_RISING BIT(3) 22 #define TPO_R02_HSYNC_HIGH BIT(4) 23 #define TPO_R02_VSYNC_HIGH BIT(5) 24 25 #define TPO_R03_NSTANDBY BIT(0) 26 #define TPO_R03_EN_CP_CLK BIT(1) 27 #define TPO_R03_EN_VGL_PUMP BIT(2) 28 #define TPO_R03_EN_PWM BIT(3) 29 #define TPO_R03_DRIVING_CAP_100 BIT(4) 30 #define TPO_R03_EN_PRE_CHARGE BIT(6) 31 #define TPO_R03_SOFTWARE_CTL BIT(7) 32 33 #define TPO_R04_NFLIP_H BIT(0) 34 #define TPO_R04_NFLIP_V BIT(1) 35 #define TPO_R04_CP_CLK_FREQ_1H BIT(2) 36 #define TPO_R04_VGL_FREQ_1H BIT(4) 37 38 #define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \ 39 TPO_R03_EN_VGL_PUMP | TPO_R03_EN_PWM | \ 40 TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \ 41 TPO_R03_SOFTWARE_CTL) 42 43 #define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \ 44 TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL) 45 46 static const u16 tpo_td043_def_gamma[12] = { 47 105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023 48 }; 49 50 struct panel_drv_data { 51 struct omap_dss_device dssdev; 52 struct omap_dss_device *in; 53 54 struct omap_video_timings videomode; 55 56 int data_lines; 57 58 struct spi_device *spi; 59 struct regulator *vcc_reg; 60 struct gpio_desc *reset_gpio; 61 u16 gamma[12]; 62 u32 mode; 63 u32 hmirror:1; 64 u32 vmirror:1; 65 u32 powered_on:1; 66 u32 spi_suspended:1; 67 u32 power_on_resume:1; 68 }; 69 70 static const struct omap_video_timings tpo_td043_timings = { 71 .x_res = 800, 72 .y_res = 480, 73 74 .pixelclock = 36000000, 75 76 .hsw = 1, 77 .hfp = 68, 78 .hbp = 214, 79 80 .vsw = 1, 81 .vfp = 39, 82 .vbp = 34, 83 84 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, 85 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, 86 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, 87 .de_level = OMAPDSS_SIG_ACTIVE_HIGH, 88 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, 89 }; 90 91 #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) 92 93 static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data) 94 { 95 struct spi_message m; 96 struct spi_transfer xfer; 97 u16 w; 98 int r; 99 100 spi_message_init(&m); 101 102 memset(&xfer, 0, sizeof(xfer)); 103 104 w = ((u16)addr << 10) | (1 << 8) | data; 105 xfer.tx_buf = &w; 106 xfer.bits_per_word = 16; 107 xfer.len = 2; 108 spi_message_add_tail(&xfer, &m); 109 110 r = spi_sync(spi, &m); 111 if (r < 0) 112 dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r); 113 return r; 114 } 115 116 static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12]) 117 { 118 u8 i, val; 119 120 /* gamma bits [9:8] */ 121 for (val = i = 0; i < 4; i++) 122 val |= (gamma[i] & 0x300) >> ((i + 1) * 2); 123 tpo_td043_write(spi, 0x11, val); 124 125 for (val = i = 0; i < 4; i++) 126 val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2); 127 tpo_td043_write(spi, 0x12, val); 128 129 for (val = i = 0; i < 4; i++) 130 val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2); 131 tpo_td043_write(spi, 0x13, val); 132 133 /* gamma bits [7:0] */ 134 for (val = i = 0; i < 12; i++) 135 tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff); 136 } 137 138 static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v) 139 { 140 u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V | 141 TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H; 142 if (h) 143 reg4 &= ~TPO_R04_NFLIP_H; 144 if (v) 145 reg4 &= ~TPO_R04_NFLIP_V; 146 147 return tpo_td043_write(spi, 4, reg4); 148 } 149 150 static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable) 151 { 152 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); 153 154 ddata->hmirror = enable; 155 return tpo_td043_write_mirror(ddata->spi, ddata->hmirror, 156 ddata->vmirror); 157 } 158 159 static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev) 160 { 161 struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); 162 163 return ddata->hmirror; 164 } 165 166 static ssize_t tpo_td043_vmirror_show(struct device *dev, 167 struct device_attribute *attr, char *buf) 168 { 169 struct panel_drv_data *ddata = dev_get_drvdata(dev); 170 171 return sysfs_emit(buf, "%d\n", ddata->vmirror); 172 } 173 174 static ssize_t tpo_td043_vmirror_store(struct device *dev, 175 struct device_attribute *attr, const char *buf, size_t count) 176 { 177 struct panel_drv_data *ddata = dev_get_drvdata(dev); 178 int val; 179 int ret; 180 181 ret = kstrtoint(buf, 0, &val); 182 if (ret < 0) 183 return ret; 184 185 val = !!val; 186 187 ret = tpo_td043_write_mirror(ddata->spi, ddata->hmirror, val); 188 if (ret < 0) 189 return ret; 190 191 ddata->vmirror = val; 192 193 return count; 194 } 195 196 static ssize_t tpo_td043_mode_show(struct device *dev, 197 struct device_attribute *attr, char *buf) 198 { 199 struct panel_drv_data *ddata = dev_get_drvdata(dev); 200 201 return sysfs_emit(buf, "%d\n", ddata->mode); 202 } 203 204 static ssize_t tpo_td043_mode_store(struct device *dev, 205 struct device_attribute *attr, const char *buf, size_t count) 206 { 207 struct panel_drv_data *ddata = dev_get_drvdata(dev); 208 long val; 209 int ret; 210 211 ret = kstrtol(buf, 0, &val); 212 if (ret != 0 || val & ~7) 213 return -EINVAL; 214 215 ddata->mode = val; 216 217 val |= TPO_R02_NCLK_RISING; 218 tpo_td043_write(ddata->spi, 2, val); 219 220 return count; 221 } 222 223 static ssize_t tpo_td043_gamma_show(struct device *dev, 224 struct device_attribute *attr, char *buf) 225 { 226 struct panel_drv_data *ddata = dev_get_drvdata(dev); 227 ssize_t len = 0; 228 int ret; 229 int i; 230 231 for (i = 0; i < ARRAY_SIZE(ddata->gamma); i++) { 232 ret = snprintf(buf + len, PAGE_SIZE - len, "%u ", 233 ddata->gamma[i]); 234 if (ret < 0) 235 return ret; 236 len += ret; 237 } 238 buf[len - 1] = '\n'; 239 240 return len; 241 } 242 243 static ssize_t tpo_td043_gamma_store(struct device *dev, 244 struct device_attribute *attr, const char *buf, size_t count) 245 { 246 struct panel_drv_data *ddata = dev_get_drvdata(dev); 247 unsigned int g[12]; 248 int ret; 249 int i; 250 251 ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u", 252 &g[0], &g[1], &g[2], &g[3], &g[4], &g[5], 253 &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]); 254 255 if (ret != 12) 256 return -EINVAL; 257 258 for (i = 0; i < 12; i++) 259 ddata->gamma[i] = g[i]; 260 261 tpo_td043_write_gamma(ddata->spi, ddata->gamma); 262 263 return count; 264 } 265 266 static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR, 267 tpo_td043_vmirror_show, tpo_td043_vmirror_store); 268 static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, 269 tpo_td043_mode_show, tpo_td043_mode_store); 270 static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR, 271 tpo_td043_gamma_show, tpo_td043_gamma_store); 272 273 static struct attribute *tpo_td043_attrs[] = { 274 &dev_attr_vmirror.attr, 275 &dev_attr_mode.attr, 276 &dev_attr_gamma.attr, 277 NULL, 278 }; 279 280 static const struct attribute_group tpo_td043_attr_group = { 281 .attrs = tpo_td043_attrs, 282 }; 283 284 static int tpo_td043_power_on(struct panel_drv_data *ddata) 285 { 286 int r; 287 288 if (ddata->powered_on) 289 return 0; 290 291 r = regulator_enable(ddata->vcc_reg); 292 if (r != 0) 293 return r; 294 295 /* wait for panel to stabilize */ 296 msleep(160); 297 298 gpiod_set_value_cansleep(ddata->reset_gpio, 0); 299 300 tpo_td043_write(ddata->spi, 2, 301 TPO_R02_MODE(ddata->mode) | TPO_R02_NCLK_RISING); 302 tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_NORMAL); 303 tpo_td043_write(ddata->spi, 0x20, 0xf0); 304 tpo_td043_write(ddata->spi, 0x21, 0xf0); 305 tpo_td043_write_mirror(ddata->spi, ddata->hmirror, 306 ddata->vmirror); 307 tpo_td043_write_gamma(ddata->spi, ddata->gamma); 308 309 ddata->powered_on = 1; 310 return 0; 311 } 312 313 static void tpo_td043_power_off(struct panel_drv_data *ddata) 314 { 315 if (!ddata->powered_on) 316 return; 317 318 tpo_td043_write(ddata->spi, 3, 319 TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM); 320 321 gpiod_set_value_cansleep(ddata->reset_gpio, 1); 322 323 /* wait for at least 2 vsyncs before cutting off power */ 324 msleep(50); 325 326 tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_STANDBY); 327 328 regulator_disable(ddata->vcc_reg); 329 330 ddata->powered_on = 0; 331 } 332 333 static int tpo_td043_connect(struct omap_dss_device *dssdev) 334 { 335 struct panel_drv_data *ddata = to_panel_data(dssdev); 336 struct omap_dss_device *in = ddata->in; 337 338 if (omapdss_device_is_connected(dssdev)) 339 return 0; 340 341 return in->ops.dpi->connect(in, dssdev); 342 } 343 344 static void tpo_td043_disconnect(struct omap_dss_device *dssdev) 345 { 346 struct panel_drv_data *ddata = to_panel_data(dssdev); 347 struct omap_dss_device *in = ddata->in; 348 349 if (!omapdss_device_is_connected(dssdev)) 350 return; 351 352 in->ops.dpi->disconnect(in, dssdev); 353 } 354 355 static int tpo_td043_enable(struct omap_dss_device *dssdev) 356 { 357 struct panel_drv_data *ddata = to_panel_data(dssdev); 358 struct omap_dss_device *in = ddata->in; 359 int r; 360 361 if (!omapdss_device_is_connected(dssdev)) 362 return -ENODEV; 363 364 if (omapdss_device_is_enabled(dssdev)) 365 return 0; 366 367 if (ddata->data_lines) 368 in->ops.dpi->set_data_lines(in, ddata->data_lines); 369 in->ops.dpi->set_timings(in, &ddata->videomode); 370 371 r = in->ops.dpi->enable(in); 372 if (r) 373 return r; 374 375 /* 376 * If we are resuming from system suspend, SPI clocks might not be 377 * enabled yet, so we'll program the LCD from SPI PM resume callback. 378 */ 379 if (!ddata->spi_suspended) { 380 r = tpo_td043_power_on(ddata); 381 if (r) { 382 in->ops.dpi->disable(in); 383 return r; 384 } 385 } 386 387 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 388 389 return 0; 390 } 391 392 static void tpo_td043_disable(struct omap_dss_device *dssdev) 393 { 394 struct panel_drv_data *ddata = to_panel_data(dssdev); 395 struct omap_dss_device *in = ddata->in; 396 397 if (!omapdss_device_is_enabled(dssdev)) 398 return; 399 400 in->ops.dpi->disable(in); 401 402 if (!ddata->spi_suspended) 403 tpo_td043_power_off(ddata); 404 405 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 406 } 407 408 static void tpo_td043_set_timings(struct omap_dss_device *dssdev, 409 struct omap_video_timings *timings) 410 { 411 struct panel_drv_data *ddata = to_panel_data(dssdev); 412 struct omap_dss_device *in = ddata->in; 413 414 ddata->videomode = *timings; 415 dssdev->panel.timings = *timings; 416 417 in->ops.dpi->set_timings(in, timings); 418 } 419 420 static void tpo_td043_get_timings(struct omap_dss_device *dssdev, 421 struct omap_video_timings *timings) 422 { 423 struct panel_drv_data *ddata = to_panel_data(dssdev); 424 425 *timings = ddata->videomode; 426 } 427 428 static int tpo_td043_check_timings(struct omap_dss_device *dssdev, 429 struct omap_video_timings *timings) 430 { 431 struct panel_drv_data *ddata = to_panel_data(dssdev); 432 struct omap_dss_device *in = ddata->in; 433 434 return in->ops.dpi->check_timings(in, timings); 435 } 436 437 static struct omap_dss_driver tpo_td043_ops = { 438 .connect = tpo_td043_connect, 439 .disconnect = tpo_td043_disconnect, 440 441 .enable = tpo_td043_enable, 442 .disable = tpo_td043_disable, 443 444 .set_timings = tpo_td043_set_timings, 445 .get_timings = tpo_td043_get_timings, 446 .check_timings = tpo_td043_check_timings, 447 448 .set_mirror = tpo_td043_set_hmirror, 449 .get_mirror = tpo_td043_get_hmirror, 450 451 .get_resolution = omapdss_default_get_resolution, 452 }; 453 454 static int tpo_td043_probe(struct spi_device *spi) 455 { 456 struct panel_drv_data *ddata; 457 struct omap_dss_device *dssdev; 458 int r; 459 460 dev_dbg(&spi->dev, "%s\n", __func__); 461 462 if (!spi->dev.of_node) 463 return -ENODEV; 464 465 spi->bits_per_word = 16; 466 spi->mode = SPI_MODE_0; 467 468 r = spi_setup(spi); 469 if (r < 0) { 470 dev_err(&spi->dev, "spi_setup failed: %d\n", r); 471 return r; 472 } 473 474 ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL); 475 if (ddata == NULL) 476 return -ENOMEM; 477 478 dev_set_drvdata(&spi->dev, ddata); 479 480 ddata->spi = spi; 481 482 ddata->in = omapdss_of_find_source_for_first_ep(spi->dev.of_node); 483 r = PTR_ERR_OR_ZERO(ddata->in); 484 if (r) { 485 dev_err(&spi->dev, "failed to find video source: %d\n", r); 486 return r; 487 } 488 489 ddata->mode = TPO_R02_MODE_800x480; 490 memcpy(ddata->gamma, tpo_td043_def_gamma, sizeof(ddata->gamma)); 491 492 ddata->vcc_reg = devm_regulator_get(&spi->dev, "vcc"); 493 if (IS_ERR(ddata->vcc_reg)) { 494 r = dev_err_probe(&spi->dev, r, "failed to get LCD VCC regulator\n"); 495 goto err_regulator; 496 } 497 498 ddata->reset_gpio = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_HIGH); 499 r = PTR_ERR_OR_ZERO(ddata->reset_gpio); 500 if (r) { 501 dev_err(&spi->dev, "couldn't request reset GPIO\n"); 502 goto err_gpio_req; 503 } 504 505 gpiod_set_consumer_name(ddata->reset_gpio, "lcd reset"); 506 507 r = sysfs_create_group(&spi->dev.kobj, &tpo_td043_attr_group); 508 if (r) { 509 dev_err(&spi->dev, "failed to create sysfs files\n"); 510 goto err_sysfs; 511 } 512 513 ddata->videomode = tpo_td043_timings; 514 515 dssdev = &ddata->dssdev; 516 dssdev->dev = &spi->dev; 517 dssdev->driver = &tpo_td043_ops; 518 dssdev->type = OMAP_DISPLAY_TYPE_DPI; 519 dssdev->owner = THIS_MODULE; 520 dssdev->panel.timings = ddata->videomode; 521 522 r = omapdss_register_display(dssdev); 523 if (r) { 524 dev_err(&spi->dev, "Failed to register panel\n"); 525 goto err_reg; 526 } 527 528 return 0; 529 530 err_reg: 531 sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group); 532 err_sysfs: 533 err_gpio_req: 534 err_regulator: 535 omap_dss_put_device(ddata->in); 536 return r; 537 } 538 539 static void tpo_td043_remove(struct spi_device *spi) 540 { 541 struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); 542 struct omap_dss_device *dssdev = &ddata->dssdev; 543 struct omap_dss_device *in = ddata->in; 544 545 dev_dbg(&ddata->spi->dev, "%s\n", __func__); 546 547 omapdss_unregister_display(dssdev); 548 549 tpo_td043_disable(dssdev); 550 tpo_td043_disconnect(dssdev); 551 552 omap_dss_put_device(in); 553 554 sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group); 555 } 556 557 #ifdef CONFIG_PM_SLEEP 558 static int tpo_td043_spi_suspend(struct device *dev) 559 { 560 struct panel_drv_data *ddata = dev_get_drvdata(dev); 561 562 dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", ddata); 563 564 ddata->power_on_resume = ddata->powered_on; 565 tpo_td043_power_off(ddata); 566 ddata->spi_suspended = 1; 567 568 return 0; 569 } 570 571 static int tpo_td043_spi_resume(struct device *dev) 572 { 573 struct panel_drv_data *ddata = dev_get_drvdata(dev); 574 int ret; 575 576 dev_dbg(dev, "tpo_td043_spi_resume\n"); 577 578 if (ddata->power_on_resume) { 579 ret = tpo_td043_power_on(ddata); 580 if (ret) 581 return ret; 582 } 583 ddata->spi_suspended = 0; 584 585 return 0; 586 } 587 #endif 588 589 static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm, 590 tpo_td043_spi_suspend, tpo_td043_spi_resume); 591 592 static const struct of_device_id tpo_td043_of_match[] = { 593 { .compatible = "omapdss,tpo,td043mtea1", }, 594 {}, 595 }; 596 597 MODULE_DEVICE_TABLE(of, tpo_td043_of_match); 598 599 static struct spi_driver tpo_td043_spi_driver = { 600 .driver = { 601 .name = "panel-tpo-td043mtea1", 602 .pm = &tpo_td043_spi_pm, 603 .of_match_table = tpo_td043_of_match, 604 .suppress_bind_attrs = true, 605 }, 606 .probe = tpo_td043_probe, 607 .remove = tpo_td043_remove, 608 }; 609 610 module_spi_driver(tpo_td043_spi_driver); 611 612 MODULE_ALIAS("spi:tpo,td043mtea1"); 613 MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>"); 614 MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver"); 615 MODULE_LICENSE("GPL"); 616