0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/delay.h>
0013 #include <linux/module.h>
0014 #include <linux/regulator/consumer.h>
0015 #include <linux/spi/spi.h>
0016
0017 #include <drm/drm_connector.h>
0018 #include <drm/drm_modes.h>
0019 #include <drm/drm_panel.h>
0020
0021 #define TPO_R02_MODE(x) ((x) & 7)
0022 #define TPO_R02_MODE_800x480 7
0023 #define TPO_R02_NCLK_RISING BIT(3)
0024 #define TPO_R02_HSYNC_HIGH BIT(4)
0025 #define TPO_R02_VSYNC_HIGH BIT(5)
0026
0027 #define TPO_R03_NSTANDBY BIT(0)
0028 #define TPO_R03_EN_CP_CLK BIT(1)
0029 #define TPO_R03_EN_VGL_PUMP BIT(2)
0030 #define TPO_R03_EN_PWM BIT(3)
0031 #define TPO_R03_DRIVING_CAP_100 BIT(4)
0032 #define TPO_R03_EN_PRE_CHARGE BIT(6)
0033 #define TPO_R03_SOFTWARE_CTL BIT(7)
0034
0035 #define TPO_R04_NFLIP_H BIT(0)
0036 #define TPO_R04_NFLIP_V BIT(1)
0037 #define TPO_R04_CP_CLK_FREQ_1H BIT(2)
0038 #define TPO_R04_VGL_FREQ_1H BIT(4)
0039
0040 #define TPO_R03_VAL_NORMAL \
0041 (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | TPO_R03_EN_VGL_PUMP | \
0042 TPO_R03_EN_PWM | TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
0043 TPO_R03_SOFTWARE_CTL)
0044
0045 #define TPO_R03_VAL_STANDBY \
0046 (TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
0047 TPO_R03_SOFTWARE_CTL)
0048
0049 static const u16 td043mtea1_def_gamma[12] = {
0050 105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023
0051 };
0052
0053 struct td043mtea1_panel {
0054 struct drm_panel panel;
0055
0056 struct spi_device *spi;
0057 struct regulator *vcc_reg;
0058 struct gpio_desc *reset_gpio;
0059
0060 unsigned int mode;
0061 u16 gamma[12];
0062 bool vmirror;
0063 bool powered_on;
0064 bool spi_suspended;
0065 bool power_on_resume;
0066 };
0067
0068 #define to_td043mtea1_device(p) container_of(p, struct td043mtea1_panel, panel)
0069
0070
0071
0072
0073
0074 static int td043mtea1_write(struct td043mtea1_panel *lcd, u8 addr, u8 value)
0075 {
0076 struct spi_message msg;
0077 struct spi_transfer xfer;
0078 u16 data;
0079 int ret;
0080
0081 spi_message_init(&msg);
0082
0083 memset(&xfer, 0, sizeof(xfer));
0084
0085 data = ((u16)addr << 10) | (1 << 8) | value;
0086 xfer.tx_buf = &data;
0087 xfer.bits_per_word = 16;
0088 xfer.len = 2;
0089 spi_message_add_tail(&xfer, &msg);
0090
0091 ret = spi_sync(lcd->spi, &msg);
0092 if (ret < 0)
0093 dev_warn(&lcd->spi->dev, "failed to write to LCD reg (%d)\n",
0094 ret);
0095
0096 return ret;
0097 }
0098
0099 static void td043mtea1_write_gamma(struct td043mtea1_panel *lcd)
0100 {
0101 const u16 *gamma = lcd->gamma;
0102 unsigned int i;
0103 u8 val;
0104
0105
0106 for (val = i = 0; i < 4; i++)
0107 val |= (gamma[i] & 0x300) >> ((i + 1) * 2);
0108 td043mtea1_write(lcd, 0x11, val);
0109
0110 for (val = i = 0; i < 4; i++)
0111 val |= (gamma[i + 4] & 0x300) >> ((i + 1) * 2);
0112 td043mtea1_write(lcd, 0x12, val);
0113
0114 for (val = i = 0; i < 4; i++)
0115 val |= (gamma[i + 8] & 0x300) >> ((i + 1) * 2);
0116 td043mtea1_write(lcd, 0x13, val);
0117
0118
0119 for (i = 0; i < 12; i++)
0120 td043mtea1_write(lcd, 0x14 + i, gamma[i] & 0xff);
0121 }
0122
0123 static int td043mtea1_write_mirror(struct td043mtea1_panel *lcd)
0124 {
0125 u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V |
0126 TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H;
0127 if (lcd->vmirror)
0128 reg4 &= ~TPO_R04_NFLIP_V;
0129
0130 return td043mtea1_write(lcd, 4, reg4);
0131 }
0132
0133 static int td043mtea1_power_on(struct td043mtea1_panel *lcd)
0134 {
0135 int ret;
0136
0137 if (lcd->powered_on)
0138 return 0;
0139
0140 ret = regulator_enable(lcd->vcc_reg);
0141 if (ret < 0)
0142 return ret;
0143
0144
0145 msleep(160);
0146
0147 gpiod_set_value(lcd->reset_gpio, 0);
0148
0149 td043mtea1_write(lcd, 2, TPO_R02_MODE(lcd->mode) | TPO_R02_NCLK_RISING);
0150 td043mtea1_write(lcd, 3, TPO_R03_VAL_NORMAL);
0151 td043mtea1_write(lcd, 0x20, 0xf0);
0152 td043mtea1_write(lcd, 0x21, 0xf0);
0153 td043mtea1_write_mirror(lcd);
0154 td043mtea1_write_gamma(lcd);
0155
0156 lcd->powered_on = true;
0157
0158 return 0;
0159 }
0160
0161 static void td043mtea1_power_off(struct td043mtea1_panel *lcd)
0162 {
0163 if (!lcd->powered_on)
0164 return;
0165
0166 td043mtea1_write(lcd, 3, TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);
0167
0168 gpiod_set_value(lcd->reset_gpio, 1);
0169
0170
0171 msleep(50);
0172
0173 td043mtea1_write(lcd, 3, TPO_R03_VAL_STANDBY);
0174
0175 regulator_disable(lcd->vcc_reg);
0176
0177 lcd->powered_on = false;
0178 }
0179
0180
0181
0182
0183
0184 static ssize_t vmirror_show(struct device *dev, struct device_attribute *attr,
0185 char *buf)
0186 {
0187 struct td043mtea1_panel *lcd = dev_get_drvdata(dev);
0188
0189 return sysfs_emit(buf, "%d\n", lcd->vmirror);
0190 }
0191
0192 static ssize_t vmirror_store(struct device *dev, struct device_attribute *attr,
0193 const char *buf, size_t count)
0194 {
0195 struct td043mtea1_panel *lcd = dev_get_drvdata(dev);
0196 int val;
0197 int ret;
0198
0199 ret = kstrtoint(buf, 0, &val);
0200 if (ret < 0)
0201 return ret;
0202
0203 lcd->vmirror = !!val;
0204
0205 ret = td043mtea1_write_mirror(lcd);
0206 if (ret < 0)
0207 return ret;
0208
0209 return count;
0210 }
0211
0212 static ssize_t mode_show(struct device *dev, struct device_attribute *attr,
0213 char *buf)
0214 {
0215 struct td043mtea1_panel *lcd = dev_get_drvdata(dev);
0216
0217 return sysfs_emit(buf, "%d\n", lcd->mode);
0218 }
0219
0220 static ssize_t mode_store(struct device *dev, struct device_attribute *attr,
0221 const char *buf, size_t count)
0222 {
0223 struct td043mtea1_panel *lcd = dev_get_drvdata(dev);
0224 long val;
0225 int ret;
0226
0227 ret = kstrtol(buf, 0, &val);
0228 if (ret != 0 || val & ~7)
0229 return -EINVAL;
0230
0231 lcd->mode = val;
0232
0233 val |= TPO_R02_NCLK_RISING;
0234 td043mtea1_write(lcd, 2, val);
0235
0236 return count;
0237 }
0238
0239 static ssize_t gamma_show(struct device *dev, struct device_attribute *attr,
0240 char *buf)
0241 {
0242 struct td043mtea1_panel *lcd = dev_get_drvdata(dev);
0243 ssize_t len = 0;
0244 unsigned int i;
0245 int ret;
0246
0247 for (i = 0; i < ARRAY_SIZE(lcd->gamma); i++) {
0248 ret = snprintf(buf + len, PAGE_SIZE - len, "%u ",
0249 lcd->gamma[i]);
0250 if (ret < 0)
0251 return ret;
0252 len += ret;
0253 }
0254 buf[len - 1] = '\n';
0255
0256 return len;
0257 }
0258
0259 static ssize_t gamma_store(struct device *dev, struct device_attribute *attr,
0260 const char *buf, size_t count)
0261 {
0262 struct td043mtea1_panel *lcd = dev_get_drvdata(dev);
0263 unsigned int g[12];
0264 unsigned int i;
0265 int ret;
0266
0267 ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u",
0268 &g[0], &g[1], &g[2], &g[3], &g[4], &g[5],
0269 &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]);
0270 if (ret != 12)
0271 return -EINVAL;
0272
0273 for (i = 0; i < 12; i++)
0274 lcd->gamma[i] = g[i];
0275
0276 td043mtea1_write_gamma(lcd);
0277
0278 return count;
0279 }
0280
0281 static DEVICE_ATTR_RW(vmirror);
0282 static DEVICE_ATTR_RW(mode);
0283 static DEVICE_ATTR_RW(gamma);
0284
0285 static struct attribute *td043mtea1_attrs[] = {
0286 &dev_attr_vmirror.attr,
0287 &dev_attr_mode.attr,
0288 &dev_attr_gamma.attr,
0289 NULL,
0290 };
0291
0292 static const struct attribute_group td043mtea1_attr_group = {
0293 .attrs = td043mtea1_attrs,
0294 };
0295
0296
0297
0298
0299
0300 static int td043mtea1_unprepare(struct drm_panel *panel)
0301 {
0302 struct td043mtea1_panel *lcd = to_td043mtea1_device(panel);
0303
0304 if (!lcd->spi_suspended)
0305 td043mtea1_power_off(lcd);
0306
0307 return 0;
0308 }
0309
0310 static int td043mtea1_prepare(struct drm_panel *panel)
0311 {
0312 struct td043mtea1_panel *lcd = to_td043mtea1_device(panel);
0313 int ret;
0314
0315
0316
0317
0318
0319 if (lcd->spi_suspended)
0320 return 0;
0321
0322 ret = td043mtea1_power_on(lcd);
0323 if (ret) {
0324 dev_err(&lcd->spi->dev, "%s: power on failed (%d)\n",
0325 __func__, ret);
0326 return ret;
0327 }
0328
0329 return 0;
0330 }
0331
0332 static const struct drm_display_mode td043mtea1_mode = {
0333 .clock = 36000,
0334 .hdisplay = 800,
0335 .hsync_start = 800 + 68,
0336 .hsync_end = 800 + 68 + 1,
0337 .htotal = 800 + 68 + 1 + 214,
0338 .vdisplay = 480,
0339 .vsync_start = 480 + 39,
0340 .vsync_end = 480 + 39 + 1,
0341 .vtotal = 480 + 39 + 1 + 34,
0342 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
0343 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
0344 .width_mm = 94,
0345 .height_mm = 56,
0346 };
0347
0348 static int td043mtea1_get_modes(struct drm_panel *panel,
0349 struct drm_connector *connector)
0350 {
0351 struct drm_display_mode *mode;
0352
0353 mode = drm_mode_duplicate(connector->dev, &td043mtea1_mode);
0354 if (!mode)
0355 return -ENOMEM;
0356
0357 drm_mode_set_name(mode);
0358 drm_mode_probed_add(connector, mode);
0359
0360 connector->display_info.width_mm = td043mtea1_mode.width_mm;
0361 connector->display_info.height_mm = td043mtea1_mode.height_mm;
0362
0363
0364
0365
0366
0367
0368 connector->display_info.bus_flags = DRM_BUS_FLAG_DE_HIGH
0369 | DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE
0370 | DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE;
0371
0372 return 1;
0373 }
0374
0375 static const struct drm_panel_funcs td043mtea1_funcs = {
0376 .unprepare = td043mtea1_unprepare,
0377 .prepare = td043mtea1_prepare,
0378 .get_modes = td043mtea1_get_modes,
0379 };
0380
0381
0382
0383
0384
0385 static int __maybe_unused td043mtea1_suspend(struct device *dev)
0386 {
0387 struct td043mtea1_panel *lcd = dev_get_drvdata(dev);
0388
0389 if (lcd->powered_on) {
0390 td043mtea1_power_off(lcd);
0391 lcd->powered_on = true;
0392 }
0393
0394 lcd->spi_suspended = true;
0395
0396 return 0;
0397 }
0398
0399 static int __maybe_unused td043mtea1_resume(struct device *dev)
0400 {
0401 struct td043mtea1_panel *lcd = dev_get_drvdata(dev);
0402 int ret;
0403
0404 lcd->spi_suspended = false;
0405
0406 if (lcd->powered_on) {
0407 lcd->powered_on = false;
0408 ret = td043mtea1_power_on(lcd);
0409 if (ret)
0410 return ret;
0411 }
0412
0413 return 0;
0414 }
0415
0416 static SIMPLE_DEV_PM_OPS(td043mtea1_pm_ops, td043mtea1_suspend,
0417 td043mtea1_resume);
0418
0419 static int td043mtea1_probe(struct spi_device *spi)
0420 {
0421 struct td043mtea1_panel *lcd;
0422 int ret;
0423
0424 lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL);
0425 if (lcd == NULL)
0426 return -ENOMEM;
0427
0428 spi_set_drvdata(spi, lcd);
0429 lcd->spi = spi;
0430 lcd->mode = TPO_R02_MODE_800x480;
0431 memcpy(lcd->gamma, td043mtea1_def_gamma, sizeof(lcd->gamma));
0432
0433 lcd->vcc_reg = devm_regulator_get(&spi->dev, "vcc");
0434 if (IS_ERR(lcd->vcc_reg))
0435 return dev_err_probe(&spi->dev, PTR_ERR(lcd->vcc_reg),
0436 "failed to get VCC regulator\n");
0437
0438 lcd->reset_gpio = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_HIGH);
0439 if (IS_ERR(lcd->reset_gpio))
0440 return dev_err_probe(&spi->dev, PTR_ERR(lcd->reset_gpio),
0441 "failed to get reset GPIO\n");
0442
0443 spi->bits_per_word = 16;
0444 spi->mode = SPI_MODE_0;
0445
0446 ret = spi_setup(spi);
0447 if (ret < 0) {
0448 dev_err(&spi->dev, "failed to setup SPI: %d\n", ret);
0449 return ret;
0450 }
0451
0452 ret = sysfs_create_group(&spi->dev.kobj, &td043mtea1_attr_group);
0453 if (ret < 0) {
0454 dev_err(&spi->dev, "failed to create sysfs files\n");
0455 return ret;
0456 }
0457
0458 drm_panel_init(&lcd->panel, &lcd->spi->dev, &td043mtea1_funcs,
0459 DRM_MODE_CONNECTOR_DPI);
0460
0461 drm_panel_add(&lcd->panel);
0462
0463 return 0;
0464 }
0465
0466 static void td043mtea1_remove(struct spi_device *spi)
0467 {
0468 struct td043mtea1_panel *lcd = spi_get_drvdata(spi);
0469
0470 drm_panel_remove(&lcd->panel);
0471 drm_panel_disable(&lcd->panel);
0472 drm_panel_unprepare(&lcd->panel);
0473
0474 sysfs_remove_group(&spi->dev.kobj, &td043mtea1_attr_group);
0475 }
0476
0477 static const struct of_device_id td043mtea1_of_match[] = {
0478 { .compatible = "tpo,td043mtea1", },
0479 { },
0480 };
0481
0482 MODULE_DEVICE_TABLE(of, td043mtea1_of_match);
0483
0484 static const struct spi_device_id td043mtea1_ids[] = {
0485 { "td043mtea1", 0 },
0486 { }
0487 };
0488
0489 MODULE_DEVICE_TABLE(spi, td043mtea1_ids);
0490
0491 static struct spi_driver td043mtea1_driver = {
0492 .probe = td043mtea1_probe,
0493 .remove = td043mtea1_remove,
0494 .id_table = td043mtea1_ids,
0495 .driver = {
0496 .name = "panel-tpo-td043mtea1",
0497 .pm = &td043mtea1_pm_ops,
0498 .of_match_table = td043mtea1_of_match,
0499 },
0500 };
0501
0502 module_spi_driver(td043mtea1_driver);
0503
0504 MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
0505 MODULE_DESCRIPTION("TPO TD043MTEA1 Panel Driver");
0506 MODULE_LICENSE("GPL");