1 /* 2 * Copyright (C) 2016 InforceComputing 3 * Author: Vinay Simha BN <simhavcs@gmail.com> 4 * 5 * Copyright (C) 2016 Linaro Ltd 6 * Author: Sumit Semwal <sumit.semwal@linaro.org> 7 * 8 * From internet archives, the panel for Nexus 7 2nd Gen, 2013 model is a 9 * JDI model LT070ME05000, and its data sheet is at: 10 * http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet 11 * 12 * This program is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU General Public License version 2 as published by 14 * the Free Software Foundation. 15 * 16 * This program is distributed in the hope that it will be useful, but WITHOUT 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 19 * more details. 20 * 21 * You should have received a copy of the GNU General Public License along with 22 * this program. If not, see <http://www.gnu.org/licenses/>. 23 */ 24 25 #include <linux/backlight.h> 26 #include <linux/delay.h> 27 #include <linux/gpio/consumer.h> 28 #include <linux/module.h> 29 #include <linux/of.h> 30 #include <linux/regulator/consumer.h> 31 32 #include <video/mipi_display.h> 33 34 #include <drm/drm_crtc.h> 35 #include <drm/drm_mipi_dsi.h> 36 #include <drm/drm_modes.h> 37 #include <drm/drm_panel.h> 38 39 static const char * const regulator_names[] = { 40 "vddp", 41 "iovcc" 42 }; 43 44 struct jdi_panel { 45 struct drm_panel base; 46 struct mipi_dsi_device *dsi; 47 48 struct regulator_bulk_data supplies[ARRAY_SIZE(regulator_names)]; 49 50 struct gpio_desc *enable_gpio; 51 struct gpio_desc *reset_gpio; 52 struct gpio_desc *dcdc_en_gpio; 53 struct backlight_device *backlight; 54 55 bool prepared; 56 bool enabled; 57 58 const struct drm_display_mode *mode; 59 }; 60 61 static inline struct jdi_panel *to_jdi_panel(struct drm_panel *panel) 62 { 63 return container_of(panel, struct jdi_panel, base); 64 } 65 66 static int jdi_panel_init(struct jdi_panel *jdi) 67 { 68 struct mipi_dsi_device *dsi = jdi->dsi; 69 struct device *dev = &jdi->dsi->dev; 70 int ret; 71 72 dsi->mode_flags |= MIPI_DSI_MODE_LPM; 73 74 ret = mipi_dsi_dcs_soft_reset(dsi); 75 if (ret < 0) 76 return ret; 77 78 usleep_range(10000, 20000); 79 80 ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT << 4); 81 if (ret < 0) { 82 dev_err(dev, "failed to set pixel format: %d\n", ret); 83 return ret; 84 } 85 86 ret = mipi_dsi_dcs_set_column_address(dsi, 0, jdi->mode->hdisplay - 1); 87 if (ret < 0) { 88 dev_err(dev, "failed to set column address: %d\n", ret); 89 return ret; 90 } 91 92 ret = mipi_dsi_dcs_set_page_address(dsi, 0, jdi->mode->vdisplay - 1); 93 if (ret < 0) { 94 dev_err(dev, "failed to set page address: %d\n", ret); 95 return ret; 96 } 97 98 /* 99 * BIT(5) BCTRL = 1 Backlight Control Block On, Brightness registers 100 * are active 101 * BIT(3) BL = 1 Backlight Control On 102 * BIT(2) DD = 0 Display Dimming is Off 103 */ 104 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 105 (u8[]){ 0x24 }, 1); 106 if (ret < 0) { 107 dev_err(dev, "failed to write control display: %d\n", ret); 108 return ret; 109 } 110 111 /* CABC off */ 112 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_POWER_SAVE, 113 (u8[]){ 0x00 }, 1); 114 if (ret < 0) { 115 dev_err(dev, "failed to set cabc off: %d\n", ret); 116 return ret; 117 } 118 119 ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 120 if (ret < 0) { 121 dev_err(dev, "failed to set exit sleep mode: %d\n", ret); 122 return ret; 123 } 124 125 msleep(120); 126 127 ret = mipi_dsi_generic_write(dsi, (u8[]){0xB0, 0x00}, 2); 128 if (ret < 0) { 129 dev_err(dev, "failed to set mcap: %d\n", ret); 130 return ret; 131 } 132 133 mdelay(10); 134 135 /* Interface setting, video mode */ 136 ret = mipi_dsi_generic_write(dsi, (u8[]) 137 {0xB3, 0x26, 0x08, 0x00, 0x20, 0x00}, 6); 138 if (ret < 0) { 139 dev_err(dev, "failed to set display interface setting: %d\n" 140 , ret); 141 return ret; 142 } 143 144 mdelay(20); 145 146 ret = mipi_dsi_generic_write(dsi, (u8[]){0xB0, 0x03}, 2); 147 if (ret < 0) { 148 dev_err(dev, "failed to set default values for mcap: %d\n" 149 , ret); 150 return ret; 151 } 152 153 return 0; 154 } 155 156 static int jdi_panel_on(struct jdi_panel *jdi) 157 { 158 struct mipi_dsi_device *dsi = jdi->dsi; 159 struct device *dev = &jdi->dsi->dev; 160 int ret; 161 162 dsi->mode_flags |= MIPI_DSI_MODE_LPM; 163 164 ret = mipi_dsi_dcs_set_display_on(dsi); 165 if (ret < 0) 166 dev_err(dev, "failed to set display on: %d\n", ret); 167 168 return ret; 169 } 170 171 static void jdi_panel_off(struct jdi_panel *jdi) 172 { 173 struct mipi_dsi_device *dsi = jdi->dsi; 174 struct device *dev = &jdi->dsi->dev; 175 int ret; 176 177 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; 178 179 ret = mipi_dsi_dcs_set_display_off(dsi); 180 if (ret < 0) 181 dev_err(dev, "failed to set display off: %d\n", ret); 182 183 ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 184 if (ret < 0) 185 dev_err(dev, "failed to enter sleep mode: %d\n", ret); 186 187 msleep(100); 188 } 189 190 static int jdi_panel_disable(struct drm_panel *panel) 191 { 192 struct jdi_panel *jdi = to_jdi_panel(panel); 193 194 if (!jdi->enabled) 195 return 0; 196 197 backlight_disable(jdi->backlight); 198 199 jdi->enabled = false; 200 201 return 0; 202 } 203 204 static int jdi_panel_unprepare(struct drm_panel *panel) 205 { 206 struct jdi_panel *jdi = to_jdi_panel(panel); 207 struct device *dev = &jdi->dsi->dev; 208 int ret; 209 210 if (!jdi->prepared) 211 return 0; 212 213 jdi_panel_off(jdi); 214 215 ret = regulator_bulk_disable(ARRAY_SIZE(jdi->supplies), jdi->supplies); 216 if (ret < 0) 217 dev_err(dev, "regulator disable failed, %d\n", ret); 218 219 gpiod_set_value(jdi->enable_gpio, 0); 220 221 gpiod_set_value(jdi->reset_gpio, 1); 222 223 gpiod_set_value(jdi->dcdc_en_gpio, 0); 224 225 jdi->prepared = false; 226 227 return 0; 228 } 229 230 static int jdi_panel_prepare(struct drm_panel *panel) 231 { 232 struct jdi_panel *jdi = to_jdi_panel(panel); 233 struct device *dev = &jdi->dsi->dev; 234 int ret; 235 236 if (jdi->prepared) 237 return 0; 238 239 ret = regulator_bulk_enable(ARRAY_SIZE(jdi->supplies), jdi->supplies); 240 if (ret < 0) { 241 dev_err(dev, "regulator enable failed, %d\n", ret); 242 return ret; 243 } 244 245 msleep(20); 246 247 gpiod_set_value(jdi->dcdc_en_gpio, 1); 248 usleep_range(10, 20); 249 250 gpiod_set_value(jdi->reset_gpio, 0); 251 usleep_range(10, 20); 252 253 gpiod_set_value(jdi->enable_gpio, 1); 254 usleep_range(10, 20); 255 256 ret = jdi_panel_init(jdi); 257 if (ret < 0) { 258 dev_err(dev, "failed to init panel: %d\n", ret); 259 goto poweroff; 260 } 261 262 ret = jdi_panel_on(jdi); 263 if (ret < 0) { 264 dev_err(dev, "failed to set panel on: %d\n", ret); 265 goto poweroff; 266 } 267 268 jdi->prepared = true; 269 270 return 0; 271 272 poweroff: 273 ret = regulator_bulk_disable(ARRAY_SIZE(jdi->supplies), jdi->supplies); 274 if (ret < 0) 275 dev_err(dev, "regulator disable failed, %d\n", ret); 276 277 gpiod_set_value(jdi->enable_gpio, 0); 278 279 gpiod_set_value(jdi->reset_gpio, 1); 280 281 gpiod_set_value(jdi->dcdc_en_gpio, 0); 282 283 return ret; 284 } 285 286 static int jdi_panel_enable(struct drm_panel *panel) 287 { 288 struct jdi_panel *jdi = to_jdi_panel(panel); 289 290 if (jdi->enabled) 291 return 0; 292 293 backlight_enable(jdi->backlight); 294 295 jdi->enabled = true; 296 297 return 0; 298 } 299 300 static const struct drm_display_mode default_mode = { 301 .clock = 155493, 302 .hdisplay = 1200, 303 .hsync_start = 1200 + 48, 304 .hsync_end = 1200 + 48 + 32, 305 .htotal = 1200 + 48 + 32 + 60, 306 .vdisplay = 1920, 307 .vsync_start = 1920 + 3, 308 .vsync_end = 1920 + 3 + 5, 309 .vtotal = 1920 + 3 + 5 + 6, 310 .vrefresh = 60, 311 .flags = 0, 312 }; 313 314 static int jdi_panel_get_modes(struct drm_panel *panel) 315 { 316 struct drm_display_mode *mode; 317 struct jdi_panel *jdi = to_jdi_panel(panel); 318 struct device *dev = &jdi->dsi->dev; 319 320 mode = drm_mode_duplicate(panel->drm, &default_mode); 321 if (!mode) { 322 dev_err(dev, "failed to add mode %ux%ux@%u\n", 323 default_mode.hdisplay, default_mode.vdisplay, 324 default_mode.vrefresh); 325 return -ENOMEM; 326 } 327 328 drm_mode_set_name(mode); 329 330 drm_mode_probed_add(panel->connector, mode); 331 332 panel->connector->display_info.width_mm = 95; 333 panel->connector->display_info.height_mm = 151; 334 335 return 1; 336 } 337 338 static int dsi_dcs_bl_get_brightness(struct backlight_device *bl) 339 { 340 struct mipi_dsi_device *dsi = bl_get_data(bl); 341 int ret; 342 u16 brightness = bl->props.brightness; 343 344 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; 345 346 ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness); 347 if (ret < 0) 348 return ret; 349 350 dsi->mode_flags |= MIPI_DSI_MODE_LPM; 351 352 return brightness & 0xff; 353 } 354 355 static int dsi_dcs_bl_update_status(struct backlight_device *bl) 356 { 357 struct mipi_dsi_device *dsi = bl_get_data(bl); 358 int ret; 359 360 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; 361 362 ret = mipi_dsi_dcs_set_display_brightness(dsi, bl->props.brightness); 363 if (ret < 0) 364 return ret; 365 366 dsi->mode_flags |= MIPI_DSI_MODE_LPM; 367 368 return 0; 369 } 370 371 static const struct backlight_ops dsi_bl_ops = { 372 .update_status = dsi_dcs_bl_update_status, 373 .get_brightness = dsi_dcs_bl_get_brightness, 374 }; 375 376 static struct backlight_device * 377 drm_panel_create_dsi_backlight(struct mipi_dsi_device *dsi) 378 { 379 struct device *dev = &dsi->dev; 380 struct backlight_properties props; 381 382 memset(&props, 0, sizeof(props)); 383 props.type = BACKLIGHT_RAW; 384 props.brightness = 255; 385 props.max_brightness = 255; 386 387 return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, 388 &dsi_bl_ops, &props); 389 } 390 391 static const struct drm_panel_funcs jdi_panel_funcs = { 392 .disable = jdi_panel_disable, 393 .unprepare = jdi_panel_unprepare, 394 .prepare = jdi_panel_prepare, 395 .enable = jdi_panel_enable, 396 .get_modes = jdi_panel_get_modes, 397 }; 398 399 static const struct of_device_id jdi_of_match[] = { 400 { .compatible = "jdi,lt070me05000", }, 401 { } 402 }; 403 MODULE_DEVICE_TABLE(of, jdi_of_match); 404 405 static int jdi_panel_add(struct jdi_panel *jdi) 406 { 407 struct device *dev = &jdi->dsi->dev; 408 int ret; 409 unsigned int i; 410 411 jdi->mode = &default_mode; 412 413 for (i = 0; i < ARRAY_SIZE(jdi->supplies); i++) 414 jdi->supplies[i].supply = regulator_names[i]; 415 416 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(jdi->supplies), 417 jdi->supplies); 418 if (ret < 0) { 419 dev_err(dev, "failed to init regulator, ret=%d\n", ret); 420 return ret; 421 } 422 423 jdi->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); 424 if (IS_ERR(jdi->enable_gpio)) { 425 ret = PTR_ERR(jdi->enable_gpio); 426 dev_err(dev, "cannot get enable-gpio %d\n", ret); 427 return ret; 428 } 429 430 jdi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); 431 if (IS_ERR(jdi->reset_gpio)) { 432 ret = PTR_ERR(jdi->reset_gpio); 433 dev_err(dev, "cannot get reset-gpios %d\n", ret); 434 return ret; 435 } 436 437 jdi->dcdc_en_gpio = devm_gpiod_get(dev, "dcdc-en", GPIOD_OUT_LOW); 438 if (IS_ERR(jdi->dcdc_en_gpio)) { 439 ret = PTR_ERR(jdi->dcdc_en_gpio); 440 dev_err(dev, "cannot get dcdc-en-gpio %d\n", ret); 441 return ret; 442 } 443 444 jdi->backlight = drm_panel_create_dsi_backlight(jdi->dsi); 445 if (IS_ERR(jdi->backlight)) { 446 ret = PTR_ERR(jdi->backlight); 447 dev_err(dev, "failed to register backlight %d\n", ret); 448 return ret; 449 } 450 451 drm_panel_init(&jdi->base); 452 jdi->base.funcs = &jdi_panel_funcs; 453 jdi->base.dev = &jdi->dsi->dev; 454 455 ret = drm_panel_add(&jdi->base); 456 457 return ret; 458 } 459 460 static void jdi_panel_del(struct jdi_panel *jdi) 461 { 462 if (jdi->base.dev) 463 drm_panel_remove(&jdi->base); 464 } 465 466 static int jdi_panel_probe(struct mipi_dsi_device *dsi) 467 { 468 struct jdi_panel *jdi; 469 int ret; 470 471 dsi->lanes = 4; 472 dsi->format = MIPI_DSI_FMT_RGB888; 473 dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | 474 MIPI_DSI_CLOCK_NON_CONTINUOUS; 475 476 jdi = devm_kzalloc(&dsi->dev, sizeof(*jdi), GFP_KERNEL); 477 if (!jdi) 478 return -ENOMEM; 479 480 mipi_dsi_set_drvdata(dsi, jdi); 481 482 jdi->dsi = dsi; 483 484 ret = jdi_panel_add(jdi); 485 if (ret < 0) 486 return ret; 487 488 return mipi_dsi_attach(dsi); 489 } 490 491 static int jdi_panel_remove(struct mipi_dsi_device *dsi) 492 { 493 struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi); 494 int ret; 495 496 ret = jdi_panel_disable(&jdi->base); 497 if (ret < 0) 498 dev_err(&dsi->dev, "failed to disable panel: %d\n", ret); 499 500 ret = mipi_dsi_detach(dsi); 501 if (ret < 0) 502 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", 503 ret); 504 505 jdi_panel_del(jdi); 506 507 return 0; 508 } 509 510 static void jdi_panel_shutdown(struct mipi_dsi_device *dsi) 511 { 512 struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi); 513 514 jdi_panel_disable(&jdi->base); 515 } 516 517 static struct mipi_dsi_driver jdi_panel_driver = { 518 .driver = { 519 .name = "panel-jdi-lt070me05000", 520 .of_match_table = jdi_of_match, 521 }, 522 .probe = jdi_panel_probe, 523 .remove = jdi_panel_remove, 524 .shutdown = jdi_panel_shutdown, 525 }; 526 module_mipi_dsi_driver(jdi_panel_driver); 527 528 MODULE_AUTHOR("Sumit Semwal <sumit.semwal@linaro.org>"); 529 MODULE_AUTHOR("Vinay Simha BN <simhavcs@gmail.com>"); 530 MODULE_DESCRIPTION("JDI LT070ME05000 WUXGA"); 531 MODULE_LICENSE("GPL v2"); 532