Commit | Line | Data |
---|---|---|
783de57c | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
78c00ccc | 2 | /* Copyright (C) 2013 Noralf Tronnes */ |
c296d5f9 TP |
3 | |
4 | #ifndef __LINUX_FBTFT_H | |
5 | #define __LINUX_FBTFT_H | |
6 | ||
7 | #include <linux/fb.h> | |
8 | #include <linux/spinlock.h> | |
9 | #include <linux/spi/spi.h> | |
10 | #include <linux/platform_device.h> | |
11 | ||
c296d5f9 TP |
12 | #define FBTFT_ONBOARD_BACKLIGHT 2 |
13 | ||
14 | #define FBTFT_GPIO_NO_MATCH 0xFFFF | |
15 | #define FBTFT_GPIO_NAME_SIZE 32 | |
16 | #define FBTFT_MAX_INIT_SEQUENCE 512 | |
17 | #define FBTFT_GAMMA_MAX_VALUES_TOTAL 128 | |
18 | ||
19 | #define FBTFT_OF_INIT_CMD BIT(24) | |
20 | #define FBTFT_OF_INIT_DELAY BIT(25) | |
21 | ||
22 | /** | |
23 | * struct fbtft_gpio - Structure that holds one pinname to gpio mapping | |
24 | * @name: pinname (reset, dc, etc.) | |
25 | * @gpio: GPIO number | |
26 | * | |
27 | */ | |
28 | struct fbtft_gpio { | |
29 | char name[FBTFT_GPIO_NAME_SIZE]; | |
c440eee1 | 30 | struct gpio_desc *gpio; |
c296d5f9 TP |
31 | }; |
32 | ||
33 | struct fbtft_par; | |
34 | ||
35 | /** | |
36 | * struct fbtft_ops - FBTFT operations structure | |
37 | * @write: Writes to interface bus | |
38 | * @read: Reads from interface bus | |
39 | * @write_vmem: Writes video memory to display | |
40 | * @write_reg: Writes to controller register | |
41 | * @set_addr_win: Set the GRAM update window | |
42 | * @reset: Reset the LCD controller | |
43 | * @mkdirty: Marks display lines for update | |
44 | * @update_display: Updates the display | |
45 | * @init_display: Initializes the display | |
46 | * @blank: Blank the display (optional) | |
47 | * @request_gpios_match: Do pinname to gpio matching | |
48 | * @request_gpios: Request gpios from the kernel | |
49 | * @free_gpios: Free previously requested gpios | |
50 | * @verify_gpios: Verify that necessary gpios is present (optional) | |
51 | * @register_backlight: Used to register backlight device (optional) | |
52 | * @unregister_backlight: Unregister backlight device (optional) | |
53 | * @set_var: Configure LCD with values from variables like @rotate and @bgr | |
54 | * (optional) | |
55 | * @set_gamma: Set Gamma curve (optional) | |
56 | * | |
57 | * Most of these operations have default functions assigned to them in | |
58 | * fbtft_framebuffer_alloc() | |
59 | */ | |
60 | struct fbtft_ops { | |
61 | int (*write)(struct fbtft_par *par, void *buf, size_t len); | |
62 | int (*read)(struct fbtft_par *par, void *buf, size_t len); | |
63 | int (*write_vmem)(struct fbtft_par *par, size_t offset, size_t len); | |
64 | void (*write_register)(struct fbtft_par *par, int len, ...); | |
65 | ||
66 | void (*set_addr_win)(struct fbtft_par *par, | |
333c7b94 | 67 | int xs, int ys, int xe, int ye); |
c296d5f9 TP |
68 | void (*reset)(struct fbtft_par *par); |
69 | void (*mkdirty)(struct fb_info *info, int from, int to); | |
70 | void (*update_display)(struct fbtft_par *par, | |
333c7b94 | 71 | unsigned int start_line, unsigned int end_line); |
c296d5f9 TP |
72 | int (*init_display)(struct fbtft_par *par); |
73 | int (*blank)(struct fbtft_par *par, bool on); | |
74 | ||
75 | unsigned long (*request_gpios_match)(struct fbtft_par *par, | |
333c7b94 | 76 | const struct fbtft_gpio *gpio); |
c296d5f9 TP |
77 | int (*request_gpios)(struct fbtft_par *par); |
78 | int (*verify_gpios)(struct fbtft_par *par); | |
79 | ||
80 | void (*register_backlight)(struct fbtft_par *par); | |
81 | void (*unregister_backlight)(struct fbtft_par *par); | |
82 | ||
83 | int (*set_var)(struct fbtft_par *par); | |
22eb36b8 | 84 | int (*set_gamma)(struct fbtft_par *par, u32 *curves); |
c296d5f9 TP |
85 | }; |
86 | ||
87 | /** | |
88 | * struct fbtft_display - Describes the display properties | |
89 | * @width: Width of display in pixels | |
90 | * @height: Height of display in pixels | |
91 | * @regwidth: LCD Controller Register width in bits | |
92 | * @buswidth: Display interface bus width in bits | |
93 | * @backlight: Backlight type. | |
94 | * @fbtftops: FBTFT operations provided by driver or device (platform_data) | |
95 | * @bpp: Bits per pixel | |
96 | * @fps: Frames per second | |
97 | * @txbuflen: Size of transmit buffer | |
98 | * @init_sequence: Pointer to LCD initialization array | |
99 | * @gamma: String representation of Gamma curve(s) | |
100 | * @gamma_num: Number of Gamma curves | |
101 | * @gamma_len: Number of values per Gamma curve | |
102 | * @debug: Initial debug value | |
103 | * | |
104 | * This structure is not stored by FBTFT except for init_sequence. | |
105 | */ | |
106 | struct fbtft_display { | |
1c41494a MY |
107 | unsigned int width; |
108 | unsigned int height; | |
109 | unsigned int regwidth; | |
110 | unsigned int buswidth; | |
111 | unsigned int backlight; | |
c296d5f9 | 112 | struct fbtft_ops fbtftops; |
1c41494a MY |
113 | unsigned int bpp; |
114 | unsigned int fps; | |
c296d5f9 | 115 | int txbuflen; |
0a859b31 | 116 | const s16 *init_sequence; |
c296d5f9 TP |
117 | char *gamma; |
118 | int gamma_num; | |
119 | int gamma_len; | |
120 | unsigned long debug; | |
121 | }; | |
122 | ||
123 | /** | |
124 | * struct fbtft_platform_data - Passes display specific data to the driver | |
125 | * @display: Display properties | |
92def781 | 126 | * @gpios: Pointer to an array of pinname to gpio mappings |
c296d5f9 TP |
127 | * @rotate: Display rotation angle |
128 | * @bgr: LCD Controller BGR bit | |
129 | * @fps: Frames per second (this will go away, use @fps in @fbtft_display) | |
130 | * @txbuflen: Size of transmit buffer | |
131 | * @startbyte: When set, enables use of Startbyte in transfers | |
132 | * @gamma: String representation of Gamma curve(s) | |
133 | * @extra: A way to pass extra info | |
134 | */ | |
135 | struct fbtft_platform_data { | |
136 | struct fbtft_display display; | |
1c41494a | 137 | unsigned int rotate; |
c296d5f9 | 138 | bool bgr; |
1c41494a | 139 | unsigned int fps; |
c296d5f9 TP |
140 | int txbuflen; |
141 | u8 startbyte; | |
142 | char *gamma; | |
143 | void *extra; | |
144 | }; | |
145 | ||
146 | /** | |
147 | * struct fbtft_par - Main FBTFT data structure | |
148 | * | |
149 | * This structure holds all relevant data to operate the display | |
150 | * | |
151 | * See sourcefile for documentation since nested structs is not | |
152 | * supported by kernel-doc. | |
153 | * | |
154 | */ | |
155 | /* @spi: Set if it is a SPI device | |
156 | * @pdev: Set if it is a platform device | |
157 | * @info: Pointer to framebuffer fb_info structure | |
158 | * @pdata: Pointer to platform data | |
159 | * @ssbuf: Not used | |
160 | * @pseudo_palette: Used by fb_set_colreg() | |
161 | * @txbuf.buf: Transmit buffer | |
162 | * @txbuf.len: Transmit buffer length | |
163 | * @buf: Small buffer used when writing init data over SPI | |
164 | * @startbyte: Used by some controllers when in SPI mode. | |
165 | * Format: 6 bit Device id + RS bit + RW bit | |
166 | * @fbtftops: FBTFT operations provided by driver or device (platform_data) | |
167 | * @dirty_lock: Protects dirty_lines_start and dirty_lines_end | |
168 | * @dirty_lines_start: Where to begin updating display | |
169 | * @dirty_lines_end: Where to end updating display | |
170 | * @gpio.reset: GPIO used to reset display | |
171 | * @gpio.dc: Data/Command signal, also known as RS | |
172 | * @gpio.rd: Read latching signal | |
173 | * @gpio.wr: Write latching signal | |
174 | * @gpio.latch: Bus latch signal, eg. 16->8 bit bus latch | |
175 | * @gpio.cs: LCD Chip Select with parallel interface bus | |
176 | * @gpio.db[16]: Parallel databus | |
177 | * @gpio.led[16]: Led control signals | |
92def781 | 178 | * @gpio.aux[16]: Auxiliary signals, not used by core |
c296d5f9 TP |
179 | * @init_sequence: Pointer to LCD initialization array |
180 | * @gamma.lock: Mutex for Gamma curve locking | |
181 | * @gamma.curves: Pointer to Gamma curve array | |
182 | * @gamma.num_values: Number of values per Gamma curve | |
183 | * @gamma.num_curves: Number of Gamma curves | |
184 | * @debug: Pointer to debug value | |
185 | * @current_debug: | |
186 | * @first_update_done: Used to only time the first display update | |
187 | * @update_time: Used to calculate 'fps' in debug output | |
188 | * @bgr: BGR mode/\n | |
189 | * @extra: Extra info needed by driver | |
190 | */ | |
191 | struct fbtft_par { | |
192 | struct spi_device *spi; | |
193 | struct platform_device *pdev; | |
194 | struct fb_info *info; | |
195 | struct fbtft_platform_data *pdata; | |
196 | u16 *ssbuf; | |
197 | u32 pseudo_palette[16]; | |
198 | struct { | |
199 | void *buf; | |
c296d5f9 TP |
200 | size_t len; |
201 | } txbuf; | |
202 | u8 *buf; | |
203 | u8 startbyte; | |
204 | struct fbtft_ops fbtftops; | |
205 | spinlock_t dirty_lock; | |
1c41494a MY |
206 | unsigned int dirty_lines_start; |
207 | unsigned int dirty_lines_end; | |
c296d5f9 | 208 | struct { |
c440eee1 NK |
209 | struct gpio_desc *reset; |
210 | struct gpio_desc *dc; | |
211 | struct gpio_desc *rd; | |
212 | struct gpio_desc *wr; | |
213 | struct gpio_desc *latch; | |
214 | struct gpio_desc *cs; | |
215 | struct gpio_desc *db[16]; | |
216 | struct gpio_desc *led[16]; | |
217 | struct gpio_desc *aux[16]; | |
c296d5f9 | 218 | } gpio; |
0a859b31 | 219 | const s16 *init_sequence; |
c296d5f9 TP |
220 | struct { |
221 | struct mutex lock; | |
22eb36b8 | 222 | u32 *curves; |
c296d5f9 TP |
223 | int num_values; |
224 | int num_curves; | |
225 | } gamma; | |
226 | unsigned long debug; | |
227 | bool first_update_done; | |
367e8560 | 228 | ktime_t update_time; |
c296d5f9 TP |
229 | bool bgr; |
230 | void *extra; | |
9adfe5c8 | 231 | bool polarity; |
c296d5f9 TP |
232 | }; |
233 | ||
2b2424d9 | 234 | #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int)) |
c296d5f9 | 235 | |
0b1533c6 LB |
236 | #define write_reg(par, ...) \ |
237 | ((par)->fbtftops.write_register(par, NUMARGS(__VA_ARGS__), __VA_ARGS__)) | |
c296d5f9 TP |
238 | |
239 | /* fbtft-core.c */ | |
60da7020 | 240 | int fbtft_write_buf_dc(struct fbtft_par *par, void *buf, size_t len, int dc); |
27a0eb8f | 241 | __printf(5, 6) |
cd951ddc JP |
242 | void fbtft_dbg_hex(const struct device *dev, int groupsize, |
243 | void *buf, size_t len, const char *fmt, ...); | |
ad6d8812 NT |
244 | struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, |
245 | struct device *dev, | |
246 | struct fbtft_platform_data *pdata); | |
cd951ddc JP |
247 | void fbtft_framebuffer_release(struct fb_info *info); |
248 | int fbtft_register_framebuffer(struct fb_info *fb_info); | |
249 | int fbtft_unregister_framebuffer(struct fb_info *fb_info); | |
250 | void fbtft_register_backlight(struct fbtft_par *par); | |
251 | void fbtft_unregister_backlight(struct fbtft_par *par); | |
252 | int fbtft_init_display(struct fbtft_par *par); | |
253 | int fbtft_probe_common(struct fbtft_display *display, struct spi_device *sdev, | |
254 | struct platform_device *pdev); | |
255 | int fbtft_remove_common(struct device *dev, struct fb_info *info); | |
c296d5f9 TP |
256 | |
257 | /* fbtft-io.c */ | |
cd951ddc JP |
258 | int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len); |
259 | int fbtft_write_spi_emulate_9(struct fbtft_par *par, void *buf, size_t len); | |
260 | int fbtft_read_spi(struct fbtft_par *par, void *buf, size_t len); | |
261 | int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len); | |
262 | int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len); | |
263 | int fbtft_write_gpio16_wr_latched(struct fbtft_par *par, void *buf, size_t len); | |
c296d5f9 TP |
264 | |
265 | /* fbtft-bus.c */ | |
cd951ddc JP |
266 | int fbtft_write_vmem8_bus8(struct fbtft_par *par, size_t offset, size_t len); |
267 | int fbtft_write_vmem16_bus16(struct fbtft_par *par, size_t offset, size_t len); | |
268 | int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len); | |
269 | int fbtft_write_vmem16_bus9(struct fbtft_par *par, size_t offset, size_t len); | |
270 | void fbtft_write_reg8_bus8(struct fbtft_par *par, int len, ...); | |
271 | void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...); | |
272 | void fbtft_write_reg16_bus8(struct fbtft_par *par, int len, ...); | |
273 | void fbtft_write_reg16_bus16(struct fbtft_par *par, int len, ...); | |
c296d5f9 | 274 | |
c296d5f9 TP |
275 | #define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \ |
276 | \ | |
277 | static int fbtft_driver_probe_spi(struct spi_device *spi) \ | |
278 | { \ | |
279 | return fbtft_probe_common(_display, spi, NULL); \ | |
280 | } \ | |
281 | \ | |
282 | static int fbtft_driver_remove_spi(struct spi_device *spi) \ | |
283 | { \ | |
284 | struct fb_info *info = spi_get_drvdata(spi); \ | |
285 | \ | |
286 | return fbtft_remove_common(&spi->dev, info); \ | |
287 | } \ | |
288 | \ | |
289 | static int fbtft_driver_probe_pdev(struct platform_device *pdev) \ | |
290 | { \ | |
291 | return fbtft_probe_common(_display, NULL, pdev); \ | |
292 | } \ | |
293 | \ | |
294 | static int fbtft_driver_remove_pdev(struct platform_device *pdev) \ | |
295 | { \ | |
296 | struct fb_info *info = platform_get_drvdata(pdev); \ | |
297 | \ | |
298 | return fbtft_remove_common(&pdev->dev, info); \ | |
299 | } \ | |
300 | \ | |
301 | static const struct of_device_id dt_ids[] = { \ | |
42efd001 HF |
302 | { .compatible = _compatible }, \ |
303 | {}, \ | |
c296d5f9 TP |
304 | }; \ |
305 | \ | |
306 | MODULE_DEVICE_TABLE(of, dt_ids); \ | |
307 | \ | |
308 | \ | |
309 | static struct spi_driver fbtft_driver_spi_driver = { \ | |
310 | .driver = { \ | |
311 | .name = _name, \ | |
189f39ee | 312 | .of_match_table = dt_ids, \ |
c296d5f9 TP |
313 | }, \ |
314 | .probe = fbtft_driver_probe_spi, \ | |
315 | .remove = fbtft_driver_remove_spi, \ | |
316 | }; \ | |
317 | \ | |
318 | static struct platform_driver fbtft_driver_platform_driver = { \ | |
319 | .driver = { \ | |
320 | .name = _name, \ | |
321 | .owner = THIS_MODULE, \ | |
189f39ee | 322 | .of_match_table = dt_ids, \ |
c296d5f9 TP |
323 | }, \ |
324 | .probe = fbtft_driver_probe_pdev, \ | |
325 | .remove = fbtft_driver_remove_pdev, \ | |
326 | }; \ | |
327 | \ | |
328 | static int __init fbtft_driver_module_init(void) \ | |
329 | { \ | |
330 | int ret; \ | |
331 | \ | |
332 | ret = spi_register_driver(&fbtft_driver_spi_driver); \ | |
333 | if (ret < 0) \ | |
334 | return ret; \ | |
335 | return platform_driver_register(&fbtft_driver_platform_driver); \ | |
336 | } \ | |
337 | \ | |
338 | static void __exit fbtft_driver_module_exit(void) \ | |
339 | { \ | |
340 | spi_unregister_driver(&fbtft_driver_spi_driver); \ | |
341 | platform_driver_unregister(&fbtft_driver_platform_driver); \ | |
342 | } \ | |
343 | \ | |
344 | module_init(fbtft_driver_module_init); \ | |
345 | module_exit(fbtft_driver_module_exit); | |
346 | ||
c296d5f9 TP |
347 | /* Debug macros */ |
348 | ||
349 | /* shorthand debug levels */ | |
350 | #define DEBUG_LEVEL_1 DEBUG_REQUEST_GPIOS | |
b32d2fb2 DV |
351 | #define DEBUG_LEVEL_2 (DEBUG_LEVEL_1 | DEBUG_DRIVER_INIT_FUNCTIONS \ |
352 | | DEBUG_TIME_FIRST_UPDATE) | |
353 | #define DEBUG_LEVEL_3 (DEBUG_LEVEL_2 | DEBUG_RESET | DEBUG_INIT_DISPLAY \ | |
354 | | DEBUG_BLANK | DEBUG_REQUEST_GPIOS \ | |
355 | | DEBUG_FREE_GPIOS \ | |
356 | | DEBUG_VERIFY_GPIOS \ | |
357 | | DEBUG_BACKLIGHT | DEBUG_SYSFS) | |
358 | #define DEBUG_LEVEL_4 (DEBUG_LEVEL_2 | DEBUG_FB_READ | DEBUG_FB_WRITE \ | |
359 | | DEBUG_FB_FILLRECT \ | |
360 | | DEBUG_FB_COPYAREA \ | |
361 | | DEBUG_FB_IMAGEBLIT | DEBUG_FB_BLANK) | |
c296d5f9 TP |
362 | #define DEBUG_LEVEL_5 (DEBUG_LEVEL_3 | DEBUG_UPDATE_DISPLAY) |
363 | #define DEBUG_LEVEL_6 (DEBUG_LEVEL_4 | DEBUG_LEVEL_5) | |
364 | #define DEBUG_LEVEL_7 0xFFFFFFFF | |
365 | ||
48b775ca MS |
366 | #define DEBUG_DRIVER_INIT_FUNCTIONS BIT(3) |
367 | #define DEBUG_TIME_FIRST_UPDATE BIT(4) | |
368 | #define DEBUG_TIME_EACH_UPDATE BIT(5) | |
369 | #define DEBUG_DEFERRED_IO BIT(6) | |
370 | #define DEBUG_FBTFT_INIT_FUNCTIONS BIT(7) | |
c296d5f9 TP |
371 | |
372 | /* fbops */ | |
48b775ca MS |
373 | #define DEBUG_FB_READ BIT(8) |
374 | #define DEBUG_FB_WRITE BIT(9) | |
375 | #define DEBUG_FB_FILLRECT BIT(10) | |
376 | #define DEBUG_FB_COPYAREA BIT(11) | |
377 | #define DEBUG_FB_IMAGEBLIT BIT(12) | |
378 | #define DEBUG_FB_SETCOLREG BIT(13) | |
379 | #define DEBUG_FB_BLANK BIT(14) | |
c296d5f9 | 380 | |
48b775ca | 381 | #define DEBUG_SYSFS BIT(16) |
c296d5f9 TP |
382 | |
383 | /* fbtftops */ | |
48b775ca MS |
384 | #define DEBUG_BACKLIGHT BIT(17) |
385 | #define DEBUG_READ BIT(18) | |
386 | #define DEBUG_WRITE BIT(19) | |
387 | #define DEBUG_WRITE_VMEM BIT(20) | |
388 | #define DEBUG_WRITE_REGISTER BIT(21) | |
389 | #define DEBUG_SET_ADDR_WIN BIT(22) | |
390 | #define DEBUG_RESET BIT(23) | |
391 | #define DEBUG_MKDIRTY BIT(24) | |
392 | #define DEBUG_UPDATE_DISPLAY BIT(25) | |
393 | #define DEBUG_INIT_DISPLAY BIT(26) | |
394 | #define DEBUG_BLANK BIT(27) | |
395 | #define DEBUG_REQUEST_GPIOS BIT(28) | |
396 | #define DEBUG_FREE_GPIOS BIT(29) | |
397 | #define DEBUG_REQUEST_GPIOS_MATCH BIT(30) | |
398 | #define DEBUG_VERIFY_GPIOS BIT(31) | |
c296d5f9 | 399 | |
c296d5f9 TP |
400 | #define fbtft_init_dbg(dev, format, arg...) \ |
401 | do { \ | |
402 | if (unlikely((dev)->platform_data && \ | |
403 | (((struct fbtft_platform_data *)(dev)->platform_data)->display.debug & DEBUG_DRIVER_INIT_FUNCTIONS))) \ | |
404 | dev_info(dev, format, ##arg); \ | |
405 | } while (0) | |
406 | ||
407 | #define fbtft_par_dbg(level, par, format, arg...) \ | |
408 | do { \ | |
f54df479 DV |
409 | if (unlikely((par)->debug & (level))) \ |
410 | dev_info((par)->info->device, format, ##arg); \ | |
c296d5f9 TP |
411 | } while (0) |
412 | ||
c296d5f9 TP |
413 | #define fbtft_par_dbg_hex(level, par, dev, type, buf, num, format, arg...) \ |
414 | do { \ | |
0b1533c6 LB |
415 | if (unlikely((par)->debug & (level))) \ |
416 | fbtft_dbg_hex(dev, sizeof(type), buf,\ | |
417 | (num) * sizeof(type), format, ##arg); \ | |
c296d5f9 TP |
418 | } while (0) |
419 | ||
420 | #endif /* __LINUX_FBTFT_H */ |