19ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas/* 29ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas * LCD panel driver for TPO TD043MTEA1 39ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas * 49ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas * Author: Gražvydas Ignotas <notasas@gmail.com> 59ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas * 69ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas * This program is free software; you can redistribute it and/or modify 79ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas * it under the terms of the GNU General Public License as published by 89ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas * the Free Software Foundation; either version 2 of the License, or 99ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas * (at your option) any later version. 109ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas */ 119ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 129ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#include <linux/module.h> 139ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#include <linux/delay.h> 149ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#include <linux/spi/spi.h> 159ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#include <linux/regulator/consumer.h> 169ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#include <linux/gpio.h> 179ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#include <linux/err.h> 185a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 199ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 20a0b38cc4d35e095f14ab0f486135f8a619ebfc14Tomi Valkeinen#include <video/omapdss.h> 219ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 229ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R02_MODE(x) ((x) & 7) 239ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R02_MODE_800x480 7 249ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R02_NCLK_RISING BIT(3) 259ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R02_HSYNC_HIGH BIT(4) 269ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R02_VSYNC_HIGH BIT(5) 279ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 289ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R03_NSTANDBY BIT(0) 299ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R03_EN_CP_CLK BIT(1) 309ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R03_EN_VGL_PUMP BIT(2) 319ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R03_EN_PWM BIT(3) 329ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R03_DRIVING_CAP_100 BIT(4) 339ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R03_EN_PRE_CHARGE BIT(6) 349ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R03_SOFTWARE_CTL BIT(7) 359ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 369ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R04_NFLIP_H BIT(0) 379ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R04_NFLIP_V BIT(1) 389ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R04_CP_CLK_FREQ_1H BIT(2) 399ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R04_VGL_FREQ_1H BIT(4) 409ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 419ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \ 429ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas TPO_R03_EN_VGL_PUMP | TPO_R03_EN_PWM | \ 439ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \ 449ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas TPO_R03_SOFTWARE_CTL) 459ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 469ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas#define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \ 479ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL) 489ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 499ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic const u16 tpo_td043_def_gamma[12] = { 504306b721ac1e8b79858b38537f0fb5a940a792beGrazvydas Ignotas 105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023 519ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas}; 529ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 539ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstruct tpo_td043_device { 549ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct spi_device *spi; 559ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct regulator *vcc_reg; 568df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas int nreset_gpio; 579ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas u16 gamma[12]; 589ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas u32 mode; 599ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas u32 hmirror:1; 609ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas u32 vmirror:1; 618df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas u32 powered_on:1; 628df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas u32 spi_suspended:1; 638df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas u32 power_on_resume:1; 649ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas}; 659ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 669ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data) 679ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 689ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct spi_message m; 699ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct spi_transfer xfer; 709ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas u16 w; 719ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas int r; 729ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 739ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas spi_message_init(&m); 749ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 759ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas memset(&xfer, 0, sizeof(xfer)); 769ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 779ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas w = ((u16)addr << 10) | (1 << 8) | data; 789ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas xfer.tx_buf = &w; 799ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas xfer.bits_per_word = 16; 809ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas xfer.len = 2; 819ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas spi_message_add_tail(&xfer, &m); 829ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 839ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas r = spi_sync(spi, &m); 849ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (r < 0) 859ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r); 869ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return r; 879ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 889ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 899ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12]) 909ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 919ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas u8 i, val; 929ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 939ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas /* gamma bits [9:8] */ 949ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas for (val = i = 0; i < 4; i++) 959ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas val |= (gamma[i] & 0x300) >> ((i + 1) * 2); 969ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write(spi, 0x11, val); 979ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 989ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas for (val = i = 0; i < 4; i++) 999ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2); 1009ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write(spi, 0x12, val); 1019ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1029ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas for (val = i = 0; i < 4; i++) 1039ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2); 1049ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write(spi, 0x13, val); 1059ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1069ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas /* gamma bits [7:0] */ 1079ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas for (val = i = 0; i < 12; i++) 1089ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff); 1099ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 1109ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1119ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v) 1129ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 1139ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V | \ 1149ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H; 1159ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (h) 1169ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas reg4 &= ~TPO_R04_NFLIP_H; 1179ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (v) 1189ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas reg4 &= ~TPO_R04_NFLIP_V; 1199ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1209ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return tpo_td043_write(spi, 4, reg4); 1219ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 1229ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1239ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable) 1249ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 1259ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 1269ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1279ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043->hmirror = enable; 1289ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, 1299ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043->vmirror); 1309ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 1319ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1329ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev) 1339ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 1349ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 1359ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1369ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return tpo_td043->hmirror; 1379ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 1389ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1399ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic ssize_t tpo_td043_vmirror_show(struct device *dev, 1409ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct device_attribute *attr, char *buf) 1419ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 1429ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); 1439ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1449ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->vmirror); 1459ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 1469ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1479ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic ssize_t tpo_td043_vmirror_store(struct device *dev, 1489ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct device_attribute *attr, const char *buf, size_t count) 1499ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 1509ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); 151e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen int val; 1529ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas int ret; 1539ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 154e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen ret = kstrtoint(buf, 0, &val); 1559ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (ret < 0) 1569ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return ret; 1579ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 158e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen val = !!val; 159e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen 1609ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val); 1619ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (ret < 0) 1629ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return ret; 1639ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1649ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043->vmirror = val; 1659ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1669ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return count; 1679ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 1689ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1699ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic ssize_t tpo_td043_mode_show(struct device *dev, 1709ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct device_attribute *attr, char *buf) 1719ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 1729ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); 1739ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1749ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->mode); 1759ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 1769ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1779ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic ssize_t tpo_td043_mode_store(struct device *dev, 1789ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct device_attribute *attr, const char *buf, size_t count) 1799ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 1809ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); 1819ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas long val; 1829ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas int ret; 1839ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 184e3502ce97f2d2d183735d9fae76b081a634ffd85Tomi Valkeinen ret = kstrtol(buf, 0, &val); 1859ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (ret != 0 || val & ~7) 1869ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return -EINVAL; 1879ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1889ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043->mode = val; 1899ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1909ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas val |= TPO_R02_NCLK_RISING; 1919ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write(tpo_td043->spi, 2, val); 1929ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1939ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return count; 1949ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 1959ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 1969ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic ssize_t tpo_td043_gamma_show(struct device *dev, 1979ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct device_attribute *attr, char *buf) 1989ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 1999ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); 2009ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas ssize_t len = 0; 2019ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas int ret; 2029ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas int i; 2039ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2049ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas for (i = 0; i < ARRAY_SIZE(tpo_td043->gamma); i++) { 2059ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas ret = snprintf(buf + len, PAGE_SIZE - len, "%u ", 2069ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043->gamma[i]); 2079ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (ret < 0) 2089ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return ret; 2099ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas len += ret; 2109ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas } 2119ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas buf[len - 1] = '\n'; 2129ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2139ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return len; 2149ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 2159ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2169ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic ssize_t tpo_td043_gamma_store(struct device *dev, 2179ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct device_attribute *attr, const char *buf, size_t count) 2189ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 2199ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); 2209ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas unsigned int g[12]; 2219ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas int ret; 2229ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas int i; 2239ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2249ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u", 2259ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas &g[0], &g[1], &g[2], &g[3], &g[4], &g[5], 2269ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]); 2279ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2289ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (ret != 12) 2299ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return -EINVAL; 2309ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2319ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas for (i = 0; i < 12; i++) 2329ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043->gamma[i] = g[i]; 2339ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2349ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); 2359ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2369ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return count; 2379ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 2389ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2399ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR, 2409ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_vmirror_show, tpo_td043_vmirror_store); 2419ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, 2429ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_mode_show, tpo_td043_mode_store); 2439ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR, 2449ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_gamma_show, tpo_td043_gamma_store); 2459ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2469ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic struct attribute *tpo_td043_attrs[] = { 2479ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas &dev_attr_vmirror.attr, 2489ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas &dev_attr_mode.attr, 2499ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas &dev_attr_gamma.attr, 2509ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas NULL, 2519ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas}; 2529ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2539ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic struct attribute_group tpo_td043_attr_group = { 2549ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .attrs = tpo_td043_attrs, 2559ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas}; 2569ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2579ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic const struct omap_video_timings tpo_td043_timings = { 2589ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .x_res = 800, 2599ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .y_res = 480, 2609ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2619ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .pixel_clock = 36000, 2629ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2639ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .hsw = 1, 2649ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .hfp = 68, 2659ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .hbp = 214, 2669ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2679ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .vsw = 1, 2689ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .vfp = 39, 2699ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .vbp = 34, 2709ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas}; 2719ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2728df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotasstatic int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) 2739ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 2748df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas int nreset_gpio = tpo_td043->nreset_gpio; 2759ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2768df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas if (tpo_td043->powered_on) 27718016e35d448d35739f8640b51476709c07e95dbStanley.Miao return 0; 27818016e35d448d35739f8640b51476709c07e95dbStanley.Miao 2799ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas regulator_enable(tpo_td043->vcc_reg); 2809ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2818df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas /* wait for regulator to stabilize */ 2829ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas msleep(160); 2839ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2849ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (gpio_is_valid(nreset_gpio)) 2859ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas gpio_set_value(nreset_gpio, 1); 2869ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2879ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write(tpo_td043->spi, 2, 2889ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING); 2899ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_NORMAL); 2909ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write(tpo_td043->spi, 0x20, 0xf0); 2919ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write(tpo_td043->spi, 0x21, 0xf0); 2929ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, 2939ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043->vmirror); 2949ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); 2959ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 2968df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas tpo_td043->powered_on = 1; 2979ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return 0; 2989ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 2999ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 3008df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotasstatic void tpo_td043_power_off(struct tpo_td043_device *tpo_td043) 3019ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 3028df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas int nreset_gpio = tpo_td043->nreset_gpio; 3039ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 3048df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas if (!tpo_td043->powered_on) 30518016e35d448d35739f8640b51476709c07e95dbStanley.Miao return; 30618016e35d448d35739f8640b51476709c07e95dbStanley.Miao 3079ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write(tpo_td043->spi, 3, 3089ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM); 3099ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 3109ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (gpio_is_valid(nreset_gpio)) 3119ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas gpio_set_value(nreset_gpio, 0); 3129ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 3139ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas /* wait for at least 2 vsyncs before cutting off power */ 3149ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas msleep(50); 3159ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 3169ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_STANDBY); 3179ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 3189ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas regulator_disable(tpo_td043->vcc_reg); 3199ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 3208df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas tpo_td043->powered_on = 0; 3218df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas} 3228df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 3238df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotasstatic int tpo_td043_enable_dss(struct omap_dss_device *dssdev) 3248df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas{ 3258df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 3268df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas int r; 3278df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 3288df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 3298df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas return 0; 3308df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 3318df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas r = omapdss_dpi_display_enable(dssdev); 3328df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas if (r) 3338df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas goto err0; 3348df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 3358df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas if (dssdev->platform_enable) { 3368df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas r = dssdev->platform_enable(dssdev); 3378df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas if (r) 3388df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas goto err1; 3398df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas } 3408df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 3418df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas /* 3428df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas * If we are resuming from system suspend, SPI clocks might not be 3438df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas * enabled yet, so we'll program the LCD from SPI PM resume callback. 3448df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas */ 3458df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas if (!tpo_td043->spi_suspended) { 3468df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas r = tpo_td043_power_on(tpo_td043); 3478df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas if (r) 3488df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas goto err1; 3498df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas } 3508df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 3518df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 3528df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 3538df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas return 0; 3548df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotaserr1: 3558df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas omapdss_dpi_display_disable(dssdev); 3568df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotaserr0: 3578df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas return r; 3588df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas} 3598df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 3608df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotasstatic void tpo_td043_disable_dss(struct omap_dss_device *dssdev) 3618df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas{ 3628df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 3638df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 3648df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 3658df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas return; 3668df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 3679ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (dssdev->platform_disable) 3689ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dssdev->platform_disable(dssdev); 36937ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen 37037ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen omapdss_dpi_display_disable(dssdev); 3718df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 3728df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas if (!tpo_td043->spi_suspended) 3738df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas tpo_td043_power_off(tpo_td043); 37437ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen} 37537ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen 37637ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinenstatic int tpo_td043_enable(struct omap_dss_device *dssdev) 37737ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen{ 37837ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen dev_dbg(&dssdev->dev, "enable\n"); 37937ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen 3808df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas return tpo_td043_enable_dss(dssdev); 38137ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen} 38237ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen 38337ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinenstatic void tpo_td043_disable(struct omap_dss_device *dssdev) 38437ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen{ 38537ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen dev_dbg(&dssdev->dev, "disable\n"); 38637ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen 3878df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas tpo_td043_disable_dss(dssdev); 38837ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen 38937ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 3909ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 3919ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 3929ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic int tpo_td043_suspend(struct omap_dss_device *dssdev) 3939ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 3948df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas dev_dbg(&dssdev->dev, "suspend\n"); 3958df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 3968df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas tpo_td043_disable_dss(dssdev); 3978df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 39837ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; 3998df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 4009ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return 0; 4019ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 4029ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4039ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic int tpo_td043_resume(struct omap_dss_device *dssdev) 4049ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 4058df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas dev_dbg(&dssdev->dev, "resume\n"); 40637ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen 4078df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas return tpo_td043_enable_dss(dssdev); 4089ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 4099ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4109ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic int tpo_td043_probe(struct omap_dss_device *dssdev) 4119ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 4129ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 4139ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas int nreset_gpio = dssdev->reset_gpio; 4149ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas int ret = 0; 4159ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4169ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dev_dbg(&dssdev->dev, "probe\n"); 4179ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4189ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (tpo_td043 == NULL) { 4199ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dev_err(&dssdev->dev, "missing tpo_td043_device\n"); 4209ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return -ENODEV; 4219ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas } 4229ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4239ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS | 4249ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IPC; 4259ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dssdev->panel.timings = tpo_td043_timings; 4269ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dssdev->ctrl.pixel_size = 24; 4279ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4289ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043->mode = TPO_R02_MODE_800x480; 4299ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma)); 4309ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4319ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043->vcc_reg = regulator_get(&dssdev->dev, "vcc"); 4329ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (IS_ERR(tpo_td043->vcc_reg)) { 4339ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dev_err(&dssdev->dev, "failed to get LCD VCC regulator\n"); 4349ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas ret = PTR_ERR(tpo_td043->vcc_reg); 4359ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas goto fail_regulator; 4369ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas } 4379ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4389ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (gpio_is_valid(nreset_gpio)) { 439f8bd493456c3da372ae81ed8f6b903f6207b9d98Jingoo Han ret = gpio_request_one(nreset_gpio, GPIOF_OUT_INIT_LOW, 440f8bd493456c3da372ae81ed8f6b903f6207b9d98Jingoo Han "lcd reset"); 4419ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (ret < 0) { 4429ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dev_err(&dssdev->dev, "couldn't request reset GPIO\n"); 4439ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas goto fail_gpio_req; 4449ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas } 4459ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas } 4469ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4479ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group); 4489ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (ret) 4499ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dev_warn(&dssdev->dev, "failed to create sysfs files\n"); 4509ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4519ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return 0; 4529ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4539ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasfail_gpio_req: 4549ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas regulator_put(tpo_td043->vcc_reg); 4559ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasfail_regulator: 4569ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas kfree(tpo_td043); 4579ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return ret; 4589ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 4599ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4609ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic void tpo_td043_remove(struct omap_dss_device *dssdev) 4619ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 4629ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 4639ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas int nreset_gpio = dssdev->reset_gpio; 4649ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4659ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dev_dbg(&dssdev->dev, "remove\n"); 4669ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4679ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group); 4689ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas regulator_put(tpo_td043->vcc_reg); 4699ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (gpio_is_valid(nreset_gpio)) 4709ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas gpio_free(nreset_gpio); 4719ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 4729ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4739ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic struct omap_dss_driver tpo_td043_driver = { 4749ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .probe = tpo_td043_probe, 4759ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .remove = tpo_td043_remove, 4769ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4779ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .enable = tpo_td043_enable, 4789ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .disable = tpo_td043_disable, 4799ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .suspend = tpo_td043_suspend, 4809ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .resume = tpo_td043_resume, 4819ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .set_mirror = tpo_td043_set_hmirror, 4829ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .get_mirror = tpo_td043_get_hmirror, 4839ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4849ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .driver = { 4859ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .name = "tpo_td043mtea1_panel", 4869ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .owner = THIS_MODULE, 4879ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas }, 4889ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas}; 4899ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4909ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic int tpo_td043_spi_probe(struct spi_device *spi) 4919ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 4929ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct omap_dss_device *dssdev = spi->dev.platform_data; 4939ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct tpo_td043_device *tpo_td043; 4949ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas int ret; 4959ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 4969ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (dssdev == NULL) { 4979ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dev_err(&spi->dev, "missing dssdev\n"); 4989ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return -ENODEV; 4999ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas } 5009ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 5019ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas spi->bits_per_word = 16; 5029ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas spi->mode = SPI_MODE_0; 5039ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 5049ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas ret = spi_setup(spi); 5059ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (ret < 0) { 5069ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dev_err(&spi->dev, "spi_setup failed: %d\n", ret); 5079ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return ret; 5089ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas } 5099ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 5109ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043 = kzalloc(sizeof(*tpo_td043), GFP_KERNEL); 5119ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas if (tpo_td043 == NULL) 5129ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return -ENOMEM; 5139ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 5149ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas tpo_td043->spi = spi; 5158df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas tpo_td043->nreset_gpio = dssdev->reset_gpio; 5169ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dev_set_drvdata(&spi->dev, tpo_td043); 5179ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas dev_set_drvdata(&dssdev->dev, tpo_td043); 5189ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 5199ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas omap_dss_register_driver(&tpo_td043_driver); 5209ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 5219ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return 0; 5229ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 5239ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 5249ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic int __devexit tpo_td043_spi_remove(struct spi_device *spi) 5259ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas{ 5269ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev); 5279ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 5289ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas omap_dss_unregister_driver(&tpo_td043_driver); 5299ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas kfree(tpo_td043); 5309ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 5319ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas return 0; 5329ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas} 5339ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 5348df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas#ifdef CONFIG_PM_SLEEP 5358df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotasstatic int tpo_td043_spi_suspend(struct device *dev) 5368df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas{ 5378df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); 5388df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 5398df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", tpo_td043); 5408df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 5418df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas tpo_td043->power_on_resume = tpo_td043->powered_on; 5428df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas tpo_td043_power_off(tpo_td043); 5438df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas tpo_td043->spi_suspended = 1; 5448df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 5458df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas return 0; 5468df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas} 5478df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 5488df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotasstatic int tpo_td043_spi_resume(struct device *dev) 5498df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas{ 5508df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); 5518df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas int ret; 5528df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 5538df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas dev_dbg(dev, "tpo_td043_spi_resume\n"); 5548df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 5558df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas if (tpo_td043->power_on_resume) { 5568df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas ret = tpo_td043_power_on(tpo_td043); 5578df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas if (ret) 5588df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas return ret; 5598df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas } 5608df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas tpo_td043->spi_suspended = 0; 5618df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 5628df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas return 0; 5638df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas} 5648df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas#endif 5658df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 5668df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotasstatic SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm, 5678df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas tpo_td043_spi_suspend, tpo_td043_spi_resume); 5688df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas 5699ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotasstatic struct spi_driver tpo_td043_spi_driver = { 5709ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .driver = { 5719ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .name = "tpo_td043mtea1_panel_spi", 5729ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .owner = THIS_MODULE, 5738df4f5ce64e9dc986570799f94c8850f57f8ced9Grazvydas Ignotas .pm = &tpo_td043_spi_pm, 5749ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas }, 5759ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .probe = tpo_td043_spi_probe, 5769ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas .remove = __devexit_p(tpo_td043_spi_remove), 5779ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas}; 5789ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 579c6d242aa64d27ebd258a12aa0a5da068e25e01f5Axel Linmodule_spi_driver(tpo_td043_spi_driver); 5809ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas Ignotas 5819ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas IgnotasMODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>"); 5829ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas IgnotasMODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver"); 5839ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59Grazvydas IgnotasMODULE_LICENSE("GPL"); 584