1 /* 2 * Copyright (C) 2014 NVIDIA Corporation 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8 9 #include <linux/backlight.h> 10 #include <linux/gpio/consumer.h> 11 #include <linux/module.h> 12 #include <linux/of.h> 13 #include <linux/regulator/consumer.h> 14 15 #include <drm/drmP.h> 16 #include <drm/drm_crtc.h> 17 #include <drm/drm_mipi_dsi.h> 18 #include <drm/drm_panel.h> 19 20 #include <video/mipi_display.h> 21 22 #include <linux/host1x.h> 23 24 struct sharp_panel { 25 struct drm_panel base; 26 /* the datasheet refers to them as DSI-LINK1 and DSI-LINK2 */ 27 struct mipi_dsi_device *link1; 28 struct mipi_dsi_device *link2; 29 30 struct backlight_device *backlight; 31 struct regulator *supply; 32 33 bool prepared; 34 bool enabled; 35 36 const struct drm_display_mode *mode; 37 }; 38 39 static inline struct sharp_panel *to_sharp_panel(struct drm_panel *panel) 40 { 41 return container_of(panel, struct sharp_panel, base); 42 } 43 44 static int sharp_panel_write(struct sharp_panel *sharp, u16 offset, u8 value) 45 { 46 u8 payload[3] = { offset >> 8, offset & 0xff, value }; 47 struct mipi_dsi_device *dsi = sharp->link1; 48 ssize_t err; 49 50 err = mipi_dsi_generic_write(dsi, payload, sizeof(payload)); 51 if (err < 0) { 52 dev_err(&dsi->dev, "failed to write %02x to %04x: %zd\n", 53 value, offset, err); 54 return err; 55 } 56 57 err = mipi_dsi_dcs_nop(dsi); 58 if (err < 0) { 59 dev_err(&dsi->dev, "failed to send DCS nop: %zd\n", err); 60 return err; 61 } 62 63 usleep_range(10, 20); 64 65 return 0; 66 } 67 68 static __maybe_unused int sharp_panel_read(struct sharp_panel *sharp, 69 u16 offset, u8 *value) 70 { 71 ssize_t err; 72 73 cpu_to_be16s(&offset); 74 75 err = mipi_dsi_generic_read(sharp->link1, &offset, sizeof(offset), 76 value, sizeof(*value)); 77 if (err < 0) 78 dev_err(&sharp->link1->dev, "failed to read from %04x: %zd\n", 79 offset, err); 80 81 return err; 82 } 83 84 static int sharp_panel_disable(struct drm_panel *panel) 85 { 86 struct sharp_panel *sharp = to_sharp_panel(panel); 87 88 if (!sharp->enabled) 89 return 0; 90 91 if (sharp->backlight) { 92 sharp->backlight->props.power = FB_BLANK_POWERDOWN; 93 backlight_update_status(sharp->backlight); 94 } 95 96 sharp->enabled = false; 97 98 return 0; 99 } 100 101 static int sharp_panel_unprepare(struct drm_panel *panel) 102 { 103 struct sharp_panel *sharp = to_sharp_panel(panel); 104 int err; 105 106 if (!sharp->prepared) 107 return 0; 108 109 err = mipi_dsi_dcs_set_display_off(sharp->link1); 110 if (err < 0) 111 dev_err(panel->dev, "failed to set display off: %d\n", err); 112 113 err = mipi_dsi_dcs_enter_sleep_mode(sharp->link1); 114 if (err < 0) 115 dev_err(panel->dev, "failed to enter sleep mode: %d\n", err); 116 117 msleep(120); 118 119 regulator_disable(sharp->supply); 120 121 sharp->prepared = false; 122 123 return 0; 124 } 125 126 static int sharp_setup_symmetrical_split(struct mipi_dsi_device *left, 127 struct mipi_dsi_device *right, 128 const struct drm_display_mode *mode) 129 { 130 int err; 131 132 err = mipi_dsi_dcs_set_column_address(left, 0, mode->hdisplay / 2 - 1); 133 if (err < 0) { 134 dev_err(&left->dev, "failed to set column address: %d\n", err); 135 return err; 136 } 137 138 err = mipi_dsi_dcs_set_page_address(left, 0, mode->vdisplay - 1); 139 if (err < 0) { 140 dev_err(&left->dev, "failed to set page address: %d\n", err); 141 return err; 142 } 143 144 err = mipi_dsi_dcs_set_column_address(right, mode->hdisplay / 2, 145 mode->hdisplay - 1); 146 if (err < 0) { 147 dev_err(&right->dev, "failed to set column address: %d\n", err); 148 return err; 149 } 150 151 err = mipi_dsi_dcs_set_page_address(right, 0, mode->vdisplay - 1); 152 if (err < 0) { 153 dev_err(&right->dev, "failed to set page address: %d\n", err); 154 return err; 155 } 156 157 return 0; 158 } 159 160 static int sharp_panel_prepare(struct drm_panel *panel) 161 { 162 struct sharp_panel *sharp = to_sharp_panel(panel); 163 u8 format = MIPI_DCS_PIXEL_FMT_24BIT; 164 int err; 165 166 if (sharp->prepared) 167 return 0; 168 169 err = regulator_enable(sharp->supply); 170 if (err < 0) 171 return err; 172 173 usleep_range(10000, 20000); 174 175 err = mipi_dsi_dcs_soft_reset(sharp->link1); 176 if (err < 0) { 177 dev_err(panel->dev, "soft reset failed: %d\n", err); 178 goto poweroff; 179 } 180 181 msleep(120); 182 183 err = mipi_dsi_dcs_exit_sleep_mode(sharp->link1); 184 if (err < 0) { 185 dev_err(panel->dev, "failed to exit sleep mode: %d\n", err); 186 goto poweroff; 187 } 188 189 /* 190 * The MIPI DCS specification mandates this delay only between the 191 * exit_sleep_mode and enter_sleep_mode commands, so it isn't strictly 192 * necessary here. 193 */ 194 /* 195 msleep(120); 196 */ 197 198 /* set left-right mode */ 199 err = sharp_panel_write(sharp, 0x1000, 0x2a); 200 if (err < 0) { 201 dev_err(panel->dev, "failed to set left-right mode: %d\n", err); 202 goto poweroff; 203 } 204 205 /* enable command mode */ 206 err = sharp_panel_write(sharp, 0x1001, 0x01); 207 if (err < 0) { 208 dev_err(panel->dev, "failed to enable command mode: %d\n", err); 209 goto poweroff; 210 } 211 212 err = mipi_dsi_dcs_set_pixel_format(sharp->link1, format); 213 if (err < 0) { 214 dev_err(panel->dev, "failed to set pixel format: %d\n", err); 215 goto poweroff; 216 } 217 218 /* 219 * TODO: The device supports both left-right and even-odd split 220 * configurations, but this driver currently supports only the left- 221 * right split. To support a different mode a mechanism needs to be 222 * put in place to communicate the configuration back to the DSI host 223 * controller. 224 */ 225 err = sharp_setup_symmetrical_split(sharp->link1, sharp->link2, 226 sharp->mode); 227 if (err < 0) { 228 dev_err(panel->dev, "failed to set up symmetrical split: %d\n", 229 err); 230 goto poweroff; 231 } 232 233 err = mipi_dsi_dcs_set_display_on(sharp->link1); 234 if (err < 0) { 235 dev_err(panel->dev, "failed to set display on: %d\n", err); 236 goto poweroff; 237 } 238 239 sharp->prepared = true; 240 241 return 0; 242 243 poweroff: 244 regulator_disable(sharp->supply); 245 return err; 246 } 247 248 static int sharp_panel_enable(struct drm_panel *panel) 249 { 250 struct sharp_panel *sharp = to_sharp_panel(panel); 251 252 if (sharp->enabled) 253 return 0; 254 255 if (sharp->backlight) { 256 sharp->backlight->props.power = FB_BLANK_UNBLANK; 257 backlight_update_status(sharp->backlight); 258 } 259 260 sharp->enabled = true; 261 262 return 0; 263 } 264 265 static const struct drm_display_mode default_mode = { 266 .clock = 278000, 267 .hdisplay = 2560, 268 .hsync_start = 2560 + 128, 269 .hsync_end = 2560 + 128 + 64, 270 .htotal = 2560 + 128 + 64 + 64, 271 .vdisplay = 1600, 272 .vsync_start = 1600 + 4, 273 .vsync_end = 1600 + 4 + 8, 274 .vtotal = 1600 + 4 + 8 + 32, 275 .vrefresh = 60, 276 }; 277 278 static int sharp_panel_get_modes(struct drm_panel *panel) 279 { 280 struct drm_display_mode *mode; 281 282 mode = drm_mode_duplicate(panel->drm, &default_mode); 283 if (!mode) { 284 dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n", 285 default_mode.hdisplay, default_mode.vdisplay, 286 default_mode.vrefresh); 287 return -ENOMEM; 288 } 289 290 drm_mode_set_name(mode); 291 292 drm_mode_probed_add(panel->connector, mode); 293 294 panel->connector->display_info.width_mm = 217; 295 panel->connector->display_info.height_mm = 136; 296 297 return 1; 298 } 299 300 static const struct drm_panel_funcs sharp_panel_funcs = { 301 .disable = sharp_panel_disable, 302 .unprepare = sharp_panel_unprepare, 303 .prepare = sharp_panel_prepare, 304 .enable = sharp_panel_enable, 305 .get_modes = sharp_panel_get_modes, 306 }; 307 308 static const struct of_device_id sharp_of_match[] = { 309 { .compatible = "sharp,lq101r1sx01", }, 310 { } 311 }; 312 MODULE_DEVICE_TABLE(of, sharp_of_match); 313 314 static int sharp_panel_add(struct sharp_panel *sharp) 315 { 316 struct device_node *np; 317 int err; 318 319 sharp->mode = &default_mode; 320 321 sharp->supply = devm_regulator_get(&sharp->link1->dev, "power"); 322 if (IS_ERR(sharp->supply)) 323 return PTR_ERR(sharp->supply); 324 325 np = of_parse_phandle(sharp->link1->dev.of_node, "backlight", 0); 326 if (np) { 327 sharp->backlight = of_find_backlight_by_node(np); 328 of_node_put(np); 329 330 if (!sharp->backlight) 331 return -EPROBE_DEFER; 332 } 333 334 drm_panel_init(&sharp->base); 335 sharp->base.funcs = &sharp_panel_funcs; 336 sharp->base.dev = &sharp->link1->dev; 337 338 err = drm_panel_add(&sharp->base); 339 if (err < 0) 340 goto put_backlight; 341 342 return 0; 343 344 put_backlight: 345 if (sharp->backlight) 346 put_device(&sharp->backlight->dev); 347 348 return err; 349 } 350 351 static void sharp_panel_del(struct sharp_panel *sharp) 352 { 353 if (sharp->base.dev) 354 drm_panel_remove(&sharp->base); 355 356 if (sharp->backlight) 357 put_device(&sharp->backlight->dev); 358 359 if (sharp->link2) 360 put_device(&sharp->link2->dev); 361 } 362 363 static int sharp_panel_probe(struct mipi_dsi_device *dsi) 364 { 365 struct mipi_dsi_device *secondary = NULL; 366 struct sharp_panel *sharp; 367 struct device_node *np; 368 int err; 369 370 dsi->lanes = 4; 371 dsi->format = MIPI_DSI_FMT_RGB888; 372 dsi->mode_flags = MIPI_DSI_MODE_LPM; 373 374 /* Find DSI-LINK1 */ 375 np = of_parse_phandle(dsi->dev.of_node, "link2", 0); 376 if (np) { 377 secondary = of_find_mipi_dsi_device_by_node(np); 378 of_node_put(np); 379 380 if (!secondary) 381 return -EPROBE_DEFER; 382 } 383 384 /* register a panel for only the DSI-LINK1 interface */ 385 if (secondary) { 386 sharp = devm_kzalloc(&dsi->dev, sizeof(*sharp), GFP_KERNEL); 387 if (!sharp) { 388 put_device(&secondary->dev); 389 return -ENOMEM; 390 } 391 392 mipi_dsi_set_drvdata(dsi, sharp); 393 394 sharp->link2 = secondary; 395 sharp->link1 = dsi; 396 397 err = sharp_panel_add(sharp); 398 if (err < 0) { 399 put_device(&secondary->dev); 400 return err; 401 } 402 } 403 404 err = mipi_dsi_attach(dsi); 405 if (err < 0) { 406 if (secondary) 407 sharp_panel_del(sharp); 408 409 return err; 410 } 411 412 return 0; 413 } 414 415 static int sharp_panel_remove(struct mipi_dsi_device *dsi) 416 { 417 struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi); 418 int err; 419 420 /* only detach from host for the DSI-LINK2 interface */ 421 if (!sharp) { 422 mipi_dsi_detach(dsi); 423 return 0; 424 } 425 426 err = sharp_panel_disable(&sharp->base); 427 if (err < 0) 428 dev_err(&dsi->dev, "failed to disable panel: %d\n", err); 429 430 err = mipi_dsi_detach(dsi); 431 if (err < 0) 432 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err); 433 434 drm_panel_detach(&sharp->base); 435 sharp_panel_del(sharp); 436 437 return 0; 438 } 439 440 static void sharp_panel_shutdown(struct mipi_dsi_device *dsi) 441 { 442 struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi); 443 444 /* nothing to do for DSI-LINK2 */ 445 if (!sharp) 446 return; 447 448 sharp_panel_disable(&sharp->base); 449 } 450 451 static struct mipi_dsi_driver sharp_panel_driver = { 452 .driver = { 453 .name = "panel-sharp-lq101r1sx01", 454 .of_match_table = sharp_of_match, 455 }, 456 .probe = sharp_panel_probe, 457 .remove = sharp_panel_remove, 458 .shutdown = sharp_panel_shutdown, 459 }; 460 module_mipi_dsi_driver(sharp_panel_driver); 461 462 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); 463 MODULE_DESCRIPTION("Sharp LQ101R1SX01 panel driver"); 464 MODULE_LICENSE("GPL v2"); 465