1 // SPDX-License-Identifier: GPL-2.0
3 * LCD: LG4573, TFT 4.3", 480x800, RGB24
4 * LCD initialization via SPI
12 #include <dm/uclass-internal.h>
17 #define PWR_ON_DELAY_MSECS 120
19 static int lb043wv_spi_write_u16(struct spi_slave *slave, u16 val)
21 unsigned short buf16 = htons(val);
24 ret = spi_xfer(slave, 16, &buf16, NULL,
25 SPI_XFER_BEGIN | SPI_XFER_END);
27 debug("%s: Failed to send: %d\n", __func__, ret);
32 static void lb043wv_spi_write_u16_array(struct spi_slave *slave, u16 *buff,
37 for (i = 0; i < size; i++)
38 lb043wv_spi_write_u16(slave, buff[i]);
41 static void lb043wv_display_mode_settings(struct spi_slave *slave)
43 static u16 display_mode_settings[] = {
78 debug("transfer display mode settings\n");
79 lb043wv_spi_write_u16_array(slave, display_mode_settings,
80 ARRAY_SIZE(display_mode_settings));
83 static void lb043wv_power_settings(struct spi_slave *slave)
85 static u16 power_settings[] = {
109 debug("transfer power settings\n");
110 lb043wv_spi_write_u16_array(slave, power_settings,
111 ARRAY_SIZE(power_settings));
114 static void lb043wv_gamma_settings(struct spi_slave *slave)
116 static u16 gamma_settings[] = {
179 debug("transfer gamma settings\n");
180 lb043wv_spi_write_u16_array(slave, gamma_settings,
181 ARRAY_SIZE(gamma_settings));
184 static void lb043wv_display_on(struct spi_slave *slave)
186 static u16 sleep_out = 0x7011;
187 static u16 display_on = 0x7029;
189 lb043wv_spi_write_u16(slave, sleep_out);
190 mdelay(PWR_ON_DELAY_MSECS);
191 lb043wv_spi_write_u16(slave, display_on);
194 static int lg4573_spi_startup(struct spi_slave *slave)
198 ret = spi_claim_bus(slave);
202 lb043wv_display_mode_settings(slave);
203 lb043wv_power_settings(slave);
204 lb043wv_gamma_settings(slave);
205 lb043wv_display_on(slave);
207 spi_release_bus(slave);
211 static int do_lgset(cmd_tbl_t *cmdtp, int flag, int argc,
214 struct spi_slave *slave;
218 ret = uclass_get_device_by_driver(UCLASS_DISPLAY,
219 DM_GET_DRIVER(lg4573_lcd), &dev);
221 printf("%s: Could not get lg4573 device\n", __func__);
224 slave = dev_get_parent_priv(dev);
226 printf("%s: No slave data\n", __func__);
229 lg4573_spi_startup(slave);
235 lgset, 2, 1, do_lgset,
240 static int lg4573_bind(struct udevice *dev)
245 static int lg4573_probe(struct udevice *dev)
250 static const struct udevice_id lg4573_ids[] = {
251 { .compatible = "lg,lg4573" },
255 struct lg4573_lcd_priv {
256 struct display_timing timing;
257 struct udevice *backlight;
258 struct gpio_desc enable;
263 static int lg4573_lcd_read_timing(struct udevice *dev,
264 struct display_timing *timing)
266 struct lg4573_lcd_priv *priv = dev_get_priv(dev);
268 memcpy(timing, &priv->timing, sizeof(struct display_timing));
273 static int lg4573_lcd_enable(struct udevice *dev, int bpp,
274 const struct display_timing *edid)
276 struct spi_slave *slave = dev_get_parent_priv(dev);
277 struct lg4573_lcd_priv *priv = dev_get_priv(dev);
280 dm_gpio_set_value(&priv->enable, 1);
281 ret = backlight_enable(priv->backlight);
283 mdelay(priv->power_on_delay);
284 lg4573_spi_startup(slave);
289 static const struct dm_display_ops lg4573_lcd_ops = {
290 .read_timing = lg4573_lcd_read_timing,
291 .enable = lg4573_lcd_enable,
294 static int lg4573_ofdata_to_platdata(struct udevice *dev)
296 struct lg4573_lcd_priv *priv = dev_get_priv(dev);
299 ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
300 "backlight", &priv->backlight);
302 debug("%s: Cannot get backlight: ret=%d\n", __func__, ret);
305 ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable,
308 debug("%s: Warning: cannot get enable GPIO: ret=%d\n",
314 priv->power_on_delay = dev_read_u32_default(dev, "power-on-delay", 10);
319 U_BOOT_DRIVER(lg4573_lcd) = {
321 .id = UCLASS_DISPLAY,
322 .ops = &lg4573_lcd_ops,
323 .ofdata_to_platdata = lg4573_ofdata_to_platdata,
324 .of_match = lg4573_ids,
326 .probe = lg4573_probe,
327 .priv_auto_alloc_size = sizeof(struct lg4573_lcd_priv),