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 void mantix_init_sequence(struct mipi_dsi_multi_context *dsi_ctx) 49 { 50 /* 51 * Init sequence was supplied by the panel vendor. 52 */ 53 mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5a); 54 55 mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_INT_CANCEL, 0x03); 56 57 mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5a, 0x03); 58 mipi_dsi_generic_write_seq_multi(dsi_ctx, 0x80, 0xa9, 0x00); /* VCOM */ 59 60 mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_SPI_FINISH, 0xa5); 61 mipi_dsi_generic_write_seq_multi(dsi_ctx, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x00, 0x2f); 62 } 63 64 static int mantix_enable(struct drm_panel *panel) 65 { 66 struct mantix *ctx = panel_to_mantix(panel); 67 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 68 struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 69 70 mantix_init_sequence(&dsi_ctx); 71 if (!dsi_ctx.accum_err) 72 dev_dbg(ctx->dev, "Panel init sequence done\n"); 73 74 /* remainder to 120ms (7.3.1 Note 4) */ 75 mipi_dsi_msleep(&dsi_ctx, 70); 76 77 mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); 78 mipi_dsi_msleep(&dsi_ctx, 120); 79 80 mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); 81 mipi_dsi_usleep_range(&dsi_ctx, 10000, 12000); 82 83 return dsi_ctx.accum_err; 84 } 85 86 static int mantix_disable(struct drm_panel *panel) 87 { 88 struct mantix *ctx = panel_to_mantix(panel); 89 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 90 struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 91 92 mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); 93 mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); 94 95 /* T10 */ 96 mipi_dsi_msleep(&dsi_ctx, 150); 97 98 return dsi_ctx.accum_err; 99 } 100 101 static int mantix_unprepare(struct drm_panel *panel) 102 { 103 struct mantix *ctx = panel_to_mantix(panel); 104 105 regulator_disable(ctx->avee); 106 regulator_disable(ctx->avdd); 107 /* T11 */ 108 usleep_range(5000, 6000); 109 regulator_disable(ctx->vddi); 110 111 gpiod_set_value_cansleep(ctx->tp_rstn_gpio, 1); 112 usleep_range(5000, 6000); 113 gpiod_set_value_cansleep(ctx->reset_gpio, 1); 114 115 /* T14 */ 116 msleep(50); 117 118 return 0; 119 } 120 121 static int mantix_prepare(struct drm_panel *panel) 122 { 123 struct mantix *ctx = panel_to_mantix(panel); 124 int ret; 125 126 /* Focaltech FT8006P, section 7.3.1 and 7.3.4 */ 127 dev_dbg(ctx->dev, "Resetting the panel\n"); 128 ret = regulator_enable(ctx->vddi); 129 if (ret < 0) { 130 dev_err(ctx->dev, "Failed to enable vddi supply: %d\n", ret); 131 return ret; 132 } 133 134 /* T1 + T2 */ 135 usleep_range(8000, 10000); 136 137 ret = regulator_enable(ctx->avdd); 138 if (ret < 0) { 139 dev_err(ctx->dev, "Failed to enable avdd supply: %d\n", ret); 140 return ret; 141 } 142 143 /* T2d */ 144 usleep_range(3500, 4000); 145 ret = regulator_enable(ctx->avee); 146 if (ret < 0) { 147 dev_err(ctx->dev, "Failed to enable avee supply: %d\n", ret); 148 return ret; 149 } 150 151 usleep_range(100, 200); 152 gpiod_set_value_cansleep(ctx->tp_rstn_gpio, 0); 153 usleep_range(100, 200); 154 gpiod_set_value_cansleep(ctx->reset_gpio, 0); 155 156 /* T6 */ 157 msleep(50); 158 159 return 0; 160 } 161 162 static const struct drm_display_mode default_mode_mantix = { 163 .hdisplay = 720, 164 .hsync_start = 720 + 45, 165 .hsync_end = 720 + 45 + 14, 166 .htotal = 720 + 45 + 14 + 25, 167 .vdisplay = 1440, 168 .vsync_start = 1440 + 130, 169 .vsync_end = 1440 + 130 + 8, 170 .vtotal = 1440 + 130 + 8 + 106, 171 .clock = 81237, 172 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 173 .width_mm = 65, 174 .height_mm = 130, 175 }; 176 177 static const struct drm_display_mode default_mode_ys = { 178 .hdisplay = 720, 179 .hsync_start = 720 + 45, 180 .hsync_end = 720 + 45 + 14, 181 .htotal = 720 + 45 + 14 + 25, 182 .vdisplay = 1440, 183 .vsync_start = 1440 + 175, 184 .vsync_end = 1440 + 175 + 8, 185 .vtotal = 1440 + 175 + 8 + 50, 186 .clock = 80706, 187 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 188 .width_mm = 65, 189 .height_mm = 130, 190 }; 191 192 static const u32 mantix_bus_formats[] = { 193 MEDIA_BUS_FMT_RGB888_1X24, 194 }; 195 196 static int mantix_get_modes(struct drm_panel *panel, 197 struct drm_connector *connector) 198 { 199 struct mantix *ctx = panel_to_mantix(panel); 200 struct drm_display_mode *mode; 201 202 mode = drm_mode_duplicate(connector->dev, ctx->default_mode); 203 if (!mode) { 204 dev_err(ctx->dev, "Failed to add mode %ux%u@%u\n", 205 ctx->default_mode->hdisplay, ctx->default_mode->vdisplay, 206 drm_mode_vrefresh(ctx->default_mode)); 207 return -ENOMEM; 208 } 209 210 drm_mode_set_name(mode); 211 212 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 213 connector->display_info.width_mm = mode->width_mm; 214 connector->display_info.height_mm = mode->height_mm; 215 drm_mode_probed_add(connector, mode); 216 217 drm_display_info_set_bus_formats(&connector->display_info, 218 mantix_bus_formats, 219 ARRAY_SIZE(mantix_bus_formats)); 220 221 return 1; 222 } 223 224 static const struct drm_panel_funcs mantix_drm_funcs = { 225 .disable = mantix_disable, 226 .unprepare = mantix_unprepare, 227 .prepare = mantix_prepare, 228 .enable = mantix_enable, 229 .get_modes = mantix_get_modes, 230 }; 231 232 static int mantix_probe(struct mipi_dsi_device *dsi) 233 { 234 struct device *dev = &dsi->dev; 235 struct mantix *ctx; 236 int ret; 237 238 ctx = devm_drm_panel_alloc(dev, struct mantix, panel, &mantix_drm_funcs, 239 DRM_MODE_CONNECTOR_DSI); 240 if (IS_ERR(ctx)) 241 return PTR_ERR(ctx); 242 243 ctx->default_mode = of_device_get_match_data(dev); 244 245 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); 246 if (IS_ERR(ctx->reset_gpio)) { 247 dev_err(dev, "cannot get reset gpio\n"); 248 return PTR_ERR(ctx->reset_gpio); 249 } 250 251 ctx->tp_rstn_gpio = devm_gpiod_get(dev, "mantix,tp-rstn", GPIOD_OUT_HIGH); 252 if (IS_ERR(ctx->tp_rstn_gpio)) { 253 dev_err(dev, "cannot get tp-rstn gpio\n"); 254 return PTR_ERR(ctx->tp_rstn_gpio); 255 } 256 257 mipi_dsi_set_drvdata(dsi, ctx); 258 ctx->dev = dev; 259 260 dsi->lanes = 4; 261 dsi->format = MIPI_DSI_FMT_RGB888; 262 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM | 263 MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_SYNC_PULSE; 264 265 ctx->avdd = devm_regulator_get(dev, "avdd"); 266 if (IS_ERR(ctx->avdd)) 267 return dev_err_probe(dev, PTR_ERR(ctx->avdd), "Failed to request avdd regulator\n"); 268 269 ctx->avee = devm_regulator_get(dev, "avee"); 270 if (IS_ERR(ctx->avee)) 271 return dev_err_probe(dev, PTR_ERR(ctx->avee), "Failed to request avee regulator\n"); 272 273 ctx->vddi = devm_regulator_get(dev, "vddi"); 274 if (IS_ERR(ctx->vddi)) 275 return dev_err_probe(dev, PTR_ERR(ctx->vddi), "Failed to request vddi regulator\n"); 276 277 ret = drm_panel_of_backlight(&ctx->panel); 278 if (ret) 279 return ret; 280 281 drm_panel_add(&ctx->panel); 282 283 ret = mipi_dsi_attach(dsi); 284 if (ret < 0) { 285 dev_err(dev, "mipi_dsi_attach failed (%d). Is host ready?\n", ret); 286 drm_panel_remove(&ctx->panel); 287 return ret; 288 } 289 290 dev_info(dev, "%ux%u@%u %ubpp dsi %udl - ready\n", 291 ctx->default_mode->hdisplay, ctx->default_mode->vdisplay, 292 drm_mode_vrefresh(ctx->default_mode), 293 mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes); 294 295 return 0; 296 } 297 298 static void mantix_remove(struct mipi_dsi_device *dsi) 299 { 300 struct mantix *ctx = mipi_dsi_get_drvdata(dsi); 301 302 mipi_dsi_detach(dsi); 303 drm_panel_remove(&ctx->panel); 304 } 305 306 static const struct of_device_id mantix_of_match[] = { 307 { .compatible = "mantix,mlaf057we51-x", .data = &default_mode_mantix }, 308 { .compatible = "ys,ys57pss36bh5gq", .data = &default_mode_ys }, 309 { /* sentinel */ } 310 }; 311 MODULE_DEVICE_TABLE(of, mantix_of_match); 312 313 static struct mipi_dsi_driver mantix_driver = { 314 .probe = mantix_probe, 315 .remove = mantix_remove, 316 .driver = { 317 .name = DRV_NAME, 318 .of_match_table = mantix_of_match, 319 }, 320 }; 321 module_mipi_dsi_driver(mantix_driver); 322 323 MODULE_AUTHOR("Guido Günther <agx@sigxcpu.org>"); 324 MODULE_DESCRIPTION("DRM driver for Mantix MLAF057WE51-X MIPI DSI panel"); 325 MODULE_LICENSE("GPL v2"); 326