1 // SPDX-License-Identifier: GPL-2.0
3 * LCD: LG4573, TFT 4.3", 480x800, RGB24
4 * LCD initialization via SPI
14 #include <dm/uclass-internal.h>
18 #include <linux/delay.h>
20 #define PWR_ON_DELAY_MSECS 120
22 static int lb043wv_spi_write_u16(struct spi_slave *slave, u16 val)
24 unsigned short buf16 = htons(val);
27 ret = spi_xfer(slave, 16, &buf16, NULL,
28 SPI_XFER_BEGIN | SPI_XFER_END);
30 debug("%s: Failed to send: %d\n", __func__, ret);
35 static void lb043wv_spi_write_u16_array(struct spi_slave *slave, u16 *buff,
40 for (i = 0; i < size; i++)
41 lb043wv_spi_write_u16(slave, buff[i]);
44 static void lb043wv_display_mode_settings(struct spi_slave *slave)
46 static u16 display_mode_settings[] = {
81 debug("transfer display mode settings\n");
82 lb043wv_spi_write_u16_array(slave, display_mode_settings,
83 ARRAY_SIZE(display_mode_settings));
86 static void lb043wv_power_settings(struct spi_slave *slave)
88 static u16 power_settings[] = {
112 debug("transfer power settings\n");
113 lb043wv_spi_write_u16_array(slave, power_settings,
114 ARRAY_SIZE(power_settings));
117 static void lb043wv_gamma_settings(struct spi_slave *slave)
119 static u16 gamma_settings[] = {
182 debug("transfer gamma settings\n");
183 lb043wv_spi_write_u16_array(slave, gamma_settings,
184 ARRAY_SIZE(gamma_settings));
187 static void lb043wv_display_on(struct spi_slave *slave)
189 static u16 sleep_out = 0x7011;
190 static u16 display_on = 0x7029;
192 lb043wv_spi_write_u16(slave, sleep_out);
193 mdelay(PWR_ON_DELAY_MSECS);
194 lb043wv_spi_write_u16(slave, display_on);
197 static int lg4573_spi_startup(struct spi_slave *slave)
201 ret = spi_claim_bus(slave);
205 lb043wv_display_mode_settings(slave);
206 lb043wv_power_settings(slave);
207 lb043wv_gamma_settings(slave);
208 lb043wv_display_on(slave);
210 spi_release_bus(slave);
214 static int do_lgset(struct cmd_tbl *cmdtp, int flag, int argc,
217 struct spi_slave *slave;
221 ret = uclass_get_device_by_driver(UCLASS_DISPLAY,
222 DM_DRIVER_GET(lg4573_lcd), &dev);
224 printf("%s: Could not get lg4573 device\n", __func__);
227 slave = dev_get_parent_priv(dev);
229 printf("%s: No slave data\n", __func__);
232 lg4573_spi_startup(slave);
238 lgset, 2, 1, do_lgset,
243 static int lg4573_bind(struct udevice *dev)
248 static int lg4573_probe(struct udevice *dev)
253 static const struct udevice_id lg4573_ids[] = {
254 { .compatible = "lg,lg4573" },
258 struct lg4573_lcd_priv {
259 struct display_timing timing;
260 struct udevice *backlight;
261 struct gpio_desc enable;
266 static int lg4573_lcd_read_timing(struct udevice *dev,
267 struct display_timing *timing)
269 struct lg4573_lcd_priv *priv = dev_get_priv(dev);
271 memcpy(timing, &priv->timing, sizeof(struct display_timing));
276 static int lg4573_lcd_enable(struct udevice *dev, int bpp,
277 const struct display_timing *edid)
279 struct spi_slave *slave = dev_get_parent_priv(dev);
280 struct lg4573_lcd_priv *priv = dev_get_priv(dev);
283 dm_gpio_set_value(&priv->enable, 1);
284 ret = backlight_enable(priv->backlight);
286 mdelay(priv->power_on_delay);
287 lg4573_spi_startup(slave);
292 static const struct dm_display_ops lg4573_lcd_ops = {
293 .read_timing = lg4573_lcd_read_timing,
294 .enable = lg4573_lcd_enable,
297 static int lg4573_of_to_plat(struct udevice *dev)
299 struct lg4573_lcd_priv *priv = dev_get_priv(dev);
302 ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
303 "backlight", &priv->backlight);
305 debug("%s: Cannot get backlight: ret=%d\n", __func__, ret);
308 ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable,
311 debug("%s: Warning: cannot get enable GPIO: ret=%d\n",
317 priv->power_on_delay = dev_read_u32_default(dev, "power-on-delay", 10);
322 U_BOOT_DRIVER(lg4573_lcd) = {
324 .id = UCLASS_DISPLAY,
325 .ops = &lg4573_lcd_ops,
326 .of_to_plat = lg4573_of_to_plat,
327 .of_match = lg4573_ids,
329 .probe = lg4573_probe,
330 .priv_auto = sizeof(struct lg4573_lcd_priv),