1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Synaptics R63353 Controller driver 4 * 5 * Copyright (C) 2020 BSH Hausgerate GmbH 6 */ 7 8 #include <linux/delay.h> 9 #include <linux/device.h> 10 #include <linux/err.h> 11 #include <linux/errno.h> 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/media-bus-format.h> 16 17 #include <linux/gpio/consumer.h> 18 #include <linux/regulator/consumer.h> 19 20 #include <drm/drm_mipi_dsi.h> 21 #include <drm/drm_modes.h> 22 #include <drm/drm_panel.h> 23 24 #include <video/mipi_display.h> 25 26 #define R63353_INSTR(...) { \ 27 .len = sizeof((u8[]) {__VA_ARGS__}), \ 28 .data = (u8[]){__VA_ARGS__} \ 29 } 30 31 struct r63353_instr { 32 size_t len; 33 const u8 *data; 34 }; 35 36 static const struct r63353_instr sharp_ls068b3sx02_init[] = { 37 R63353_INSTR(0x51, 0xff), 38 R63353_INSTR(0x53, 0x0c), 39 R63353_INSTR(0x55, 0x00), 40 R63353_INSTR(0x84, 0x00), 41 R63353_INSTR(0x29), 42 }; 43 44 struct r63353_desc { 45 const char *name; 46 const struct r63353_instr *init; 47 const size_t init_length; 48 const struct drm_display_mode *mode; 49 u32 width_mm; 50 u32 height_mm; 51 }; 52 53 struct r63353_panel { 54 struct drm_panel base; 55 struct mipi_dsi_device *dsi; 56 57 struct gpio_desc *reset_gpio; 58 struct regulator *dvdd; 59 struct regulator *avdd; 60 61 struct r63353_desc *pdata; 62 }; 63 64 static inline struct r63353_panel *to_r63353_panel(struct drm_panel *panel) 65 { 66 return container_of(panel, struct r63353_panel, base); 67 } 68 69 static int r63353_panel_power_on(struct r63353_panel *rpanel) 70 { 71 struct mipi_dsi_device *dsi = rpanel->dsi; 72 struct device *dev = &dsi->dev; 73 int ret; 74 75 ret = regulator_enable(rpanel->avdd); 76 if (ret) { 77 dev_err(dev, "Failed to enable avdd regulator (%d)\n", ret); 78 return ret; 79 } 80 81 usleep_range(15000, 25000); 82 83 ret = regulator_enable(rpanel->dvdd); 84 if (ret) { 85 dev_err(dev, "Failed to enable dvdd regulator (%d)\n", ret); 86 regulator_disable(rpanel->avdd); 87 return ret; 88 } 89 90 usleep_range(300000, 350000); 91 gpiod_set_value(rpanel->reset_gpio, 1); 92 usleep_range(15000, 25000); 93 94 return 0; 95 } 96 97 static int r63353_panel_power_off(struct r63353_panel *rpanel) 98 { 99 gpiod_set_value(rpanel->reset_gpio, 0); 100 regulator_disable(rpanel->dvdd); 101 regulator_disable(rpanel->avdd); 102 103 return 0; 104 } 105 106 static int r63353_panel_activate(struct r63353_panel *rpanel) 107 { 108 struct mipi_dsi_device *dsi = rpanel->dsi; 109 struct device *dev = &dsi->dev; 110 int i, ret; 111 112 ret = mipi_dsi_dcs_soft_reset(dsi); 113 if (ret < 0) { 114 dev_err(dev, "Failed to do Software Reset (%d)\n", ret); 115 goto fail; 116 } 117 118 usleep_range(15000, 17000); 119 120 ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 121 if (ret < 0) { 122 dev_err(dev, "Failed to enter sleep mode (%d)\n", ret); 123 goto fail; 124 } 125 126 for (i = 0; i < rpanel->pdata->init_length; i++) { 127 const struct r63353_instr *instr = &rpanel->pdata->init[i]; 128 129 ret = mipi_dsi_dcs_write_buffer(dsi, instr->data, instr->len); 130 if (ret < 0) 131 goto fail; 132 } 133 134 msleep(120); 135 136 ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 137 if (ret < 0) { 138 dev_err(dev, "Failed to exit sleep mode (%d)\n", ret); 139 goto fail; 140 } 141 142 usleep_range(5000, 10000); 143 144 ret = mipi_dsi_dcs_set_display_on(dsi); 145 if (ret < 0) { 146 dev_err(dev, "Failed to set display ON (%d)\n", ret); 147 goto fail; 148 } 149 150 return 0; 151 152 fail: 153 gpiod_set_value(rpanel->reset_gpio, 0); 154 155 return ret; 156 } 157 158 static int r63353_panel_prepare(struct drm_panel *panel) 159 { 160 struct r63353_panel *rpanel = to_r63353_panel(panel); 161 struct mipi_dsi_device *dsi = rpanel->dsi; 162 struct device *dev = &dsi->dev; 163 int ret; 164 165 dev_dbg(dev, "Preparing\n"); 166 167 ret = r63353_panel_power_on(rpanel); 168 if (ret) 169 return ret; 170 171 ret = r63353_panel_activate(rpanel); 172 if (ret) { 173 r63353_panel_power_off(rpanel); 174 return ret; 175 } 176 177 dev_dbg(dev, "Prepared\n"); 178 return 0; 179 } 180 181 static int r63353_panel_deactivate(struct r63353_panel *rpanel) 182 { 183 struct mipi_dsi_device *dsi = rpanel->dsi; 184 struct device *dev = &dsi->dev; 185 int ret; 186 187 ret = mipi_dsi_dcs_set_display_off(dsi); 188 if (ret < 0) { 189 dev_err(dev, "Failed to set display OFF (%d)\n", ret); 190 return ret; 191 } 192 193 usleep_range(5000, 10000); 194 195 ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 196 if (ret < 0) { 197 dev_err(dev, "Failed to enter sleep mode (%d)\n", ret); 198 return ret; 199 } 200 201 return 0; 202 } 203 204 static int r63353_panel_unprepare(struct drm_panel *panel) 205 { 206 struct r63353_panel *rpanel = to_r63353_panel(panel); 207 208 r63353_panel_deactivate(rpanel); 209 r63353_panel_power_off(rpanel); 210 211 return 0; 212 } 213 214 static const struct drm_display_mode sharp_ls068b3sx02_timing = { 215 .clock = 70000, 216 .hdisplay = 640, 217 .hsync_start = 640 + 35, 218 .hsync_end = 640 + 35 + 2, 219 .htotal = 640 + 35 + 2 + 150, 220 .vdisplay = 1280, 221 .vsync_start = 1280 + 2, 222 .vsync_end = 1280 + 2 + 4, 223 .vtotal = 1280 + 2 + 4 + 0, 224 }; 225 226 static int r63353_panel_get_modes(struct drm_panel *panel, 227 struct drm_connector *connector) 228 { 229 struct r63353_panel *rpanel = to_r63353_panel(panel); 230 struct drm_display_mode *mode; 231 static const u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; 232 233 mode = drm_mode_duplicate(connector->dev, rpanel->pdata->mode); 234 if (!mode) 235 return -ENOMEM; 236 237 drm_mode_set_name(mode); 238 drm_mode_probed_add(connector, mode); 239 240 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 241 connector->display_info.width_mm = rpanel->pdata->width_mm; 242 connector->display_info.height_mm = rpanel->pdata->height_mm; 243 244 drm_display_info_set_bus_formats(&connector->display_info, 245 &bus_format, 1); 246 247 return 1; 248 } 249 250 static const struct drm_panel_funcs r63353_panel_funcs = { 251 .prepare = r63353_panel_prepare, 252 .unprepare = r63353_panel_unprepare, 253 .get_modes = r63353_panel_get_modes, 254 }; 255 256 static int r63353_panel_probe(struct mipi_dsi_device *dsi) 257 { 258 int ret = 0; 259 struct device *dev = &dsi->dev; 260 struct r63353_panel *panel; 261 262 panel = devm_kzalloc(&dsi->dev, sizeof(*panel), GFP_KERNEL); 263 if (!panel) 264 return -ENOMEM; 265 266 mipi_dsi_set_drvdata(dsi, panel); 267 panel->dsi = dsi; 268 panel->pdata = (struct r63353_desc *)of_device_get_match_data(dev); 269 270 dev_info(dev, "Panel %s\n", panel->pdata->name); 271 272 dsi->lanes = 2; 273 dsi->format = MIPI_DSI_FMT_RGB888; 274 dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | 275 MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM | 276 MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_NO_EOT_PACKET; 277 278 panel->dvdd = devm_regulator_get(dev, "dvdd"); 279 if (IS_ERR(panel->dvdd)) 280 return PTR_ERR(panel->dvdd); 281 panel->avdd = devm_regulator_get(dev, "avdd"); 282 if (IS_ERR(panel->avdd)) 283 return PTR_ERR(panel->avdd); 284 285 panel->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 286 if (IS_ERR(panel->reset_gpio)) { 287 dev_err(dev, "failed to get RESET GPIO\n"); 288 return PTR_ERR(panel->reset_gpio); 289 } 290 291 drm_panel_init(&panel->base, dev, &r63353_panel_funcs, 292 DRM_MODE_CONNECTOR_DSI); 293 294 panel->base.prepare_prev_first = true; 295 ret = drm_panel_of_backlight(&panel->base); 296 if (ret) 297 return ret; 298 299 drm_panel_add(&panel->base); 300 301 ret = mipi_dsi_attach(dsi); 302 if (ret < 0) { 303 dev_err(dev, "mipi_dsi_attach failed: %d\n", ret); 304 drm_panel_remove(&panel->base); 305 return ret; 306 } 307 308 return ret; 309 } 310 311 static void r63353_panel_remove(struct mipi_dsi_device *dsi) 312 { 313 struct r63353_panel *rpanel = mipi_dsi_get_drvdata(dsi); 314 struct device *dev = &dsi->dev; 315 int ret; 316 317 ret = mipi_dsi_detach(dsi); 318 if (ret < 0) 319 dev_err(dev, "Failed to detach from host (%d)\n", ret); 320 321 drm_panel_remove(&rpanel->base); 322 } 323 324 static void r63353_panel_shutdown(struct mipi_dsi_device *dsi) 325 { 326 struct r63353_panel *rpanel = mipi_dsi_get_drvdata(dsi); 327 328 r63353_panel_unprepare(&rpanel->base); 329 } 330 331 static const struct r63353_desc sharp_ls068b3sx02_data = { 332 .name = "Sharp LS068B3SX02", 333 .mode = &sharp_ls068b3sx02_timing, 334 .init = sharp_ls068b3sx02_init, 335 .init_length = ARRAY_SIZE(sharp_ls068b3sx02_init), 336 .width_mm = 68, 337 .height_mm = 159, 338 }; 339 340 static const struct of_device_id r63353_of_match[] = { 341 { .compatible = "sharp,ls068b3sx02", .data = &sharp_ls068b3sx02_data }, 342 { } 343 }; 344 345 MODULE_DEVICE_TABLE(of, r63353_of_match); 346 347 static struct mipi_dsi_driver r63353_panel_driver = { 348 .driver = { 349 .name = "r63353-dsi", 350 .of_match_table = r63353_of_match, 351 }, 352 .probe = r63353_panel_probe, 353 .remove = r63353_panel_remove, 354 .shutdown = r63353_panel_shutdown, 355 }; 356 357 module_mipi_dsi_driver(r63353_panel_driver); 358 359 MODULE_AUTHOR("Matthias Proske <Matthias.Proske@bshg.com>"); 360 MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>"); 361 MODULE_DESCRIPTION("Synaptics R63353 Controller Driver"); 362 MODULE_LICENSE("GPL"); 363