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 mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 110 int i; 111 112 mipi_dsi_dcs_soft_reset_multi(&dsi_ctx); 113 114 mipi_dsi_usleep_range(&dsi_ctx, 15000, 17000); 115 116 mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); 117 118 for (i = 0; i < rpanel->pdata->init_length; i++) { 119 const struct r63353_instr *instr = &rpanel->pdata->init[i]; 120 121 mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, instr->data, 122 instr->len); 123 } 124 125 mipi_dsi_msleep(&dsi_ctx, 120); 126 127 mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); 128 129 mipi_dsi_usleep_range(&dsi_ctx, 5000, 10000); 130 131 mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); 132 133 if (dsi_ctx.accum_err) 134 gpiod_set_value(rpanel->reset_gpio, 0); 135 136 return dsi_ctx.accum_err; 137 } 138 139 static int r63353_panel_prepare(struct drm_panel *panel) 140 { 141 struct r63353_panel *rpanel = to_r63353_panel(panel); 142 struct mipi_dsi_device *dsi = rpanel->dsi; 143 struct device *dev = &dsi->dev; 144 int ret; 145 146 dev_dbg(dev, "Preparing\n"); 147 148 ret = r63353_panel_power_on(rpanel); 149 if (ret) 150 return ret; 151 152 ret = r63353_panel_activate(rpanel); 153 if (ret) { 154 r63353_panel_power_off(rpanel); 155 return ret; 156 } 157 158 dev_dbg(dev, "Prepared\n"); 159 return 0; 160 } 161 162 static void r63353_panel_deactivate(struct r63353_panel *rpanel) 163 { 164 struct mipi_dsi_device *dsi = rpanel->dsi; 165 struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 166 167 mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); 168 169 mipi_dsi_usleep_range(&dsi_ctx, 5000, 10000); 170 171 mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); 172 } 173 174 static int r63353_panel_unprepare(struct drm_panel *panel) 175 { 176 struct r63353_panel *rpanel = to_r63353_panel(panel); 177 178 r63353_panel_deactivate(rpanel); 179 r63353_panel_power_off(rpanel); 180 181 return 0; 182 } 183 184 static const struct drm_display_mode sharp_ls068b3sx02_timing = { 185 .clock = 70000, 186 .hdisplay = 640, 187 .hsync_start = 640 + 35, 188 .hsync_end = 640 + 35 + 2, 189 .htotal = 640 + 35 + 2 + 150, 190 .vdisplay = 1280, 191 .vsync_start = 1280 + 2, 192 .vsync_end = 1280 + 2 + 4, 193 .vtotal = 1280 + 2 + 4 + 0, 194 }; 195 196 static int r63353_panel_get_modes(struct drm_panel *panel, 197 struct drm_connector *connector) 198 { 199 struct r63353_panel *rpanel = to_r63353_panel(panel); 200 struct drm_display_mode *mode; 201 static const u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; 202 203 mode = drm_mode_duplicate(connector->dev, rpanel->pdata->mode); 204 if (!mode) 205 return -ENOMEM; 206 207 drm_mode_set_name(mode); 208 drm_mode_probed_add(connector, mode); 209 210 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 211 connector->display_info.width_mm = rpanel->pdata->width_mm; 212 connector->display_info.height_mm = rpanel->pdata->height_mm; 213 214 drm_display_info_set_bus_formats(&connector->display_info, 215 &bus_format, 1); 216 217 return 1; 218 } 219 220 static const struct drm_panel_funcs r63353_panel_funcs = { 221 .prepare = r63353_panel_prepare, 222 .unprepare = r63353_panel_unprepare, 223 .get_modes = r63353_panel_get_modes, 224 }; 225 226 static int r63353_panel_probe(struct mipi_dsi_device *dsi) 227 { 228 int ret = 0; 229 struct device *dev = &dsi->dev; 230 struct r63353_panel *panel; 231 232 panel = devm_kzalloc(&dsi->dev, sizeof(*panel), GFP_KERNEL); 233 if (!panel) 234 return -ENOMEM; 235 236 mipi_dsi_set_drvdata(dsi, panel); 237 panel->dsi = dsi; 238 panel->pdata = (struct r63353_desc *)of_device_get_match_data(dev); 239 240 dev_info(dev, "Panel %s\n", panel->pdata->name); 241 242 dsi->lanes = 2; 243 dsi->format = MIPI_DSI_FMT_RGB888; 244 dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | 245 MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM | 246 MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_NO_EOT_PACKET; 247 248 panel->dvdd = devm_regulator_get(dev, "dvdd"); 249 if (IS_ERR(panel->dvdd)) 250 return PTR_ERR(panel->dvdd); 251 panel->avdd = devm_regulator_get(dev, "avdd"); 252 if (IS_ERR(panel->avdd)) 253 return PTR_ERR(panel->avdd); 254 255 panel->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 256 if (IS_ERR(panel->reset_gpio)) { 257 dev_err(dev, "failed to get RESET GPIO\n"); 258 return PTR_ERR(panel->reset_gpio); 259 } 260 261 drm_panel_init(&panel->base, dev, &r63353_panel_funcs, 262 DRM_MODE_CONNECTOR_DSI); 263 264 panel->base.prepare_prev_first = true; 265 ret = drm_panel_of_backlight(&panel->base); 266 if (ret) 267 return ret; 268 269 drm_panel_add(&panel->base); 270 271 ret = mipi_dsi_attach(dsi); 272 if (ret < 0) { 273 dev_err(dev, "mipi_dsi_attach failed: %d\n", ret); 274 drm_panel_remove(&panel->base); 275 return ret; 276 } 277 278 return ret; 279 } 280 281 static void r63353_panel_remove(struct mipi_dsi_device *dsi) 282 { 283 struct r63353_panel *rpanel = mipi_dsi_get_drvdata(dsi); 284 struct device *dev = &dsi->dev; 285 int ret; 286 287 ret = mipi_dsi_detach(dsi); 288 if (ret < 0) 289 dev_err(dev, "Failed to detach from host (%d)\n", ret); 290 291 drm_panel_remove(&rpanel->base); 292 } 293 294 static void r63353_panel_shutdown(struct mipi_dsi_device *dsi) 295 { 296 struct r63353_panel *rpanel = mipi_dsi_get_drvdata(dsi); 297 298 drm_panel_unprepare(&rpanel->base); 299 } 300 301 static const struct r63353_desc sharp_ls068b3sx02_data = { 302 .name = "Sharp LS068B3SX02", 303 .mode = &sharp_ls068b3sx02_timing, 304 .init = sharp_ls068b3sx02_init, 305 .init_length = ARRAY_SIZE(sharp_ls068b3sx02_init), 306 .width_mm = 68, 307 .height_mm = 159, 308 }; 309 310 static const struct of_device_id r63353_of_match[] = { 311 { .compatible = "sharp,ls068b3sx02", .data = &sharp_ls068b3sx02_data }, 312 { } 313 }; 314 315 MODULE_DEVICE_TABLE(of, r63353_of_match); 316 317 static struct mipi_dsi_driver r63353_panel_driver = { 318 .driver = { 319 .name = "r63353-dsi", 320 .of_match_table = r63353_of_match, 321 }, 322 .probe = r63353_panel_probe, 323 .remove = r63353_panel_remove, 324 .shutdown = r63353_panel_shutdown, 325 }; 326 327 module_mipi_dsi_driver(r63353_panel_driver); 328 329 MODULE_AUTHOR("Matthias Proske <Matthias.Proske@bshg.com>"); 330 MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>"); 331 MODULE_DESCRIPTION("Synaptics R63353 Controller Driver"); 332 MODULE_LICENSE("GPL"); 333