123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * Copyright (C) 2020 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
- #include <common.h>
- #include <backlight.h>
- #include <dm.h>
- #include <mipi_dsi.h>
- #include <panel.h>
- #include <asm/gpio.h>
- #include <dm/device_compat.h>
- #include <linux/delay.h>
- #include <power/regulator.h>
- struct tl070wsh30_panel_priv {
- struct udevice *reg;
- struct udevice *backlight;
- struct gpio_desc reset;
- };
- static const struct display_timing default_timing = {
- .pixelclock.typ = 47250000,
- .hactive.typ = 1024,
- .hfront_porch.typ = 46,
- .hback_porch.typ = 100,
- .hsync_len.typ = 80,
- .vactive.typ = 600,
- .vfront_porch.typ = 5,
- .vback_porch.typ = 20,
- .vsync_len.typ = 5,
- .flags = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH,
- };
- static int tl070wsh30_panel_enable_backlight(struct udevice *dev)
- {
- struct mipi_dsi_panel_plat *plat = dev_get_plat(dev);
- struct mipi_dsi_device *device = plat->device;
- struct tl070wsh30_panel_priv *priv = dev_get_priv(dev);
- int ret;
- ret = mipi_dsi_attach(device);
- if (ret < 0)
- return ret;
- ret = mipi_dsi_dcs_exit_sleep_mode(device);
- if (ret)
- return ret;
- mdelay(200);
- ret = mipi_dsi_dcs_set_display_on(device);
- if (ret)
- return ret;
- mdelay(20);
- ret = backlight_enable(priv->backlight);
- if (ret)
- return ret;
- return 0;
- }
- static int tl070wsh30_panel_get_display_timing(struct udevice *dev,
- struct display_timing *timings)
- {
- memcpy(timings, &default_timing, sizeof(*timings));
- return 0;
- }
- static int tl070wsh30_panel_of_to_plat(struct udevice *dev)
- {
- struct tl070wsh30_panel_priv *priv = dev_get_priv(dev);
- int ret;
- if (IS_ENABLED(CONFIG_DM_REGULATOR)) {
- ret = device_get_supply_regulator(dev, "power-supply",
- &priv->reg);
- if (ret && ret != -ENOENT) {
- dev_err(dev, "Warning: cannot get power supply\n");
- return ret;
- }
- }
- ret = gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset,
- GPIOD_IS_OUT);
- if (ret) {
- dev_err(dev, "Warning: cannot get reset GPIO\n");
- if (ret != -ENOENT)
- return ret;
- }
- ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
- "backlight", &priv->backlight);
- if (ret) {
- dev_err(dev, "Cannot get backlight: ret=%d\n", ret);
- return ret;
- }
- return 0;
- }
- static int tl070wsh30_panel_probe(struct udevice *dev)
- {
- struct tl070wsh30_panel_priv *priv = dev_get_priv(dev);
- struct mipi_dsi_panel_plat *plat = dev_get_plat(dev);
- int ret;
- if (IS_ENABLED(CONFIG_DM_REGULATOR) && priv->reg) {
- ret = regulator_set_enable(priv->reg, true);
- if (ret)
- return ret;
- }
- mdelay(10);
- /* reset panel */
- dm_gpio_set_value(&priv->reset, true);
-
- mdelay(10);
- dm_gpio_set_value(&priv->reset, false);
- /* fill characteristics of DSI data link */
- plat->lanes = 4;
- plat->format = MIPI_DSI_FMT_RGB888;
- plat->mode_flags = MIPI_DSI_MODE_VIDEO |
- MIPI_DSI_MODE_VIDEO_BURST |
- MIPI_DSI_MODE_LPM;
- return 0;
- }
- static const struct panel_ops tl070wsh30_panel_ops = {
- .enable_backlight = tl070wsh30_panel_enable_backlight,
- .get_display_timing = tl070wsh30_panel_get_display_timing,
- };
- static const struct udevice_id tl070wsh30_panel_ids[] = {
- { .compatible = "tdo,tl070wsh30" },
- { }
- };
- U_BOOT_DRIVER(tl070wsh30_panel) = {
- .name = "tl070wsh30_panel",
- .id = UCLASS_PANEL,
- .of_match = tl070wsh30_panel_ids,
- .ops = &tl070wsh30_panel_ops,
- .of_to_plat = tl070wsh30_panel_of_to_plat,
- .probe = tl070wsh30_panel_probe,
- .plat_auto = sizeof(struct mipi_dsi_panel_plat),
- .priv_auto = sizeof(struct tl070wsh30_panel_priv),
- };
|