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