// SPDX-License-Identifier: GPL-2.0 /* * Panel driver for the WideChips WS2401 480x800 DPI RGB panel, used in * the Samsung Mobile Display (SMD) LMS380KF01. * Found in the Samsung Galaxy Ace 2 GT-I8160 mobile phone. * Linus Walleij <linus.walleij@linaro.org> * Inspired by code and know-how in the vendor driver by Gareth Phillips.
*/ #include <drm/drm_mipi_dbi.h> #include <drm/drm_modes.h> #include <drm/drm_panel.h>
/** * struct ws2401 - state container for a panel controlled by the WS2401 * controller
*/ struct ws2401 { /** @dev: the container device */ struct device *dev; /** @dbi: the DBI bus abstraction handle */ struct mipi_dbi dbi; /** @panel: the DRM panel instance for this device */ struct drm_panel panel; /** @width: the width of this panel in mm */
u32 width; /** @height: the height of this panel in mm */
u32 height; /** @reset: reset GPIO line */ struct gpio_desc *reset; /** @regulators: VCCIO and VIO supply regulators */ struct regulator_bulk_data regulators[2]; /** @internal_bl: If using internal backlight */ bool internal_bl;
};
/* Power up */
ret = regulator_bulk_enable(ARRAY_SIZE(ws->regulators),
ws->regulators); if (ret) {
dev_err(ws->dev, "failed to enable regulators: %d\n", ret); return ret;
}
msleep(10);
if (ws->internal_bl) {
mipi_dbi_command(dbi, WS2401_WRCTRLD, 0x2c);
} else {
mipi_dbi_command(dbi, WS2401_WRCTRLD, 0x00); /* * When not using internal backlight we do not need any further * L2 accesses to the panel so we close the door on our way out. * Otherwise we need to leave the L2 door open.
*/
mipi_dbi_command(dbi, WS2401_PASSWD1, 0xa5, 0xa5);
}
return 0;
}
staticint ws2401_power_off(struct ws2401 *ws)
{ /* Go into RESET and disable regulators */
gpiod_set_value_cansleep(ws->reset, 1); return regulator_bulk_disable(ARRAY_SIZE(ws->regulators),
ws->regulators);
}
/* Make sure we disable backlight, if any */ if (ws->internal_bl)
mipi_dbi_command(dbi, WS2401_WRCTRLD, 0x00);
mipi_dbi_command(dbi, MIPI_DCS_ENTER_SLEEP_MODE);
msleep(120); return ws2401_power_off(to_ws2401(panel));
}
/** * ws2401_get_modes() - return the mode * @panel: the panel to get the mode for * @connector: reference to the central DRM connector control structure
*/ staticint ws2401_get_modes(struct drm_panel *panel, struct drm_connector *connector)
{ struct ws2401 *ws = to_ws2401(panel); struct drm_display_mode *mode; staticconst u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
/* * We just support the LMS380KF01 so far, if we implement more panels * this mode, the following connector display_info settings and * probably the custom DCS sequences needs to selected based on what * the target panel needs.
*/
mode = drm_mode_duplicate(connector->dev, &lms380kf01_480_800_mode); if (!mode) {
dev_err(ws->dev, "failed to add mode\n"); return -ENOMEM;
}
/* * VCI is the analog voltage supply * VCCIO is the digital I/O voltage supply
*/
ws->regulators[0].supply = "vci";
ws->regulators[1].supply = "vccio";
ret = devm_regulator_bulk_get(dev,
ARRAY_SIZE(ws->regulators),
ws->regulators); if (ret) return dev_err_probe(dev, ret, "failed to get regulators\n");
ws->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ws->reset)) {
ret = PTR_ERR(ws->reset); return dev_err_probe(dev, ret, "no RESET GPIO\n");
}
ret = mipi_dbi_spi_init(spi, &ws->dbi, NULL); if (ret) return dev_err_probe(dev, ret, "MIPI DBI init failed\n");
ws->dbi.read_commands = ws2401_dbi_read_commands;
/* * Samsung LMS380KF01 is the one instance of this display controller that we * know about, but if more are found, the controller can be parameterized * here and used for other configurations.
*/ staticconststruct of_device_id ws2401_match[] = {
{ .compatible = "samsung,lms380kf01", },
{},
};
MODULE_DEVICE_TABLE(of, ws2401_match);
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.