Lines Matching +full:panel +full:- +full:dsi
1 // SPDX-License-Identifier: GPL-2.0+
3 * MIPI-DSI Novatek NT35560-based panel controller.
6 * Sony ACX424AKM - a 480x854 AMOLED DSI panel
7 * Sony ACX424AKP - a 480x864 AMOLED DSI panel
9 * Copyright (C) Linaro Ltd. 2019-2021
11 * Based on code and know-how from Marcus Lorentzon
12 * Copyright (C) ST-Ericsson SA 2010
13 * Based on code and know-how from Johan Olson and Joakim Wesslen
42 * and panel 00 ... seems like default values.
53 struct drm_panel panel; member
140 static inline struct nt35560 *panel_to_nt35560(struct drm_panel *panel) in panel_to_nt35560() argument
142 return container_of(panel, struct nt35560, panel); in panel_to_nt35560()
151 struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev); in nt35560_set_brightness() local
153 int duty_ns = bl->props.brightness; in nt35560_set_brightness()
162 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, in nt35560_set_brightness()
165 dev_err(nt->dev, "failed to disable display backlight (%d)\n", ret); in nt35560_set_brightness()
172 pwm_ratio = max(((duty_ns * 256) / period_ns) - 1, 1); in nt35560_set_brightness()
178 dev_dbg(nt->dev, "calculated duty cycle %02x\n", pwm_ratio); in nt35560_set_brightness()
179 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, in nt35560_set_brightness()
182 dev_err(nt->dev, "failed to set display PWM ratio (%d)\n", ret); in nt35560_set_brightness()
196 ret = mipi_dsi_dcs_write(dsi, 0xf3, &par, 1); in nt35560_set_brightness()
198 dev_err(nt->dev, "failed to unlock CMD 2 (%d)\n", ret); in nt35560_set_brightness()
202 ret = mipi_dsi_dcs_write(dsi, 0x00, &par, 1); in nt35560_set_brightness()
204 dev_err(nt->dev, "failed to enter page 1 (%d)\n", ret); in nt35560_set_brightness()
208 ret = mipi_dsi_dcs_write(dsi, 0x7d, &par, 1); in nt35560_set_brightness()
210 dev_err(nt->dev, "failed to disable MTP reload (%d)\n", ret); in nt35560_set_brightness()
213 ret = mipi_dsi_dcs_write(dsi, 0x22, &pwm_div, 1); in nt35560_set_brightness()
215 dev_err(nt->dev, "failed to set PWM divisor (%d)\n", ret); in nt35560_set_brightness()
219 ret = mipi_dsi_dcs_write(dsi, 0x7f, &par, 1); in nt35560_set_brightness()
221 dev_err(nt->dev, "failed to lock CMD 2 (%d)\n", ret); in nt35560_set_brightness()
227 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, in nt35560_set_brightness()
230 dev_err(nt->dev, "failed to enable display backlight (%d)\n", ret); in nt35560_set_brightness()
249 struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev); in nt35560_read_id() local
250 u8 vendor, version, panel; in nt35560_read_id() local
254 ret = mipi_dsi_dcs_read(dsi, NT35560_DCS_READ_ID1, &vendor, 1); in nt35560_read_id()
256 dev_err(nt->dev, "could not vendor ID byte\n"); in nt35560_read_id()
259 ret = mipi_dsi_dcs_read(dsi, NT35560_DCS_READ_ID2, &version, 1); in nt35560_read_id()
261 dev_err(nt->dev, "could not read device version byte\n"); in nt35560_read_id()
264 ret = mipi_dsi_dcs_read(dsi, NT35560_DCS_READ_ID3, &panel, 1); in nt35560_read_id()
266 dev_err(nt->dev, "could not read panel ID byte\n"); in nt35560_read_id()
271 dev_err(nt->dev, "device vendor ID is zero\n"); in nt35560_read_id()
272 return -ENODEV; in nt35560_read_id()
275 val = (vendor << 8) | panel; in nt35560_read_id()
281 dev_info(nt->dev, "MTP vendor: %02x, version: %02x, panel: %02x\n", in nt35560_read_id()
282 vendor, version, panel); in nt35560_read_id()
285 dev_info(nt->dev, "unknown vendor: %02x, version: %02x, panel: %02x\n", in nt35560_read_id()
286 vendor, version, panel); in nt35560_read_id()
297 ret = regulator_enable(nt->supply); in nt35560_power_on()
299 dev_err(nt->dev, "failed to enable supply (%d)\n", ret); in nt35560_power_on()
304 gpiod_set_value_cansleep(nt->reset_gpio, 1); in nt35560_power_on()
306 /* De-assert RESET */ in nt35560_power_on()
307 gpiod_set_value_cansleep(nt->reset_gpio, 0); in nt35560_power_on()
316 gpiod_set_value_cansleep(nt->reset_gpio, 1); in nt35560_power_off()
319 regulator_disable(nt->supply); in nt35560_power_off()
322 static int nt35560_prepare(struct drm_panel *panel) in nt35560_prepare() argument
324 struct nt35560 *nt = panel_to_nt35560(panel); in nt35560_prepare()
325 struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev); in nt35560_prepare() local
335 dev_err(nt->dev, "failed to read panel ID (%d)\n", ret); in nt35560_prepare()
340 ret = mipi_dsi_dcs_set_tear_on(dsi, in nt35560_prepare()
343 dev_err(nt->dev, "failed to enable vblank TE (%d)\n", ret); in nt35560_prepare()
351 * selects DSI, similar code is found in other drivers such as the in nt35560_prepare()
352 * Sharp LS043T1LE01 which makes us suspect that this panel may be in nt35560_prepare()
357 ret = mipi_dsi_dcs_write(dsi, NT35560_DCS_SET_MDDI, in nt35560_prepare()
360 dev_err(nt->dev, "failed to set MDDI (%d)\n", ret); in nt35560_prepare()
365 ret = mipi_dsi_dcs_exit_sleep_mode(dsi); in nt35560_prepare()
367 dev_err(nt->dev, "failed to exit sleep mode (%d)\n", ret); in nt35560_prepare()
372 ret = mipi_dsi_dcs_set_display_on(dsi); in nt35560_prepare()
374 dev_err(nt->dev, "failed to turn display on (%d)\n", ret); in nt35560_prepare()
377 if (nt->video_mode) { in nt35560_prepare()
379 ret = mipi_dsi_turn_on_peripheral(dsi); in nt35560_prepare()
381 dev_err(nt->dev, "failed to turn on peripheral\n"); in nt35560_prepare()
393 static int nt35560_unprepare(struct drm_panel *panel) in nt35560_unprepare() argument
395 struct nt35560 *nt = panel_to_nt35560(panel); in nt35560_unprepare()
396 struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev); in nt35560_unprepare() local
399 ret = mipi_dsi_dcs_set_display_off(dsi); in nt35560_unprepare()
401 dev_err(nt->dev, "failed to turn display off (%d)\n", ret); in nt35560_unprepare()
406 ret = mipi_dsi_dcs_enter_sleep_mode(dsi); in nt35560_unprepare()
408 dev_err(nt->dev, "failed to enter sleep mode (%d)\n", ret); in nt35560_unprepare()
419 static int nt35560_get_modes(struct drm_panel *panel, in nt35560_get_modes() argument
422 struct nt35560 *nt = panel_to_nt35560(panel); in nt35560_get_modes()
423 const struct nt35560_config *conf = nt->conf; in nt35560_get_modes()
426 if (nt->video_mode) in nt35560_get_modes()
427 mode = drm_mode_duplicate(connector->dev, in nt35560_get_modes()
428 conf->vid_mode); in nt35560_get_modes()
430 mode = drm_mode_duplicate(connector->dev, in nt35560_get_modes()
431 conf->cmd_mode); in nt35560_get_modes()
433 dev_err(panel->dev, "bad mode or failed to add mode\n"); in nt35560_get_modes()
434 return -EINVAL; in nt35560_get_modes()
437 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; in nt35560_get_modes()
439 connector->display_info.width_mm = mode->width_mm; in nt35560_get_modes()
440 connector->display_info.height_mm = mode->height_mm; in nt35560_get_modes()
453 static int nt35560_probe(struct mipi_dsi_device *dsi) in nt35560_probe() argument
455 struct device *dev = &dsi->dev; in nt35560_probe()
461 return -ENOMEM; in nt35560_probe()
462 nt->video_mode = of_property_read_bool(dev->of_node, in nt35560_probe()
463 "enforce-video-mode"); in nt35560_probe()
465 mipi_dsi_set_drvdata(dsi, nt); in nt35560_probe()
466 nt->dev = dev; in nt35560_probe()
468 nt->conf = of_device_get_match_data(dev); in nt35560_probe()
469 if (!nt->conf) { in nt35560_probe()
471 return -ENODEV; in nt35560_probe()
474 dsi->lanes = 2; in nt35560_probe()
475 dsi->format = MIPI_DSI_FMT_RGB888; in nt35560_probe()
477 * FIXME: these come from the ST-Ericsson vendor driver for the in nt35560_probe()
479 * platform, if you have the datasheet, please cross-check the in nt35560_probe()
482 dsi->lp_rate = 19200000; in nt35560_probe()
483 dsi->hs_rate = 420160000; in nt35560_probe()
485 if (nt->video_mode) in nt35560_probe()
487 dsi->mode_flags = in nt35560_probe()
491 dsi->mode_flags = in nt35560_probe()
494 nt->supply = devm_regulator_get(dev, "vddi"); in nt35560_probe()
495 if (IS_ERR(nt->supply)) in nt35560_probe()
496 return PTR_ERR(nt->supply); in nt35560_probe()
499 nt->reset_gpio = devm_gpiod_get_optional(dev, "reset", in nt35560_probe()
501 if (IS_ERR(nt->reset_gpio)) in nt35560_probe()
502 return dev_err_probe(dev, PTR_ERR(nt->reset_gpio), in nt35560_probe()
505 drm_panel_init(&nt->panel, dev, &nt35560_drm_funcs, in nt35560_probe()
508 nt->panel.backlight = devm_backlight_device_register(dev, "nt35560", dev, nt, in nt35560_probe()
510 if (IS_ERR(nt->panel.backlight)) in nt35560_probe()
511 return dev_err_probe(dev, PTR_ERR(nt->panel.backlight), in nt35560_probe()
514 drm_panel_add(&nt->panel); in nt35560_probe()
516 ret = mipi_dsi_attach(dsi); in nt35560_probe()
518 drm_panel_remove(&nt->panel); in nt35560_probe()
525 static void nt35560_remove(struct mipi_dsi_device *dsi) in nt35560_remove() argument
527 struct nt35560 *nt = mipi_dsi_get_drvdata(dsi); in nt35560_remove()
529 mipi_dsi_detach(dsi); in nt35560_remove()
530 drm_panel_remove(&nt->panel); in nt35560_remove()
550 .name = "panel-novatek-nt35560",
557 MODULE_DESCRIPTION("MIPI-DSI Novatek NT35560 Panel Driver");