1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Innolux/Chimei EJ030NA TFT LCD panel driver 4 * 5 * Copyright (C) 2020, Paul Cercueil <paul@crapouillou.net> 6 * Copyright (C) 2020, Christophe Branchereau <cbranchereau@gmail.com> 7 */ 8 9 #include <linux/delay.h> 10 #include <linux/device.h> 11 #include <linux/gpio/consumer.h> 12 #include <linux/media-bus-format.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/platform_device.h> 16 #include <linux/regmap.h> 17 #include <linux/regulator/consumer.h> 18 #include <linux/spi/spi.h> 19 20 #include <drm/drm_modes.h> 21 #include <drm/drm_panel.h> 22 23 struct ej030na_info { 24 const struct drm_display_mode *display_modes; 25 unsigned int num_modes; 26 u16 width_mm, height_mm; 27 u32 bus_format, bus_flags; 28 }; 29 30 struct ej030na { 31 struct drm_panel panel; 32 struct spi_device *spi; 33 struct regmap *map; 34 35 const struct ej030na_info *panel_info; 36 37 struct regulator *supply; 38 struct gpio_desc *reset_gpio; 39 }; 40 41 static inline struct ej030na *to_ej030na(struct drm_panel *panel) 42 { 43 return container_of(panel, struct ej030na, panel); 44 } 45 46 static const struct reg_sequence ej030na_init_sequence[] = { 47 { 0x05, 0x1e }, 48 { 0x05, 0x5c }, 49 { 0x02, 0x14 }, 50 { 0x03, 0x40 }, 51 { 0x04, 0x07 }, 52 { 0x06, 0x12 }, 53 { 0x07, 0xd2 }, 54 { 0x0c, 0x06 }, 55 { 0x0d, 0x40 }, 56 { 0x0e, 0x40 }, 57 { 0x0f, 0x40 }, 58 { 0x10, 0x40 }, 59 { 0x11, 0x40 }, 60 { 0x2f, 0x40 }, 61 { 0x5a, 0x02 }, 62 63 { 0x30, 0x07 }, 64 { 0x31, 0x57 }, 65 { 0x32, 0x53 }, 66 { 0x33, 0x77 }, 67 { 0x34, 0xb8 }, 68 { 0x35, 0xbd }, 69 { 0x36, 0xb8 }, 70 { 0x37, 0xe7 }, 71 { 0x38, 0x04 }, 72 { 0x39, 0xff }, 73 74 { 0x40, 0x0b }, 75 { 0x41, 0xb8 }, 76 { 0x42, 0xab }, 77 { 0x43, 0xb9 }, 78 { 0x44, 0x6a }, 79 { 0x45, 0x56 }, 80 { 0x46, 0x61 }, 81 { 0x47, 0x08 }, 82 { 0x48, 0x0f }, 83 { 0x49, 0x0f }, 84 }; 85 86 static int ej030na_prepare(struct drm_panel *panel) 87 { 88 struct ej030na *priv = to_ej030na(panel); 89 struct device *dev = &priv->spi->dev; 90 int err; 91 92 err = regulator_enable(priv->supply); 93 if (err) { 94 dev_err(dev, "Failed to enable power supply: %d\n", err); 95 return err; 96 } 97 98 /* Reset the chip */ 99 gpiod_set_value_cansleep(priv->reset_gpio, 1); 100 usleep_range(50, 150); 101 gpiod_set_value_cansleep(priv->reset_gpio, 0); 102 usleep_range(50, 150); 103 104 err = regmap_multi_reg_write(priv->map, ej030na_init_sequence, 105 ARRAY_SIZE(ej030na_init_sequence)); 106 if (err) { 107 dev_err(dev, "Failed to init registers: %d\n", err); 108 goto err_disable_regulator; 109 } 110 111 return 0; 112 113 err_disable_regulator: 114 regulator_disable(priv->supply); 115 return err; 116 } 117 118 static int ej030na_unprepare(struct drm_panel *panel) 119 { 120 struct ej030na *priv = to_ej030na(panel); 121 122 gpiod_set_value_cansleep(priv->reset_gpio, 1); 123 regulator_disable(priv->supply); 124 125 return 0; 126 } 127 128 static int ej030na_enable(struct drm_panel *panel) 129 { 130 struct ej030na *priv = to_ej030na(panel); 131 132 /* standby off */ 133 regmap_write(priv->map, 0x2b, 0x01); 134 135 if (panel->backlight) { 136 /* Wait for the picture to be ready before enabling backlight */ 137 msleep(120); 138 } 139 140 return 0; 141 } 142 143 static int ej030na_disable(struct drm_panel *panel) 144 { 145 struct ej030na *priv = to_ej030na(panel); 146 147 /* standby on */ 148 regmap_write(priv->map, 0x2b, 0x00); 149 150 return 0; 151 } 152 153 static int ej030na_get_modes(struct drm_panel *panel, 154 struct drm_connector *connector) 155 { 156 struct ej030na *priv = to_ej030na(panel); 157 const struct ej030na_info *panel_info = priv->panel_info; 158 struct drm_display_mode *mode; 159 unsigned int i; 160 161 for (i = 0; i < panel_info->num_modes; i++) { 162 mode = drm_mode_duplicate(connector->dev, 163 &panel_info->display_modes[i]); 164 if (!mode) 165 return -ENOMEM; 166 167 drm_mode_set_name(mode); 168 169 mode->type = DRM_MODE_TYPE_DRIVER; 170 if (panel_info->num_modes == 1) 171 mode->type |= DRM_MODE_TYPE_PREFERRED; 172 173 drm_mode_probed_add(connector, mode); 174 } 175 176 connector->display_info.bpc = 8; 177 connector->display_info.width_mm = panel_info->width_mm; 178 connector->display_info.height_mm = panel_info->height_mm; 179 180 drm_display_info_set_bus_formats(&connector->display_info, 181 &panel_info->bus_format, 1); 182 connector->display_info.bus_flags = panel_info->bus_flags; 183 184 return panel_info->num_modes; 185 } 186 187 static const struct drm_panel_funcs ej030na_funcs = { 188 .prepare = ej030na_prepare, 189 .unprepare = ej030na_unprepare, 190 .enable = ej030na_enable, 191 .disable = ej030na_disable, 192 .get_modes = ej030na_get_modes, 193 }; 194 195 static const struct regmap_config ej030na_regmap_config = { 196 .reg_bits = 8, 197 .val_bits = 8, 198 .max_register = 0x5a, 199 }; 200 201 static int ej030na_probe(struct spi_device *spi) 202 { 203 struct device *dev = &spi->dev; 204 struct ej030na *priv; 205 int err; 206 207 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 208 if (!priv) 209 return -ENOMEM; 210 211 priv->spi = spi; 212 spi_set_drvdata(spi, priv); 213 214 priv->map = devm_regmap_init_spi(spi, &ej030na_regmap_config); 215 if (IS_ERR(priv->map)) { 216 dev_err(dev, "Unable to init regmap\n"); 217 return PTR_ERR(priv->map); 218 } 219 220 priv->panel_info = of_device_get_match_data(dev); 221 if (!priv->panel_info) 222 return -EINVAL; 223 224 priv->supply = devm_regulator_get(dev, "power"); 225 if (IS_ERR(priv->supply)) 226 return dev_err_probe(dev, PTR_ERR(priv->supply), 227 "Failed to get power supply\n"); 228 229 priv->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); 230 if (IS_ERR(priv->reset_gpio)) 231 return dev_err_probe(dev, PTR_ERR(priv->reset_gpio), 232 "Failed to get reset GPIO\n"); 233 234 drm_panel_init(&priv->panel, dev, &ej030na_funcs, 235 DRM_MODE_CONNECTOR_DPI); 236 237 err = drm_panel_of_backlight(&priv->panel); 238 if (err) 239 return err; 240 241 drm_panel_add(&priv->panel); 242 243 return 0; 244 } 245 246 static void ej030na_remove(struct spi_device *spi) 247 { 248 struct ej030na *priv = spi_get_drvdata(spi); 249 250 drm_panel_remove(&priv->panel); 251 drm_panel_disable(&priv->panel); 252 drm_panel_unprepare(&priv->panel); 253 } 254 255 static const struct drm_display_mode ej030na_modes[] = { 256 { /* 60 Hz */ 257 .clock = 14400, 258 .hdisplay = 320, 259 .hsync_start = 320 + 10, 260 .hsync_end = 320 + 10 + 37, 261 .htotal = 320 + 10 + 37 + 33, 262 .vdisplay = 480, 263 .vsync_start = 480 + 102, 264 .vsync_end = 480 + 102 + 9 + 9, 265 .vtotal = 480 + 102 + 9 + 9, 266 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 267 }, 268 { /* 50 Hz */ 269 .clock = 12000, 270 .hdisplay = 320, 271 .hsync_start = 320 + 10, 272 .hsync_end = 320 + 10 + 37, 273 .htotal = 320 + 10 + 37 + 33, 274 .vdisplay = 480, 275 .vsync_start = 480 + 102, 276 .vsync_end = 480 + 102 + 9, 277 .vtotal = 480 + 102 + 9 + 9, 278 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 279 }, 280 }; 281 282 static const struct ej030na_info ej030na_info = { 283 .display_modes = ej030na_modes, 284 .num_modes = ARRAY_SIZE(ej030na_modes), 285 .width_mm = 70, 286 .height_mm = 51, 287 .bus_format = MEDIA_BUS_FMT_RGB888_3X8_DELTA, 288 .bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE | DRM_BUS_FLAG_DE_LOW, 289 }; 290 291 static const struct of_device_id ej030na_of_match[] = { 292 { .compatible = "innolux,ej030na", .data = &ej030na_info }, 293 { /* sentinel */ } 294 }; 295 MODULE_DEVICE_TABLE(of, ej030na_of_match); 296 297 static struct spi_driver ej030na_driver = { 298 .driver = { 299 .name = "panel-innolux-ej030na", 300 .of_match_table = ej030na_of_match, 301 }, 302 .probe = ej030na_probe, 303 .remove = ej030na_remove, 304 }; 305 module_spi_driver(ej030na_driver); 306 307 MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>"); 308 MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>"); 309 MODULE_LICENSE("GPL v2"); 310