1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2020 BayLibre, SAS
4 * Author: Neil Armstrong <narmstrong@baylibre.com>
12 #include <dm/device_compat.h>
13 #include <linux/delay.h>
14 #include <power/regulator.h>
16 struct tl070wsh30_panel_priv {
18 struct udevice *backlight;
19 struct gpio_desc reset;
22 static const struct display_timing default_timing = {
23 .pixelclock.typ = 47250000,
25 .hfront_porch.typ = 46,
26 .hback_porch.typ = 100,
29 .vfront_porch.typ = 5,
30 .vback_porch.typ = 20,
32 .flags = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH,
35 static int tl070wsh30_panel_enable_backlight(struct udevice *dev)
37 struct mipi_dsi_panel_plat *plat = dev_get_plat(dev);
38 struct mipi_dsi_device *device = plat->device;
39 struct tl070wsh30_panel_priv *priv = dev_get_priv(dev);
42 ret = mipi_dsi_attach(device);
46 ret = mipi_dsi_dcs_exit_sleep_mode(device);
52 ret = mipi_dsi_dcs_set_display_on(device);
58 ret = backlight_enable(priv->backlight);
65 static int tl070wsh30_panel_get_display_timing(struct udevice *dev,
66 struct display_timing *timings)
68 memcpy(timings, &default_timing, sizeof(*timings));
73 static int tl070wsh30_panel_of_to_plat(struct udevice *dev)
75 struct tl070wsh30_panel_priv *priv = dev_get_priv(dev);
78 if (IS_ENABLED(CONFIG_DM_REGULATOR)) {
79 ret = device_get_supply_regulator(dev, "power-supply",
81 if (ret && ret != -ENOENT) {
82 dev_err(dev, "Warning: cannot get power supply\n");
87 ret = gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset,
90 dev_err(dev, "Warning: cannot get reset GPIO\n");
95 ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
96 "backlight", &priv->backlight);
98 dev_err(dev, "Cannot get backlight: ret=%d\n", ret);
105 static int tl070wsh30_panel_probe(struct udevice *dev)
107 struct tl070wsh30_panel_priv *priv = dev_get_priv(dev);
108 struct mipi_dsi_panel_plat *plat = dev_get_plat(dev);
111 if (IS_ENABLED(CONFIG_DM_REGULATOR) && priv->reg) {
112 ret = regulator_set_enable(priv->reg, true);
120 dm_gpio_set_value(&priv->reset, true);
124 dm_gpio_set_value(&priv->reset, false);
126 /* fill characteristics of DSI data link */
128 plat->format = MIPI_DSI_FMT_RGB888;
129 plat->mode_flags = MIPI_DSI_MODE_VIDEO |
130 MIPI_DSI_MODE_VIDEO_BURST |
136 static const struct panel_ops tl070wsh30_panel_ops = {
137 .enable_backlight = tl070wsh30_panel_enable_backlight,
138 .get_display_timing = tl070wsh30_panel_get_display_timing,
141 static const struct udevice_id tl070wsh30_panel_ids[] = {
142 { .compatible = "tdo,tl070wsh30" },
146 U_BOOT_DRIVER(tl070wsh30_panel) = {
147 .name = "tl070wsh30_panel",
149 .of_match = tl070wsh30_panel_ids,
150 .ops = &tl070wsh30_panel_ops,
151 .of_to_plat = tl070wsh30_panel_of_to_plat,
152 .probe = tl070wsh30_panel_probe,
153 .plat_auto = sizeof(struct mipi_dsi_panel_plat),
154 .priv_auto = sizeof(struct tl070wsh30_panel_priv),