// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2014 Google, Inc. * * Copyright (C) 2022 Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt> * * Adapted from the downstream Pixel C driver written by Sean Paul
*/
ret = mipi_dsi_dcs_set_display_off(jdi->link1); if (ret < 0)
dev_err(panel->dev, "failed to set display off: %d\n", ret);
ret = mipi_dsi_dcs_set_display_off(jdi->link2); if (ret < 0)
dev_err(panel->dev, "failed to set display off: %d\n", ret);
/* Specified by JDI @ 50ms, subject to change */
msleep(50);
ret = mipi_dsi_dcs_enter_sleep_mode(jdi->link1); if (ret < 0)
dev_err(panel->dev, "failed to enter sleep mode: %d\n", ret);
ret = mipi_dsi_dcs_enter_sleep_mode(jdi->link2); if (ret < 0)
dev_err(panel->dev, "failed to enter sleep mode: %d\n", ret);
/* Specified by JDI @ 150ms, subject to change */
msleep(150);
gpiod_set_value(jdi->reset_gpio, 1);
/* T4 = 1ms */
usleep_range(1000, 3000);
gpiod_set_value(jdi->enable_gpio, 0);
/* T5 = 2ms */
usleep_range(2000, 4000);
regulator_disable(jdi->ddi_supply);
/* T6 = 2ms plus some time to discharge capacitors */
usleep_range(7000, 9000);
regulator_disable(jdi->supply); /* Specified by JDI @ 20ms, subject to change */
msleep(20);
/* Disable backlight to avoid showing random pixels * with a conservative delay for it to take effect.
*/
backlight_disable(jdi->backlight);
jdi_wait_frames(jdi, 3);
gpiod_set_value(jdi->enable_gpio, 1); /* T3 = 10ms */
usleep_range(10000, 15000);
gpiod_set_value(jdi->reset_gpio, 0); /* Specified by JDI @ 3ms, subject to change */
usleep_range(3000, 5000);
/* * TODO: The device supports both left-right and even-odd split * configurations, but this driver currently supports only the left- * right split. To support a different mode a mechanism needs to be * put in place to communicate the configuration back to the DSI host * controller.
*/
err = jdi_setup_symmetrical_split(jdi->link1, jdi->link2,
jdi->mode); if (err < 0) {
dev_err(panel->dev, "failed to set up symmetrical split: %d\n",
err); goto poweroff;
}
err = mipi_dsi_dcs_set_tear_scanline(jdi->link1,
jdi->mode->vdisplay - 16); if (err < 0) {
dev_err(panel->dev, "failed to set tear scanline: %d\n", err); goto poweroff;
}
err = mipi_dsi_dcs_set_tear_scanline(jdi->link2,
jdi->mode->vdisplay - 16); if (err < 0) {
dev_err(panel->dev, "failed to set tear scanline: %d\n", err); goto poweroff;
}
err = mipi_dsi_dcs_set_tear_on(jdi->link1,
MIPI_DSI_DCS_TEAR_MODE_VBLANK); if (err < 0) {
dev_err(panel->dev, "failed to set tear on: %d\n", err); goto poweroff;
}
err = mipi_dsi_dcs_set_tear_on(jdi->link2,
MIPI_DSI_DCS_TEAR_MODE_VBLANK); if (err < 0) {
dev_err(panel->dev, "failed to set tear on: %d\n", err); goto poweroff;
}
err = mipi_dsi_dcs_set_pixel_format(jdi->link1, MIPI_DCS_PIXEL_FMT_24BIT); if (err < 0) {
dev_err(panel->dev, "failed to set pixel format: %d\n", err); goto poweroff;
}
err = mipi_dsi_dcs_set_pixel_format(jdi->link2, MIPI_DCS_PIXEL_FMT_24BIT); if (err < 0) {
dev_err(panel->dev, "failed to set pixel format: %d\n", err); goto poweroff;
}
err = mipi_dsi_dcs_exit_sleep_mode(jdi->link1); if (err < 0) {
dev_err(panel->dev, "failed to exit sleep mode: %d\n", err); goto poweroff;
}
err = mipi_dsi_dcs_exit_sleep_mode(jdi->link2); if (err < 0) {
dev_err(panel->dev, "failed to exit sleep mode: %d\n", err); goto poweroff;
}
err = jdi_write_dcdc_registers(jdi); if (err < 0) {
dev_err(panel->dev, "failed to write dcdc registers: %d\n", err); goto poweroff;
} /* * We need to wait 150ms between mipi_dsi_dcs_exit_sleep_mode() and * mipi_dsi_dcs_set_display_on().
*/
msleep(150);
err = mipi_dsi_dcs_set_display_on(jdi->link1); if (err < 0) {
dev_err(panel->dev, "failed to set display on: %d\n", err); goto poweroff;
}
err = mipi_dsi_dcs_set_display_on(jdi->link2); if (err < 0) {
dev_err(panel->dev, "failed to set display on: %d\n", err); goto poweroff;
}
/* T6 = 2ms plus some time to discharge capacitors */
usleep_range(7000, 9000);
supply_off:
regulator_disable(jdi->supply); /* Specified by JDI @ 20ms, subject to change */
msleep(20);
jdi->supply = devm_regulator_get(dev, "power"); if (IS_ERR(jdi->supply)) return dev_err_probe(dev, PTR_ERR(jdi->supply), "failed to get power regulator\n");
jdi->ddi_supply = devm_regulator_get(dev, "ddi"); if (IS_ERR(jdi->ddi_supply)) return dev_err_probe(dev, PTR_ERR(jdi->ddi_supply), "failed to get ddi regulator\n");
jdi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(jdi->reset_gpio)) return dev_err_probe(dev, PTR_ERR(jdi->reset_gpio), "failed to get reset gpio\n"); /* T4 = 1ms */
usleep_range(1000, 3000);
jdi->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(jdi->enable_gpio)) return dev_err_probe(dev, PTR_ERR(jdi->enable_gpio), "failed to get enable gpio\n"); /* T5 = 2ms */
usleep_range(2000, 4000);
jdi->backlight = devm_of_find_backlight(dev); if (IS_ERR(jdi->backlight)) return dev_err_probe(dev, PTR_ERR(jdi->backlight), "failed to create backlight\n");
drm_panel_add(&jdi->base);
return 0;
}
staticvoid jdi_panel_del(struct jdi_panel *jdi)
{ if (jdi->base.dev)
drm_panel_remove(&jdi->base);
/* register a panel for only the DSI-LINK1 interface */ if (secondary) {
jdi = devm_drm_panel_alloc(&dsi->dev, __typeof(*jdi),
base, &jdi_panel_funcs,
DRM_MODE_CONNECTOR_DSI);
if (IS_ERR(jdi)) {
put_device(&secondary->dev); return PTR_ERR(jdi);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.