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