panel-tpo-tpg110.c (11352B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Panel driver for the TPO TPG110 400CH LTPS TFT LCD Single Chip 4 * Digital Driver. 5 * 6 * This chip drives a TFT LCD, so it does not know what kind of 7 * display is actually connected to it, so the width and height of that 8 * display needs to be supplied from the machine configuration. 9 * 10 * Author: 11 * Linus Walleij <linus.walleij@linaro.org> 12 */ 13#include <drm/drm_modes.h> 14#include <drm/drm_panel.h> 15 16#include <linux/bitops.h> 17#include <linux/delay.h> 18#include <linux/gpio/consumer.h> 19#include <linux/init.h> 20#include <linux/kernel.h> 21#include <linux/module.h> 22#include <linux/of.h> 23#include <linux/platform_device.h> 24#include <linux/spi/spi.h> 25 26#define TPG110_TEST 0x00 27#define TPG110_CHIPID 0x01 28#define TPG110_CTRL1 0x02 29#define TPG110_RES_MASK GENMASK(2, 0) 30#define TPG110_RES_800X480 0x07 31#define TPG110_RES_640X480 0x06 32#define TPG110_RES_480X272 0x05 33#define TPG110_RES_480X640 0x04 34#define TPG110_RES_480X272_D 0x01 /* Dual scan: outputs 800x480 */ 35#define TPG110_RES_400X240_D 0x00 /* Dual scan: outputs 800x480 */ 36#define TPG110_CTRL2 0x03 37#define TPG110_CTRL2_PM BIT(0) 38#define TPG110_CTRL2_RES_PM_CTRL BIT(7) 39 40/** 41 * struct tpg110_panel_mode - lookup struct for the supported modes 42 */ 43struct tpg110_panel_mode { 44 /** 45 * @name: the name of this panel 46 */ 47 const char *name; 48 /** 49 * @magic: the magic value from the detection register 50 */ 51 u32 magic; 52 /** 53 * @mode: the DRM display mode for this panel 54 */ 55 struct drm_display_mode mode; 56 /** 57 * @bus_flags: the DRM bus flags for this panel e.g. inverted clock 58 */ 59 u32 bus_flags; 60}; 61 62/** 63 * struct tpg110 - state container for the TPG110 panel 64 */ 65struct tpg110 { 66 /** 67 * @dev: the container device 68 */ 69 struct device *dev; 70 /** 71 * @spi: the corresponding SPI device 72 */ 73 struct spi_device *spi; 74 /** 75 * @panel: the DRM panel instance for this device 76 */ 77 struct drm_panel panel; 78 /** 79 * @panel_mode: the panel mode as detected 80 */ 81 const struct tpg110_panel_mode *panel_mode; 82 /** 83 * @width: the width of this panel in mm 84 */ 85 u32 width; 86 /** 87 * @height: the height of this panel in mm 88 */ 89 u32 height; 90 /** 91 * @grestb: reset GPIO line 92 */ 93 struct gpio_desc *grestb; 94}; 95 96/* 97 * TPG110 modes, these are the simple modes, the dualscan modes that 98 * take 400x240 or 480x272 in and display as 800x480 are not listed. 99 */ 100static const struct tpg110_panel_mode tpg110_modes[] = { 101 { 102 .name = "800x480 RGB", 103 .magic = TPG110_RES_800X480, 104 .mode = { 105 .clock = 33200, 106 .hdisplay = 800, 107 .hsync_start = 800 + 40, 108 .hsync_end = 800 + 40 + 1, 109 .htotal = 800 + 40 + 1 + 216, 110 .vdisplay = 480, 111 .vsync_start = 480 + 10, 112 .vsync_end = 480 + 10 + 1, 113 .vtotal = 480 + 10 + 1 + 35, 114 }, 115 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, 116 }, 117 { 118 .name = "640x480 RGB", 119 .magic = TPG110_RES_640X480, 120 .mode = { 121 .clock = 25200, 122 .hdisplay = 640, 123 .hsync_start = 640 + 24, 124 .hsync_end = 640 + 24 + 1, 125 .htotal = 640 + 24 + 1 + 136, 126 .vdisplay = 480, 127 .vsync_start = 480 + 18, 128 .vsync_end = 480 + 18 + 1, 129 .vtotal = 480 + 18 + 1 + 27, 130 }, 131 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, 132 }, 133 { 134 .name = "480x272 RGB", 135 .magic = TPG110_RES_480X272, 136 .mode = { 137 .clock = 9000, 138 .hdisplay = 480, 139 .hsync_start = 480 + 2, 140 .hsync_end = 480 + 2 + 1, 141 .htotal = 480 + 2 + 1 + 43, 142 .vdisplay = 272, 143 .vsync_start = 272 + 2, 144 .vsync_end = 272 + 2 + 1, 145 .vtotal = 272 + 2 + 1 + 12, 146 }, 147 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, 148 }, 149 { 150 .name = "480x640 RGB", 151 .magic = TPG110_RES_480X640, 152 .mode = { 153 .clock = 20500, 154 .hdisplay = 480, 155 .hsync_start = 480 + 2, 156 .hsync_end = 480 + 2 + 1, 157 .htotal = 480 + 2 + 1 + 43, 158 .vdisplay = 640, 159 .vsync_start = 640 + 4, 160 .vsync_end = 640 + 4 + 1, 161 .vtotal = 640 + 4 + 1 + 8, 162 }, 163 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, 164 }, 165 { 166 .name = "400x240 RGB", 167 .magic = TPG110_RES_400X240_D, 168 .mode = { 169 .clock = 8300, 170 .hdisplay = 400, 171 .hsync_start = 400 + 20, 172 .hsync_end = 400 + 20 + 1, 173 .htotal = 400 + 20 + 1 + 108, 174 .vdisplay = 240, 175 .vsync_start = 240 + 2, 176 .vsync_end = 240 + 2 + 1, 177 .vtotal = 240 + 2 + 1 + 20, 178 }, 179 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, 180 }, 181}; 182 183static inline struct tpg110 * 184to_tpg110(struct drm_panel *panel) 185{ 186 return container_of(panel, struct tpg110, panel); 187} 188 189static u8 tpg110_readwrite_reg(struct tpg110 *tpg, bool write, 190 u8 address, u8 outval) 191{ 192 struct spi_message m; 193 struct spi_transfer t[2]; 194 u8 buf[2]; 195 int ret; 196 197 spi_message_init(&m); 198 memset(t, 0, sizeof(t)); 199 200 if (write) { 201 /* 202 * Clear address bit 0, 1 when writing, just to be sure 203 * The actual bit indicating a write here is bit 1, bit 204 * 0 is just surplus to pad it up to 8 bits. 205 */ 206 buf[0] = address << 2; 207 buf[0] &= ~0x03; 208 buf[1] = outval; 209 210 t[0].bits_per_word = 8; 211 t[0].tx_buf = &buf[0]; 212 t[0].len = 1; 213 214 t[1].tx_buf = &buf[1]; 215 t[1].len = 1; 216 t[1].bits_per_word = 8; 217 } else { 218 /* Set address bit 0 to 1 to read */ 219 buf[0] = address << 1; 220 buf[0] |= 0x01; 221 222 /* 223 * The last bit/clock is Hi-Z turnaround cycle, so we need 224 * to send only 7 bits here. The 8th bit is the high impedance 225 * turn-around cycle. 226 */ 227 t[0].bits_per_word = 7; 228 t[0].tx_buf = &buf[0]; 229 t[0].len = 1; 230 231 t[1].rx_buf = &buf[1]; 232 t[1].len = 1; 233 t[1].bits_per_word = 8; 234 } 235 236 spi_message_add_tail(&t[0], &m); 237 spi_message_add_tail(&t[1], &m); 238 ret = spi_sync(tpg->spi, &m); 239 if (ret) { 240 dev_err(tpg->dev, "SPI message error %d\n", ret); 241 return ret; 242 } 243 if (write) 244 return 0; 245 /* Read */ 246 return buf[1]; 247} 248 249static u8 tpg110_read_reg(struct tpg110 *tpg, u8 address) 250{ 251 return tpg110_readwrite_reg(tpg, false, address, 0); 252} 253 254static void tpg110_write_reg(struct tpg110 *tpg, u8 address, u8 outval) 255{ 256 tpg110_readwrite_reg(tpg, true, address, outval); 257} 258 259static int tpg110_startup(struct tpg110 *tpg) 260{ 261 u8 val; 262 int i; 263 264 /* De-assert the reset signal */ 265 gpiod_set_value_cansleep(tpg->grestb, 0); 266 usleep_range(1000, 2000); 267 dev_dbg(tpg->dev, "de-asserted GRESTB\n"); 268 269 /* Test display communication */ 270 tpg110_write_reg(tpg, TPG110_TEST, 0x55); 271 val = tpg110_read_reg(tpg, TPG110_TEST); 272 if (val != 0x55) { 273 dev_err(tpg->dev, "failed communication test\n"); 274 return -ENODEV; 275 } 276 277 val = tpg110_read_reg(tpg, TPG110_CHIPID); 278 dev_info(tpg->dev, "TPG110 chip ID: %d version: %d\n", 279 val >> 4, val & 0x0f); 280 281 /* Show display resolution */ 282 val = tpg110_read_reg(tpg, TPG110_CTRL1); 283 val &= TPG110_RES_MASK; 284 switch (val) { 285 case TPG110_RES_400X240_D: 286 dev_info(tpg->dev, "IN 400x240 RGB -> OUT 800x480 RGB (dual scan)\n"); 287 break; 288 case TPG110_RES_480X272_D: 289 dev_info(tpg->dev, "IN 480x272 RGB -> OUT 800x480 RGB (dual scan)\n"); 290 break; 291 case TPG110_RES_480X640: 292 dev_info(tpg->dev, "480x640 RGB\n"); 293 break; 294 case TPG110_RES_480X272: 295 dev_info(tpg->dev, "480x272 RGB\n"); 296 break; 297 case TPG110_RES_640X480: 298 dev_info(tpg->dev, "640x480 RGB\n"); 299 break; 300 case TPG110_RES_800X480: 301 dev_info(tpg->dev, "800x480 RGB\n"); 302 break; 303 default: 304 dev_err(tpg->dev, "ILLEGAL RESOLUTION 0x%02x\n", val); 305 break; 306 } 307 308 /* From the producer side, this is the same resolution */ 309 if (val == TPG110_RES_480X272_D) 310 val = TPG110_RES_480X272; 311 312 for (i = 0; i < ARRAY_SIZE(tpg110_modes); i++) { 313 const struct tpg110_panel_mode *pm; 314 315 pm = &tpg110_modes[i]; 316 if (pm->magic == val) { 317 tpg->panel_mode = pm; 318 break; 319 } 320 } 321 if (i == ARRAY_SIZE(tpg110_modes)) { 322 dev_err(tpg->dev, "unsupported mode (%02x) detected\n", val); 323 return -ENODEV; 324 } 325 326 val = tpg110_read_reg(tpg, TPG110_CTRL2); 327 dev_info(tpg->dev, "resolution and standby is controlled by %s\n", 328 (val & TPG110_CTRL2_RES_PM_CTRL) ? "software" : "hardware"); 329 /* Take control over resolution and standby */ 330 val |= TPG110_CTRL2_RES_PM_CTRL; 331 tpg110_write_reg(tpg, TPG110_CTRL2, val); 332 333 return 0; 334} 335 336static int tpg110_disable(struct drm_panel *panel) 337{ 338 struct tpg110 *tpg = to_tpg110(panel); 339 u8 val; 340 341 /* Put chip into standby */ 342 val = tpg110_read_reg(tpg, TPG110_CTRL2_PM); 343 val &= ~TPG110_CTRL2_PM; 344 tpg110_write_reg(tpg, TPG110_CTRL2_PM, val); 345 346 return 0; 347} 348 349static int tpg110_enable(struct drm_panel *panel) 350{ 351 struct tpg110 *tpg = to_tpg110(panel); 352 u8 val; 353 354 /* Take chip out of standby */ 355 val = tpg110_read_reg(tpg, TPG110_CTRL2_PM); 356 val |= TPG110_CTRL2_PM; 357 tpg110_write_reg(tpg, TPG110_CTRL2_PM, val); 358 359 return 0; 360} 361 362/** 363 * tpg110_get_modes() - return the appropriate mode 364 * @panel: the panel to get the mode for 365 * @connector: reference to the central DRM connector control structure 366 * 367 * This currently does not present a forest of modes, instead it 368 * presents the mode that is configured for the system under use, 369 * and which is detected by reading the registers of the display. 370 */ 371static int tpg110_get_modes(struct drm_panel *panel, 372 struct drm_connector *connector) 373{ 374 struct tpg110 *tpg = to_tpg110(panel); 375 struct drm_display_mode *mode; 376 377 connector->display_info.width_mm = tpg->width; 378 connector->display_info.height_mm = tpg->height; 379 connector->display_info.bus_flags = tpg->panel_mode->bus_flags; 380 381 mode = drm_mode_duplicate(connector->dev, &tpg->panel_mode->mode); 382 drm_mode_set_name(mode); 383 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 384 385 mode->width_mm = tpg->width; 386 mode->height_mm = tpg->height; 387 388 drm_mode_probed_add(connector, mode); 389 390 return 1; 391} 392 393static const struct drm_panel_funcs tpg110_drm_funcs = { 394 .disable = tpg110_disable, 395 .enable = tpg110_enable, 396 .get_modes = tpg110_get_modes, 397}; 398 399static int tpg110_probe(struct spi_device *spi) 400{ 401 struct device *dev = &spi->dev; 402 struct device_node *np = dev->of_node; 403 struct tpg110 *tpg; 404 int ret; 405 406 tpg = devm_kzalloc(dev, sizeof(*tpg), GFP_KERNEL); 407 if (!tpg) 408 return -ENOMEM; 409 tpg->dev = dev; 410 411 /* We get the physical display dimensions from the DT */ 412 ret = of_property_read_u32(np, "width-mm", &tpg->width); 413 if (ret) 414 dev_err(dev, "no panel width specified\n"); 415 ret = of_property_read_u32(np, "height-mm", &tpg->height); 416 if (ret) 417 dev_err(dev, "no panel height specified\n"); 418 419 /* This asserts the GRESTB signal, putting the display into reset */ 420 tpg->grestb = devm_gpiod_get(dev, "grestb", GPIOD_OUT_HIGH); 421 if (IS_ERR(tpg->grestb)) { 422 dev_err(dev, "no GRESTB GPIO\n"); 423 return -ENODEV; 424 } 425 426 spi->bits_per_word = 8; 427 spi->mode |= SPI_3WIRE_HIZ; 428 ret = spi_setup(spi); 429 if (ret < 0) { 430 dev_err(dev, "spi setup failed.\n"); 431 return ret; 432 } 433 tpg->spi = spi; 434 435 ret = tpg110_startup(tpg); 436 if (ret) 437 return ret; 438 439 drm_panel_init(&tpg->panel, dev, &tpg110_drm_funcs, 440 DRM_MODE_CONNECTOR_DPI); 441 442 ret = drm_panel_of_backlight(&tpg->panel); 443 if (ret) 444 return ret; 445 446 spi_set_drvdata(spi, tpg); 447 448 drm_panel_add(&tpg->panel); 449 450 return 0; 451} 452 453static void tpg110_remove(struct spi_device *spi) 454{ 455 struct tpg110 *tpg = spi_get_drvdata(spi); 456 457 drm_panel_remove(&tpg->panel); 458} 459 460static const struct of_device_id tpg110_match[] = { 461 { .compatible = "tpo,tpg110", }, 462 {}, 463}; 464MODULE_DEVICE_TABLE(of, tpg110_match); 465 466static struct spi_driver tpg110_driver = { 467 .probe = tpg110_probe, 468 .remove = tpg110_remove, 469 .driver = { 470 .name = "tpo-tpg110-panel", 471 .of_match_table = tpg110_match, 472 }, 473}; 474module_spi_driver(tpg110_driver); 475 476MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); 477MODULE_DESCRIPTION("TPO TPG110 panel driver"); 478MODULE_LICENSE("GPL v2");