]> Git Repo - u-boot.git/blame - drivers/video/lg4573.c
Merge tag 'dm-pull-14dec20' of git://git.denx.de/u-boot-dm into next
[u-boot.git] / drivers / video / lg4573.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0
fc1a79d9
HS
2/*
3 * LCD: LG4573, TFT 4.3", 480x800, RGB24
4 * LCD initialization via SPI
5 *
fc1a79d9
HS
6 */
7#include <common.h>
79db1b46 8#include <backlight.h>
09140113 9#include <command.h>
79db1b46
HS
10#include <display.h>
11#include <dm.h>
f7ae49fc 12#include <log.h>
79db1b46
HS
13#include <dm/read.h>
14#include <dm/uclass-internal.h>
fc1a79d9
HS
15#include <errno.h>
16#include <spi.h>
79db1b46 17#include <asm/gpio.h>
c05ed00a 18#include <linux/delay.h>
fc1a79d9
HS
19
20#define PWR_ON_DELAY_MSECS 120
21
79db1b46 22static int lb043wv_spi_write_u16(struct spi_slave *slave, u16 val)
fc1a79d9 23{
fc1a79d9
HS
24 unsigned short buf16 = htons(val);
25 int ret = 0;
26
79db1b46
HS
27 ret = spi_xfer(slave, 16, &buf16, NULL,
28 SPI_XFER_BEGIN | SPI_XFER_END);
fc1a79d9
HS
29 if (ret)
30 debug("%s: Failed to send: %d\n", __func__, ret);
31
32 return ret;
33}
34
79db1b46 35static void lb043wv_spi_write_u16_array(struct spi_slave *slave, u16 *buff,
fc1a79d9
HS
36 int size)
37{
38 int i;
39
40 for (i = 0; i < size; i++)
79db1b46 41 lb043wv_spi_write_u16(slave, buff[i]);
fc1a79d9
HS
42}
43
79db1b46 44static void lb043wv_display_mode_settings(struct spi_slave *slave)
fc1a79d9
HS
45{
46 static u16 display_mode_settings[] = {
47 0x703A,
48 0x7270,
49 0x70B1,
50 0x7208,
51 0x723B,
52 0x720F,
53 0x70B2,
54 0x7200,
55 0x72C8,
56 0x70B3,
57 0x7200,
58 0x70B4,
59 0x7200,
60 0x70B5,
61 0x7242,
62 0x7210,
63 0x7210,
64 0x7200,
65 0x7220,
66 0x70B6,
67 0x720B,
68 0x720F,
69 0x723C,
70 0x7213,
71 0x7213,
72 0x72E8,
73 0x70B7,
74 0x7246,
75 0x7206,
76 0x720C,
77 0x7200,
78 0x7200,
79 };
80
81 debug("transfer display mode settings\n");
79db1b46 82 lb043wv_spi_write_u16_array(slave, display_mode_settings,
fc1a79d9
HS
83 ARRAY_SIZE(display_mode_settings));
84}
85
79db1b46 86static void lb043wv_power_settings(struct spi_slave *slave)
fc1a79d9
HS
87{
88 static u16 power_settings[] = {
89 0x70C0,
90 0x7201,
91 0x7211,
92 0x70C3,
93 0x7207,
94 0x7203,
95 0x7204,
96 0x7204,
97 0x7204,
98 0x70C4,
99 0x7212,
100 0x7224,
101 0x7218,
102 0x7218,
103 0x7202,
104 0x7249,
105 0x70C5,
106 0x726F,
107 0x70C6,
108 0x7241,
109 0x7263,
110 };
111
112 debug("transfer power settings\n");
79db1b46 113 lb043wv_spi_write_u16_array(slave, power_settings,
fc1a79d9
HS
114 ARRAY_SIZE(power_settings));
115}
116
79db1b46 117static void lb043wv_gamma_settings(struct spi_slave *slave)
fc1a79d9
HS
118{
119 static u16 gamma_settings[] = {
120 0x70D0,
121 0x7203,
122 0x7207,
123 0x7273,
124 0x7235,
125 0x7200,
126 0x7201,
127 0x7220,
128 0x7200,
129 0x7203,
130 0x70D1,
131 0x7203,
132 0x7207,
133 0x7273,
134 0x7235,
135 0x7200,
136 0x7201,
137 0x7220,
138 0x7200,
139 0x7203,
140 0x70D2,
141 0x7203,
142 0x7207,
143 0x7273,
144 0x7235,
145 0x7200,
146 0x7201,
147 0x7220,
148 0x7200,
149 0x7203,
150 0x70D3,
151 0x7203,
152 0x7207,
153 0x7273,
154 0x7235,
155 0x7200,
156 0x7201,
157 0x7220,
158 0x7200,
159 0x7203,
160 0x70D4,
161 0x7203,
162 0x7207,
163 0x7273,
164 0x7235,
165 0x7200,
166 0x7201,
167 0x7220,
168 0x7200,
169 0x7203,
170 0x70D5,
171 0x7203,
172 0x7207,
173 0x7273,
174 0x7235,
175 0x7200,
176 0x7201,
177 0x7220,
178 0x7200,
179 0x7203,
180 };
181
182 debug("transfer gamma settings\n");
79db1b46 183 lb043wv_spi_write_u16_array(slave, gamma_settings,
fc1a79d9
HS
184 ARRAY_SIZE(gamma_settings));
185}
186
79db1b46 187static void lb043wv_display_on(struct spi_slave *slave)
fc1a79d9
HS
188{
189 static u16 sleep_out = 0x7011;
190 static u16 display_on = 0x7029;
191
79db1b46 192 lb043wv_spi_write_u16(slave, sleep_out);
fc1a79d9 193 mdelay(PWR_ON_DELAY_MSECS);
79db1b46 194 lb043wv_spi_write_u16(slave, display_on);
fc1a79d9
HS
195}
196
79db1b46 197static int lg4573_spi_startup(struct spi_slave *slave)
fc1a79d9 198{
fc1a79d9
HS
199 int ret;
200
79db1b46
HS
201 ret = spi_claim_bus(slave);
202 if (ret)
203 return ret;
fc1a79d9 204
79db1b46
HS
205 lb043wv_display_mode_settings(slave);
206 lb043wv_power_settings(slave);
207 lb043wv_gamma_settings(slave);
208 lb043wv_display_on(slave);
fc1a79d9 209
79db1b46 210 spi_release_bus(slave);
fc1a79d9 211 return 0;
fc1a79d9
HS
212}
213
09140113
SG
214static int do_lgset(struct cmd_tbl *cmdtp, int flag, int argc,
215 char *const argv[])
fc1a79d9 216{
79db1b46
HS
217 struct spi_slave *slave;
218 struct udevice *dev;
219 int ret;
220
221 ret = uclass_get_device_by_driver(UCLASS_DISPLAY,
222 DM_GET_DRIVER(lg4573_lcd), &dev);
223 if (ret) {
224 printf("%s: Could not get lg4573 device\n", __func__);
225 return ret;
226 }
227 slave = dev_get_parent_priv(dev);
228 if (!slave) {
229 printf("%s: No slave data\n", __func__);
230 return -ENODEV;
231 }
232 lg4573_spi_startup(slave);
233
fc1a79d9
HS
234 return 0;
235}
236
237U_BOOT_CMD(
238 lgset, 2, 1, do_lgset,
239 "set lgdisplay",
240 ""
241);
79db1b46
HS
242
243static int lg4573_bind(struct udevice *dev)
244{
245 return 0;
246}
247
248static int lg4573_probe(struct udevice *dev)
249{
250 return 0;
251}
252
253static const struct udevice_id lg4573_ids[] = {
254 { .compatible = "lg,lg4573" },
255 { }
256};
257
258struct lg4573_lcd_priv {
259 struct display_timing timing;
260 struct udevice *backlight;
261 struct gpio_desc enable;
262 int panel_bpp;
263 u32 power_on_delay;
264};
265
266static int lg4573_lcd_read_timing(struct udevice *dev,
267 struct display_timing *timing)
268{
269 struct lg4573_lcd_priv *priv = dev_get_priv(dev);
270
271 memcpy(timing, &priv->timing, sizeof(struct display_timing));
272
273 return 0;
274}
275
276static int lg4573_lcd_enable(struct udevice *dev, int bpp,
277 const struct display_timing *edid)
278{
279 struct spi_slave *slave = dev_get_parent_priv(dev);
280 struct lg4573_lcd_priv *priv = dev_get_priv(dev);
281 int ret = 0;
282
283 dm_gpio_set_value(&priv->enable, 1);
284 ret = backlight_enable(priv->backlight);
285
286 mdelay(priv->power_on_delay);
287 lg4573_spi_startup(slave);
288
289 return ret;
290};
291
292static const struct dm_display_ops lg4573_lcd_ops = {
293 .read_timing = lg4573_lcd_read_timing,
294 .enable = lg4573_lcd_enable,
295};
296
d1998a9f 297static int lg4573_of_to_plat(struct udevice *dev)
79db1b46
HS
298{
299 struct lg4573_lcd_priv *priv = dev_get_priv(dev);
300 int ret;
301
302 ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
303 "backlight", &priv->backlight);
304 if (ret) {
305 debug("%s: Cannot get backlight: ret=%d\n", __func__, ret);
306 return log_ret(ret);
307 }
308 ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable,
309 GPIOD_IS_OUT);
310 if (ret) {
311 debug("%s: Warning: cannot get enable GPIO: ret=%d\n",
312 __func__, ret);
313 if (ret != -ENOENT)
314 return log_ret(ret);
315 }
316
317 priv->power_on_delay = dev_read_u32_default(dev, "power-on-delay", 10);
318
319 return 0;
320}
321
322U_BOOT_DRIVER(lg4573_lcd) = {
323 .name = "lg4573",
324 .id = UCLASS_DISPLAY,
325 .ops = &lg4573_lcd_ops,
d1998a9f 326 .of_to_plat = lg4573_of_to_plat,
79db1b46
HS
327 .of_match = lg4573_ids,
328 .bind = lg4573_bind,
329 .probe = lg4573_probe,
41575d8e 330 .priv_auto = sizeof(struct lg4573_lcd_priv),
79db1b46 331};
This page took 0.26234 seconds and 4 git commands to generate.