1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Mantix MLAF057WE51 5.7" MIPI-DSI panel driver 4 * 5 * Copyright (C) Purism SPC 2020 6 */ 7 8 #include <linux/backlight.h> 9 #include <linux/delay.h> 10 #include <linux/gpio/consumer.h> 11 #include <linux/module.h> 12 #include <linux/of_device.h> 13 #include <linux/regulator/consumer.h> 14 15 #include <video/mipi_display.h> 16 17 #include <drm/drm_mipi_dsi.h> 18 #include <drm/drm_modes.h> 19 #include <drm/drm_panel.h> 20 21 #define DRV_NAME "panel-mantix-mlaf057we51" 22 23 /* Manufacturer specific Commands send via DSI */ 24 #define MANTIX_CMD_OTP_STOP_RELOAD_MIPI 0x41 25 #define MANTIX_CMD_INT_CANCEL 0x4C 26 #define MANTIX_CMD_SPI_FINISH 0x90 27 28 struct mantix { 29 struct device *dev; 30 struct drm_panel panel; 31 32 struct gpio_desc *reset_gpio; 33 struct gpio_desc *tp_rstn_gpio; 34 35 struct regulator *avdd; 36 struct regulator *avee; 37 struct regulator *vddi; 38 39 const struct drm_display_mode *default_mode; 40 }; 41 42 static inline struct mantix *panel_to_mantix(struct drm_panel *panel) 43 { 44 return container_of(panel, struct mantix, panel); 45 } 46 47 #define dsi_generic_write_seq(dsi, seq...) do { \ 48 static const u8 d[] = { seq }; \ 49 int ret; \ 50 ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \ 51 if (ret < 0) \ 52 return ret; \ 53 } while (0) 54 55 static int mantix_init_sequence(struct mantix *ctx) 56 { 57 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 58 struct device *dev = ctx->dev; 59 60 /* 61 * Init sequence was supplied by the panel vendor. 62 */ 63 dsi_generic_write_seq(dsi, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5A); 64 65 dsi_generic_write_seq(dsi, MANTIX_CMD_INT_CANCEL, 0x03); 66 dsi_generic_write_seq(dsi, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5A, 0x03); 67 dsi_generic_write_seq(dsi, 0x80, 0xA9, 0x00); 68 69 dsi_generic_write_seq(dsi, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5A, 0x09); 70 dsi_generic_write_seq(dsi, 0x80, 0x64, 0x00, 0x64, 0x00, 0x00); 71 msleep(20); 72 73 dsi_generic_write_seq(dsi, MANTIX_CMD_SPI_FINISH, 0xA5); 74 dsi_generic_write_seq(dsi, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x00, 0x2F); 75 msleep(20); 76 77 dev_dbg(dev, "Panel init sequence done\n"); 78 return 0; 79 } 80 81 static int mantix_enable(struct drm_panel *panel) 82 { 83 struct mantix *ctx = panel_to_mantix(panel); 84 struct device *dev = ctx->dev; 85 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 86 int ret; 87 88 ret = mantix_init_sequence(ctx); 89 if (ret < 0) { 90 dev_err(ctx->dev, "Panel init sequence failed: %d\n", ret); 91 return ret; 92 } 93 94 ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 95 if (ret < 0) { 96 dev_err(dev, "Failed to exit sleep mode\n"); 97 return ret; 98 } 99 msleep(20); 100 101 ret = mipi_dsi_dcs_set_display_on(dsi); 102 if (ret) 103 return ret; 104 usleep_range(10000, 12000); 105 106 ret = mipi_dsi_turn_on_peripheral(dsi); 107 if (ret < 0) { 108 dev_err(dev, "Failed to turn on peripheral\n"); 109 return ret; 110 } 111 112 return 0; 113 } 114 115 static int mantix_disable(struct drm_panel *panel) 116 { 117 struct mantix *ctx = panel_to_mantix(panel); 118 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 119 int ret; 120 121 ret = mipi_dsi_dcs_set_display_off(dsi); 122 if (ret < 0) 123 dev_err(ctx->dev, "Failed to turn off the display: %d\n", ret); 124 125 ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 126 if (ret < 0) 127 dev_err(ctx->dev, "Failed to enter sleep mode: %d\n", ret); 128 129 130 return 0; 131 } 132 133 static int mantix_unprepare(struct drm_panel *panel) 134 { 135 struct mantix *ctx = panel_to_mantix(panel); 136 137 gpiod_set_value_cansleep(ctx->tp_rstn_gpio, 1); 138 usleep_range(5000, 6000); 139 gpiod_set_value_cansleep(ctx->reset_gpio, 1); 140 141 regulator_disable(ctx->avee); 142 regulator_disable(ctx->avdd); 143 /* T11 */ 144 usleep_range(5000, 6000); 145 regulator_disable(ctx->vddi); 146 /* T14 */ 147 msleep(50); 148 149 return 0; 150 } 151 152 static int mantix_prepare(struct drm_panel *panel) 153 { 154 struct mantix *ctx = panel_to_mantix(panel); 155 int ret; 156 157 /* Focaltech FT8006P, section 7.3.1 and 7.3.4 */ 158 dev_dbg(ctx->dev, "Resetting the panel\n"); 159 ret = regulator_enable(ctx->vddi); 160 if (ret < 0) { 161 dev_err(ctx->dev, "Failed to enable vddi supply: %d\n", ret); 162 return ret; 163 } 164 165 /* T1 + T2 */ 166 usleep_range(8000, 10000); 167 168 ret = regulator_enable(ctx->avdd); 169 if (ret < 0) { 170 dev_err(ctx->dev, "Failed to enable avdd supply: %d\n", ret); 171 return ret; 172 } 173 174 /* T2d */ 175 usleep_range(3500, 4000); 176 ret = regulator_enable(ctx->avee); 177 if (ret < 0) { 178 dev_err(ctx->dev, "Failed to enable avee supply: %d\n", ret); 179 return ret; 180 } 181 182 /* T3 + T4 + time for voltage to become stable: */ 183 usleep_range(6000, 7000); 184 gpiod_set_value_cansleep(ctx->reset_gpio, 0); 185 gpiod_set_value_cansleep(ctx->tp_rstn_gpio, 0); 186 187 /* T6 */ 188 msleep(50); 189 190 return 0; 191 } 192 193 static const struct drm_display_mode default_mode_mantix = { 194 .hdisplay = 720, 195 .hsync_start = 720 + 45, 196 .hsync_end = 720 + 45 + 14, 197 .htotal = 720 + 45 + 14 + 25, 198 .vdisplay = 1440, 199 .vsync_start = 1440 + 130, 200 .vsync_end = 1440 + 130 + 8, 201 .vtotal = 1440 + 130 + 8 + 106, 202 .clock = 85298, 203 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 204 .width_mm = 65, 205 .height_mm = 130, 206 }; 207 208 static const struct drm_display_mode default_mode_ys = { 209 .hdisplay = 720, 210 .hsync_start = 720 + 45, 211 .hsync_end = 720 + 45 + 14, 212 .htotal = 720 + 45 + 14 + 25, 213 .vdisplay = 1440, 214 .vsync_start = 1440 + 175, 215 .vsync_end = 1440 + 175 + 8, 216 .vtotal = 1440 + 175 + 8 + 50, 217 .clock = 85298, 218 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 219 .width_mm = 65, 220 .height_mm = 130, 221 }; 222 223 static int mantix_get_modes(struct drm_panel *panel, 224 struct drm_connector *connector) 225 { 226 struct mantix *ctx = panel_to_mantix(panel); 227 struct drm_display_mode *mode; 228 229 mode = drm_mode_duplicate(connector->dev, ctx->default_mode); 230 if (!mode) { 231 dev_err(ctx->dev, "Failed to add mode %ux%u@%u\n", 232 ctx->default_mode->hdisplay, ctx->default_mode->vdisplay, 233 drm_mode_vrefresh(ctx->default_mode)); 234 return -ENOMEM; 235 } 236 237 drm_mode_set_name(mode); 238 239 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 240 connector->display_info.width_mm = mode->width_mm; 241 connector->display_info.height_mm = mode->height_mm; 242 drm_mode_probed_add(connector, mode); 243 244 return 1; 245 } 246 247 static const struct drm_panel_funcs mantix_drm_funcs = { 248 .disable = mantix_disable, 249 .unprepare = mantix_unprepare, 250 .prepare = mantix_prepare, 251 .enable = mantix_enable, 252 .get_modes = mantix_get_modes, 253 }; 254 255 static int mantix_probe(struct mipi_dsi_device *dsi) 256 { 257 struct device *dev = &dsi->dev; 258 struct mantix *ctx; 259 int ret; 260 261 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 262 if (!ctx) 263 return -ENOMEM; 264 ctx->default_mode = of_device_get_match_data(dev); 265 266 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); 267 if (IS_ERR(ctx->reset_gpio)) { 268 dev_err(dev, "cannot get reset gpio\n"); 269 return PTR_ERR(ctx->reset_gpio); 270 } 271 272 ctx->tp_rstn_gpio = devm_gpiod_get(dev, "mantix,tp-rstn", GPIOD_OUT_HIGH); 273 if (IS_ERR(ctx->tp_rstn_gpio)) { 274 dev_err(dev, "cannot get tp-rstn gpio\n"); 275 return PTR_ERR(ctx->tp_rstn_gpio); 276 } 277 278 mipi_dsi_set_drvdata(dsi, ctx); 279 ctx->dev = dev; 280 281 dsi->lanes = 4; 282 dsi->format = MIPI_DSI_FMT_RGB888; 283 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | 284 MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_SYNC_PULSE; 285 286 ctx->avdd = devm_regulator_get(dev, "avdd"); 287 if (IS_ERR(ctx->avdd)) 288 return dev_err_probe(dev, PTR_ERR(ctx->avdd), "Failed to request avdd regulator\n"); 289 290 ctx->avee = devm_regulator_get(dev, "avee"); 291 if (IS_ERR(ctx->avee)) 292 return dev_err_probe(dev, PTR_ERR(ctx->avee), "Failed to request avee regulator\n"); 293 294 ctx->vddi = devm_regulator_get(dev, "vddi"); 295 if (IS_ERR(ctx->vddi)) 296 return dev_err_probe(dev, PTR_ERR(ctx->vddi), "Failed to request vddi regulator\n"); 297 298 drm_panel_init(&ctx->panel, dev, &mantix_drm_funcs, 299 DRM_MODE_CONNECTOR_DSI); 300 301 ret = drm_panel_of_backlight(&ctx->panel); 302 if (ret) 303 return ret; 304 305 drm_panel_add(&ctx->panel); 306 307 ret = mipi_dsi_attach(dsi); 308 if (ret < 0) { 309 dev_err(dev, "mipi_dsi_attach failed (%d). Is host ready?\n", ret); 310 drm_panel_remove(&ctx->panel); 311 return ret; 312 } 313 314 dev_info(dev, "%ux%u@%u %ubpp dsi %udl - ready\n", 315 ctx->default_mode->hdisplay, ctx->default_mode->vdisplay, 316 drm_mode_vrefresh(ctx->default_mode), 317 mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes); 318 319 return 0; 320 } 321 322 static void mantix_shutdown(struct mipi_dsi_device *dsi) 323 { 324 struct mantix *ctx = mipi_dsi_get_drvdata(dsi); 325 326 drm_panel_unprepare(&ctx->panel); 327 drm_panel_disable(&ctx->panel); 328 } 329 330 static int mantix_remove(struct mipi_dsi_device *dsi) 331 { 332 struct mantix *ctx = mipi_dsi_get_drvdata(dsi); 333 334 mantix_shutdown(dsi); 335 336 mipi_dsi_detach(dsi); 337 drm_panel_remove(&ctx->panel); 338 339 return 0; 340 } 341 342 static const struct of_device_id mantix_of_match[] = { 343 { .compatible = "mantix,mlaf057we51-x", .data = &default_mode_mantix }, 344 { .compatible = "ys,ys57pss36bh5gq", .data = &default_mode_ys }, 345 { /* sentinel */ } 346 }; 347 MODULE_DEVICE_TABLE(of, mantix_of_match); 348 349 static struct mipi_dsi_driver mantix_driver = { 350 .probe = mantix_probe, 351 .remove = mantix_remove, 352 .shutdown = mantix_shutdown, 353 .driver = { 354 .name = DRV_NAME, 355 .of_match_table = mantix_of_match, 356 }, 357 }; 358 module_mipi_dsi_driver(mantix_driver); 359 360 MODULE_AUTHOR("Guido Günther <agx@sigxcpu.org>"); 361 MODULE_DESCRIPTION("DRM driver for Mantix MLAF057WE51-X MIPI DSI panel"); 362 MODULE_LICENSE("GPL v2"); 363