]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/staging/fbtft/fbtft_device.c
Merge tag 'mac80211-for-davem-2015-10-13' of git://git.kernel.org/pub/scm/linux/kerne...
[mirror_ubuntu-zesty-kernel.git] / drivers / staging / fbtft / fbtft_device.c
1 /*
2 *
3 * Copyright (C) 2013, Noralf Tronnes
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <linux/module.h>
21 #include <linux/kernel.h>
22 #include <linux/init.h>
23 #include <linux/gpio.h>
24 #include <linux/spi/spi.h>
25
26 #include "fbtft.h"
27
28 #define DRVNAME "fbtft_device"
29
30 #define MAX_GPIOS 32
31
32 static struct spi_device *spi_device;
33 static struct platform_device *p_device;
34
35 static char *name;
36 module_param(name, charp, 0);
37 MODULE_PARM_DESC(name, "Devicename (required). name=list => list all supported devices.");
38
39 static unsigned rotate;
40 module_param(rotate, uint, 0);
41 MODULE_PARM_DESC(rotate,
42 "Angle to rotate display counter clockwise: 0, 90, 180, 270");
43
44 static unsigned busnum;
45 module_param(busnum, uint, 0);
46 MODULE_PARM_DESC(busnum, "SPI bus number (default=0)");
47
48 static unsigned cs;
49 module_param(cs, uint, 0);
50 MODULE_PARM_DESC(cs, "SPI chip select (default=0)");
51
52 static unsigned speed;
53 module_param(speed, uint, 0);
54 MODULE_PARM_DESC(speed, "SPI speed (override device default)");
55
56 static int mode = -1;
57 module_param(mode, int, 0);
58 MODULE_PARM_DESC(mode, "SPI mode (override device default)");
59
60 static char *gpios;
61 module_param(gpios, charp, 0);
62 MODULE_PARM_DESC(gpios,
63 "List of gpios. Comma separated with the form: reset:23,dc:24 (when overriding the default, all gpios must be specified)");
64
65 static unsigned fps;
66 module_param(fps, uint, 0);
67 MODULE_PARM_DESC(fps, "Frames per second (override driver default)");
68
69 static char *gamma;
70 module_param(gamma, charp, 0);
71 MODULE_PARM_DESC(gamma,
72 "String representation of Gamma Curve(s). Driver specific.");
73
74 static int txbuflen;
75 module_param(txbuflen, int, 0);
76 MODULE_PARM_DESC(txbuflen, "txbuflen (override driver default)");
77
78 static int bgr = -1;
79 module_param(bgr, int, 0);
80 MODULE_PARM_DESC(bgr,
81 "BGR bit (supported by some drivers).");
82
83 static unsigned startbyte;
84 module_param(startbyte, uint, 0);
85 MODULE_PARM_DESC(startbyte, "Sets the Start byte used by some SPI displays.");
86
87 static bool custom;
88 module_param(custom, bool, 0);
89 MODULE_PARM_DESC(custom, "Add a custom display device. Use speed= argument to make it a SPI device, else platform_device");
90
91 static unsigned width;
92 module_param(width, uint, 0);
93 MODULE_PARM_DESC(width, "Display width, used with the custom argument");
94
95 static unsigned height;
96 module_param(height, uint, 0);
97 MODULE_PARM_DESC(height, "Display height, used with the custom argument");
98
99 static unsigned buswidth = 8;
100 module_param(buswidth, uint, 0);
101 MODULE_PARM_DESC(buswidth, "Display bus width, used with the custom argument");
102
103 static int init[FBTFT_MAX_INIT_SEQUENCE];
104 static int init_num;
105 module_param_array(init, int, &init_num, 0);
106 MODULE_PARM_DESC(init, "Init sequence, used with the custom argument");
107
108 static unsigned long debug;
109 module_param(debug, ulong, 0);
110 MODULE_PARM_DESC(debug,
111 "level: 0-7 (the remaining 29 bits is for advanced usage)");
112
113 static unsigned verbose = 3;
114 module_param(verbose, uint, 0);
115 MODULE_PARM_DESC(verbose,
116 "0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)");
117
118
119 struct fbtft_device_display {
120 char *name;
121 struct spi_board_info *spi;
122 struct platform_device *pdev;
123 };
124
125 static void fbtft_device_pdev_release(struct device *dev);
126
127 static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len);
128 static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
129 int xs, int ys, int xe, int ye);
130
131 #define ADAFRUIT18_GAMMA \
132 "02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \
133 "03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10"
134
135 static int hy28b_init_sequence[] = {
136 -1, 0x00e7, 0x0010, -1, 0x0000, 0x0001,
137 -1, 0x0001, 0x0100, -1, 0x0002, 0x0700,
138 -1, 0x0003, 0x1030, -1, 0x0004, 0x0000,
139 -1, 0x0008, 0x0207, -1, 0x0009, 0x0000,
140 -1, 0x000a, 0x0000, -1, 0x000c, 0x0001,
141 -1, 0x000d, 0x0000, -1, 0x000f, 0x0000,
142 -1, 0x0010, 0x0000, -1, 0x0011, 0x0007,
143 -1, 0x0012, 0x0000, -1, 0x0013, 0x0000,
144 -2, 50, -1, 0x0010, 0x1590, -1, 0x0011,
145 0x0227, -2, 50, -1, 0x0012, 0x009c, -2, 50,
146 -1, 0x0013, 0x1900, -1, 0x0029, 0x0023,
147 -1, 0x002b, 0x000e, -2, 50,
148 -1, 0x0020, 0x0000, -1, 0x0021, 0x0000,
149 -2, 50, -1, 0x0050, 0x0000,
150 -1, 0x0051, 0x00ef, -1, 0x0052, 0x0000,
151 -1, 0x0053, 0x013f, -1, 0x0060, 0xa700,
152 -1, 0x0061, 0x0001, -1, 0x006a, 0x0000,
153 -1, 0x0080, 0x0000, -1, 0x0081, 0x0000,
154 -1, 0x0082, 0x0000, -1, 0x0083, 0x0000,
155 -1, 0x0084, 0x0000, -1, 0x0085, 0x0000,
156 -1, 0x0090, 0x0010, -1, 0x0092, 0x0000,
157 -1, 0x0093, 0x0003, -1, 0x0095, 0x0110,
158 -1, 0x0097, 0x0000, -1, 0x0098, 0x0000,
159 -1, 0x0007, 0x0133, -1, 0x0020, 0x0000,
160 -1, 0x0021, 0x0000, -2, 100, -3 };
161
162 #define HY28B_GAMMA \
163 "04 1F 4 7 7 0 7 7 6 0\n" \
164 "0F 00 1 7 4 0 0 0 6 7"
165
166 static int pitft_init_sequence[] = {
167 -1, 0x01, -2, 5, -1, 0x28, -1, 0xEF,
168 0x03, 0x80, 0x02, -1, 0xCF, 0x00, 0xC1, 0x30,
169 -1, 0xED, 0x64, 0x03, 0x12, 0x81,
170 -1, 0xE8, 0x85, 0x00, 0x78,
171 -1, 0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02,
172 -1, 0xF7, 0x20, -1, 0xEA, 0x00, 0x00,
173 -1, 0xC0, 0x23, -1, 0xC1, 0x10, -1, 0xC5,
174 0x3e, 0x28, -1, 0xC7, 0x86, -1, 0x3A, 0x55,
175 -1, 0xB1, 0x00, 0x18, -1, 0xB6, 0x08, 0x82,
176 0x27, -1, 0xF2, 0x00, -1, 0x26, 0x01,
177 -1, 0xE0, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08,
178 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03,
179 0x0E, 0x09, 0x00, -1, 0xE1, 0x00, 0x0E, 0x14,
180 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48,
181 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, -1,
182 0x11, -2, 100, -1, 0x29, -2, 20, -3 };
183
184 static int waveshare32b_init_sequence[] = {
185 -1, 0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02,
186 -1, 0xCF, 0x00, 0xC1, 0x30,
187 -1, 0xE8, 0x85, 0x00, 0x78, -1, 0xEA, 0x00,
188 0x00, -1, 0xED, 0x64, 0x03, 0x12, 0x81,
189 -1, 0xF7, 0x20, -1, 0xC0, 0x23, -1, 0xC1,
190 0x10, -1, 0xC5, 0x3e, 0x28, -1, 0xC7, 0x86,
191 -1, 0x36, 0x28, -1, 0x3A, 0x55, -1, 0xB1, 0x00,
192 0x18, -1, 0xB6, 0x08, 0x82, 0x27,
193 -1, 0xF2, 0x00, -1, 0x26, 0x01,
194 -1, 0xE0, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E,
195 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
196 -1, 0xE1, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31,
197 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
198 -1, 0x11, -2, 120, -1, 0x29, -1, 0x2c, -3 };
199
200 /* Supported displays in alphabetical order */
201 static struct fbtft_device_display displays[] = {
202 {
203 .name = "adafruit18",
204 .spi = &(struct spi_board_info) {
205 .modalias = "fb_st7735r",
206 .max_speed_hz = 32000000,
207 .mode = SPI_MODE_0,
208 .platform_data = &(struct fbtft_platform_data) {
209 .display = {
210 .buswidth = 8,
211 .backlight = 1,
212 },
213 .gpios = (const struct fbtft_gpio []) {
214 { "reset", 25 },
215 { "dc", 24 },
216 { "led", 18 },
217 {},
218 },
219 .gamma = ADAFRUIT18_GAMMA,
220 }
221 }
222 }, {
223 .name = "adafruit18_green",
224 .spi = &(struct spi_board_info) {
225 .modalias = "fb_st7735r",
226 .max_speed_hz = 4000000,
227 .mode = SPI_MODE_0,
228 .platform_data = &(struct fbtft_platform_data) {
229 .display = {
230 .buswidth = 8,
231 .backlight = 1,
232 .fbtftops.set_addr_win =
233 adafruit18_green_tab_set_addr_win,
234 },
235 .bgr = true,
236 .gpios = (const struct fbtft_gpio []) {
237 { "reset", 25 },
238 { "dc", 24 },
239 { "led", 18 },
240 {},
241 },
242 .gamma = ADAFRUIT18_GAMMA,
243 }
244 }
245 }, {
246 .name = "adafruit22",
247 .spi = &(struct spi_board_info) {
248 .modalias = "fb_hx8340bn",
249 .max_speed_hz = 32000000,
250 .mode = SPI_MODE_0,
251 .platform_data = &(struct fbtft_platform_data) {
252 .display = {
253 .buswidth = 9,
254 .backlight = 1,
255 },
256 .bgr = true,
257 .gpios = (const struct fbtft_gpio []) {
258 { "reset", 25 },
259 { "led", 23 },
260 {},
261 },
262 }
263 }
264 }, {
265 .name = "adafruit22a",
266 .spi = &(struct spi_board_info) {
267 .modalias = "fb_ili9340",
268 .max_speed_hz = 32000000,
269 .mode = SPI_MODE_0,
270 .platform_data = &(struct fbtft_platform_data) {
271 .display = {
272 .buswidth = 8,
273 .backlight = 1,
274 },
275 .bgr = true,
276 .gpios = (const struct fbtft_gpio []) {
277 { "reset", 25 },
278 { "dc", 24 },
279 { "led", 18 },
280 {},
281 },
282 }
283 }
284 }, {
285 .name = "adafruit28",
286 .spi = &(struct spi_board_info) {
287 .modalias = "fb_ili9341",
288 .max_speed_hz = 32000000,
289 .mode = SPI_MODE_0,
290 .platform_data = &(struct fbtft_platform_data) {
291 .display = {
292 .buswidth = 8,
293 .backlight = 1,
294 },
295 .bgr = true,
296 .gpios = (const struct fbtft_gpio []) {
297 { "reset", 25 },
298 { "dc", 24 },
299 { "led", 18 },
300 {},
301 },
302 }
303 }
304 }, {
305 .name = "adafruit13m",
306 .spi = &(struct spi_board_info) {
307 .modalias = "fb_ssd1306",
308 .max_speed_hz = 16000000,
309 .mode = SPI_MODE_0,
310 .platform_data = &(struct fbtft_platform_data) {
311 .display = {
312 .buswidth = 8,
313 },
314 .gpios = (const struct fbtft_gpio []) {
315 { "reset", 25 },
316 { "dc", 24 },
317 {},
318 },
319 }
320 }
321 }, {
322 .name = "agm1264k-fl",
323 .pdev = &(struct platform_device) {
324 .name = "fb_agm1264k-fl",
325 .id = 0,
326 .dev = {
327 .release = fbtft_device_pdev_release,
328 .platform_data = &(struct fbtft_platform_data) {
329 .display = {
330 .buswidth = 8,
331 .backlight = FBTFT_ONBOARD_BACKLIGHT,
332 },
333 .gpios = (const struct fbtft_gpio []) {
334 {},
335 },
336 },
337 }
338 }
339 }, {
340 .name = "dogs102",
341 .spi = &(struct spi_board_info) {
342 .modalias = "fb_uc1701",
343 .max_speed_hz = 8000000,
344 .mode = SPI_MODE_0,
345 .platform_data = &(struct fbtft_platform_data) {
346 .display = {
347 .buswidth = 8,
348 },
349 .bgr = true,
350 .gpios = (const struct fbtft_gpio []) {
351 { "reset", 13 },
352 { "dc", 6 },
353 {},
354 },
355 }
356 }
357 }, {
358 .name = "er_tftm050_2",
359 .spi = &(struct spi_board_info) {
360 .modalias = "fb_ra8875",
361 .max_speed_hz = 5000000,
362 .mode = SPI_MODE_3,
363 .platform_data = &(struct fbtft_platform_data) {
364 .display = {
365 .buswidth = 8,
366 .backlight = 1,
367 .width = 480,
368 .height = 272,
369 },
370 .bgr = true,
371 .gpios = (const struct fbtft_gpio []) {
372 { "reset", 25 },
373 { "dc", 24 },
374 {},
375 },
376 }
377 }
378 }, {
379 .name = "er_tftm070_5",
380 .spi = &(struct spi_board_info) {
381 .modalias = "fb_ra8875",
382 .max_speed_hz = 5000000,
383 .mode = SPI_MODE_3,
384 .platform_data = &(struct fbtft_platform_data) {
385 .display = {
386 .buswidth = 8,
387 .backlight = 1,
388 .width = 800,
389 .height = 480,
390 },
391 .bgr = true,
392 .gpios = (const struct fbtft_gpio []) {
393 { "reset", 25 },
394 { "dc", 24 },
395 {},
396 },
397 }
398 }
399 }, {
400 .name = "ew24ha0",
401 .spi = &(struct spi_board_info) {
402 .modalias = "fb_uc1611",
403 .max_speed_hz = 32000000,
404 .mode = SPI_MODE_3,
405 .platform_data = &(struct fbtft_platform_data) {
406 .display = {
407 .buswidth = 8,
408 },
409 .gpios = (const struct fbtft_gpio []) {
410 { "dc", 24 },
411 {},
412 },
413 }
414 }
415 }, {
416 .name = "ew24ha0_9bit",
417 .spi = &(struct spi_board_info) {
418 .modalias = "fb_uc1611",
419 .max_speed_hz = 32000000,
420 .mode = SPI_MODE_3,
421 .platform_data = &(struct fbtft_platform_data) {
422 .display = {
423 .buswidth = 9,
424 },
425 .gpios = (const struct fbtft_gpio []) {
426 {},
427 },
428 }
429 }
430 }, {
431 .name = "flexfb",
432 .spi = &(struct spi_board_info) {
433 .modalias = "flexfb",
434 .max_speed_hz = 32000000,
435 .mode = SPI_MODE_0,
436 .platform_data = &(struct fbtft_platform_data) {
437 .gpios = (const struct fbtft_gpio []) {
438 { "reset", 25 },
439 { "dc", 24 },
440 {},
441 },
442 }
443 }
444 }, {
445 .name = "flexpfb",
446 .pdev = &(struct platform_device) {
447 .name = "flexpfb",
448 .id = 0,
449 .dev = {
450 .release = fbtft_device_pdev_release,
451 .platform_data = &(struct fbtft_platform_data) {
452 .gpios = (const struct fbtft_gpio []) {
453 { "reset", 17 },
454 { "dc", 1 },
455 { "wr", 0 },
456 { "cs", 21 },
457 { "db00", 9 },
458 { "db01", 11 },
459 { "db02", 18 },
460 { "db03", 23 },
461 { "db04", 24 },
462 { "db05", 25 },
463 { "db06", 8 },
464 { "db07", 7 },
465 { "led", 4 },
466 {},
467 },
468 },
469 }
470 }
471 }, {
472 .name = "freetronicsoled128",
473 .spi = &(struct spi_board_info) {
474 .modalias = "fb_ssd1351",
475 .max_speed_hz = 20000000,
476 .mode = SPI_MODE_0,
477 .platform_data = &(struct fbtft_platform_data) {
478 .display = {
479 .buswidth = 8,
480 .backlight = FBTFT_ONBOARD_BACKLIGHT,
481 },
482 .bgr = true,
483 .gpios = (const struct fbtft_gpio []) {
484 { "reset", 24 },
485 { "dc", 25 },
486 {},
487 },
488 }
489 }
490 }, {
491 .name = "hx8353d",
492 .spi = &(struct spi_board_info) {
493 .modalias = "fb_hx8353d",
494 .max_speed_hz = 16000000,
495 .mode = SPI_MODE_0,
496 .platform_data = &(struct fbtft_platform_data) {
497 .display = {
498 .buswidth = 8,
499 .backlight = 1,
500 },
501 .gpios = (const struct fbtft_gpio []) {
502 { "reset", 25 },
503 { "dc", 24 },
504 { "led", 23 },
505 {},
506 },
507 }
508 }
509 }, {
510 .name = "hy28a",
511 .spi = &(struct spi_board_info) {
512 .modalias = "fb_ili9320",
513 .max_speed_hz = 32000000,
514 .mode = SPI_MODE_3,
515 .platform_data = &(struct fbtft_platform_data) {
516 .display = {
517 .buswidth = 8,
518 .backlight = 1,
519 },
520 .startbyte = 0x70,
521 .bgr = true,
522 .gpios = (const struct fbtft_gpio []) {
523 { "reset", 25 },
524 { "led", 18 },
525 {},
526 },
527 }
528 }
529 }, {
530 .name = "hy28b",
531 .spi = &(struct spi_board_info) {
532 .modalias = "fb_ili9325",
533 .max_speed_hz = 48000000,
534 .mode = SPI_MODE_3,
535 .platform_data = &(struct fbtft_platform_data) {
536 .display = {
537 .buswidth = 8,
538 .backlight = 1,
539 .init_sequence = hy28b_init_sequence,
540 },
541 .startbyte = 0x70,
542 .bgr = true,
543 .fps = 50,
544 .gpios = (const struct fbtft_gpio []) {
545 { "reset", 25 },
546 { "led", 18 },
547 {},
548 },
549 .gamma = HY28B_GAMMA,
550 }
551 }
552 }, {
553 .name = "ili9481",
554 .spi = &(struct spi_board_info) {
555 .modalias = "fb_ili9481",
556 .max_speed_hz = 32000000,
557 .mode = SPI_MODE_0,
558 .platform_data = &(struct fbtft_platform_data) {
559 .display = {
560 .regwidth = 16,
561 .buswidth = 8,
562 .backlight = 1,
563 },
564 .bgr = true,
565 .gpios = (const struct fbtft_gpio []) {
566 { "reset", 25 },
567 { "dc", 24 },
568 { "led", 22 },
569 {},
570 },
571 }
572 }
573 }, {
574 .name = "itdb24",
575 .pdev = &(struct platform_device) {
576 .name = "fb_s6d1121",
577 .id = 0,
578 .dev = {
579 .release = fbtft_device_pdev_release,
580 .platform_data = &(struct fbtft_platform_data) {
581 .display = {
582 .buswidth = 8,
583 .backlight = 1,
584 },
585 .bgr = false,
586 .gpios = (const struct fbtft_gpio []) {
587 /* Wiring for LCD adapter kit */
588 { "reset", 7 },
589 { "dc", 0 }, /* rev 2: 2 */
590 { "wr", 1 }, /* rev 2: 3 */
591 { "cs", 8 },
592 { "db00", 17 },
593 { "db01", 18 },
594 { "db02", 21 }, /* rev 2: 27 */
595 { "db03", 22 },
596 { "db04", 23 },
597 { "db05", 24 },
598 { "db06", 25 },
599 { "db07", 4 },
600 {}
601 },
602 },
603 }
604 }
605 }, {
606 .name = "itdb28",
607 .pdev = &(struct platform_device) {
608 .name = "fb_ili9325",
609 .id = 0,
610 .dev = {
611 .release = fbtft_device_pdev_release,
612 .platform_data = &(struct fbtft_platform_data) {
613 .display = {
614 .buswidth = 8,
615 .backlight = 1,
616 },
617 .bgr = true,
618 .gpios = (const struct fbtft_gpio []) {
619 {},
620 },
621 },
622 }
623 }
624 }, {
625 .name = "itdb28_spi",
626 .spi = &(struct spi_board_info) {
627 .modalias = "fb_ili9325",
628 .max_speed_hz = 32000000,
629 .mode = SPI_MODE_0,
630 .platform_data = &(struct fbtft_platform_data) {
631 .display = {
632 .buswidth = 8,
633 .backlight = 1,
634 },
635 .bgr = true,
636 .gpios = (const struct fbtft_gpio []) {
637 { "reset", 25 },
638 { "dc", 24 },
639 {},
640 },
641 }
642 }
643 }, {
644 .name = "mi0283qt-2",
645 .spi = &(struct spi_board_info) {
646 .modalias = "fb_hx8347d",
647 .max_speed_hz = 32000000,
648 .mode = SPI_MODE_0,
649 .platform_data = &(struct fbtft_platform_data) {
650 .display = {
651 .buswidth = 8,
652 .backlight = 1,
653 },
654 .startbyte = 0x70,
655 .bgr = true,
656 .gpios = (const struct fbtft_gpio []) {
657 { "reset", 25 },
658 { "dc", 24 },
659 { "led", 18 },
660 {},
661 },
662 }
663 }
664 }, {
665 .name = "mi0283qt-9a",
666 .spi = &(struct spi_board_info) {
667 .modalias = "fb_ili9341",
668 .max_speed_hz = 32000000,
669 .mode = SPI_MODE_0,
670 .platform_data = &(struct fbtft_platform_data) {
671 .display = {
672 .buswidth = 9,
673 .backlight = 1,
674 },
675 .bgr = true,
676 .gpios = (const struct fbtft_gpio []) {
677 { "reset", 25 },
678 { "led", 18 },
679 {},
680 },
681 }
682 }
683 }, {
684 .name = "mi0283qt-v2",
685 .spi = &(struct spi_board_info) {
686 .modalias = "fb_watterott",
687 .max_speed_hz = 4000000,
688 .mode = SPI_MODE_3,
689 .platform_data = &(struct fbtft_platform_data) {
690 .gpios = (const struct fbtft_gpio []) {
691 { "reset", 25 },
692 {},
693 },
694 }
695 }
696 }, {
697 .name = "nokia3310",
698 .spi = &(struct spi_board_info) {
699 .modalias = "fb_pcd8544",
700 .max_speed_hz = 400000,
701 .mode = SPI_MODE_0,
702 .platform_data = &(struct fbtft_platform_data) {
703 .display = {
704 .buswidth = 8,
705 },
706 .gpios = (const struct fbtft_gpio []) {
707 { "reset", 25 },
708 { "dc", 24 },
709 { "led", 23 },
710 {},
711 },
712 }
713 }
714 }, {
715 .name = "nokia3310a",
716 .spi = &(struct spi_board_info) {
717 .modalias = "fb_tls8204",
718 .max_speed_hz = 1000000,
719 .mode = SPI_MODE_0,
720 .platform_data = &(struct fbtft_platform_data) {
721 .display = {
722 .buswidth = 8,
723 },
724 .gpios = (const struct fbtft_gpio []) {
725 { "reset", 25 },
726 { "dc", 24 },
727 { "led", 23 },
728 {},
729 },
730 }
731 }
732 }, {
733 .name = "nokia5110",
734 .spi = &(struct spi_board_info) {
735 .modalias = "fb_ili9163",
736 .max_speed_hz = 12000000,
737 .mode = SPI_MODE_0,
738 .platform_data = &(struct fbtft_platform_data) {
739 .display = {
740 .buswidth = 8,
741 .backlight = 1,
742 },
743 .bgr = true,
744 .gpios = (const struct fbtft_gpio []) {
745 {},
746 },
747 }
748 }
749 }, {
750
751 .name = "piscreen",
752 .spi = &(struct spi_board_info) {
753 .modalias = "fb_ili9486",
754 .max_speed_hz = 32000000,
755 .mode = SPI_MODE_0,
756 .platform_data = &(struct fbtft_platform_data) {
757 .display = {
758 .regwidth = 16,
759 .buswidth = 8,
760 .backlight = 1,
761 },
762 .bgr = true,
763 .gpios = (const struct fbtft_gpio []) {
764 { "reset", 25 },
765 { "dc", 24 },
766 { "led", 22 },
767 {},
768 },
769 }
770 }
771 }, {
772 .name = "pitft",
773 .spi = &(struct spi_board_info) {
774 .modalias = "fb_ili9340",
775 .max_speed_hz = 32000000,
776 .mode = SPI_MODE_0,
777 .chip_select = 0,
778 .platform_data = &(struct fbtft_platform_data) {
779 .display = {
780 .buswidth = 8,
781 .backlight = 1,
782 .init_sequence = pitft_init_sequence,
783 },
784 .bgr = true,
785 .gpios = (const struct fbtft_gpio []) {
786 { "dc", 25 },
787 {},
788 },
789 }
790 }
791 }, {
792 .name = "pioled",
793 .spi = &(struct spi_board_info) {
794 .modalias = "fb_ssd1351",
795 .max_speed_hz = 20000000,
796 .mode = SPI_MODE_0,
797 .platform_data = &(struct fbtft_platform_data) {
798 .display = {
799 .buswidth = 8,
800 },
801 .bgr = true,
802 .gpios = (const struct fbtft_gpio []) {
803 { "reset", 24 },
804 { "dc", 25 },
805 {},
806 },
807 .gamma = "0 2 2 2 2 2 2 2 "
808 "2 2 2 2 2 2 2 2 "
809 "2 2 2 2 2 2 2 2 "
810 "2 2 2 2 2 2 2 3 "
811 "3 3 3 3 3 3 3 3 "
812 "3 3 3 3 3 3 3 3 "
813 "3 3 3 4 4 4 4 4 "
814 "4 4 4 4 4 4 4"
815 }
816 }
817 }, {
818 .name = "rpi-display",
819 .spi = &(struct spi_board_info) {
820 .modalias = "fb_ili9341",
821 .max_speed_hz = 32000000,
822 .mode = SPI_MODE_0,
823 .platform_data = &(struct fbtft_platform_data) {
824 .display = {
825 .buswidth = 8,
826 .backlight = 1,
827 },
828 .bgr = true,
829 .gpios = (const struct fbtft_gpio []) {
830 { "reset", 23 },
831 { "dc", 24 },
832 { "led", 18 },
833 {},
834 },
835 }
836 }
837 }, {
838 .name = "s6d02a1",
839 .spi = &(struct spi_board_info) {
840 .modalias = "fb_s6d02a1",
841 .max_speed_hz = 32000000,
842 .mode = SPI_MODE_0,
843 .platform_data = &(struct fbtft_platform_data) {
844 .display = {
845 .buswidth = 8,
846 .backlight = 1,
847 },
848 .bgr = true,
849 .gpios = (const struct fbtft_gpio []) {
850 { "reset", 25 },
851 { "dc", 24 },
852 { "led", 23 },
853 {},
854 },
855 }
856 }
857 }, {
858 .name = "sainsmart18",
859 .spi = &(struct spi_board_info) {
860 .modalias = "fb_st7735r",
861 .max_speed_hz = 32000000,
862 .mode = SPI_MODE_0,
863 .platform_data = &(struct fbtft_platform_data) {
864 .display = {
865 .buswidth = 8,
866 },
867 .gpios = (const struct fbtft_gpio []) {
868 { "reset", 25 },
869 { "dc", 24 },
870 {},
871 },
872 }
873 }
874 }, {
875 .name = "sainsmart32",
876 .pdev = &(struct platform_device) {
877 .name = "fb_ssd1289",
878 .id = 0,
879 .dev = {
880 .release = fbtft_device_pdev_release,
881 .platform_data = &(struct fbtft_platform_data) {
882 .display = {
883 .buswidth = 16,
884 .txbuflen = -2, /* disable buffer */
885 .backlight = 1,
886 .fbtftops.write = write_gpio16_wr_slow,
887 },
888 .bgr = true,
889 .gpios = (const struct fbtft_gpio []) {
890 {},
891 },
892 },
893 },
894 }
895 }, {
896 .name = "sainsmart32_fast",
897 .pdev = &(struct platform_device) {
898 .name = "fb_ssd1289",
899 .id = 0,
900 .dev = {
901 .release = fbtft_device_pdev_release,
902 .platform_data = &(struct fbtft_platform_data) {
903 .display = {
904 .buswidth = 16,
905 .txbuflen = -2, /* disable buffer */
906 .backlight = 1,
907 },
908 .bgr = true,
909 .gpios = (const struct fbtft_gpio []) {
910 {},
911 },
912 },
913 },
914 }
915 }, {
916 .name = "sainsmart32_latched",
917 .pdev = &(struct platform_device) {
918 .name = "fb_ssd1289",
919 .id = 0,
920 .dev = {
921 .release = fbtft_device_pdev_release,
922 .platform_data = &(struct fbtft_platform_data) {
923 .display = {
924 .buswidth = 16,
925 .txbuflen = -2, /* disable buffer */
926 .backlight = 1,
927 .fbtftops.write =
928 fbtft_write_gpio16_wr_latched,
929 },
930 .bgr = true,
931 .gpios = (const struct fbtft_gpio []) {
932 {},
933 },
934 },
935 },
936 }
937 }, {
938 .name = "sainsmart32_spi",
939 .spi = &(struct spi_board_info) {
940 .modalias = "fb_ssd1289",
941 .max_speed_hz = 16000000,
942 .mode = SPI_MODE_0,
943 .platform_data = &(struct fbtft_platform_data) {
944 .display = {
945 .buswidth = 8,
946 .backlight = 1,
947 },
948 .bgr = true,
949 .gpios = (const struct fbtft_gpio []) {
950 { "reset", 25 },
951 { "dc", 24 },
952 {},
953 },
954 }
955 }
956 }, {
957 .name = "spidev",
958 .spi = &(struct spi_board_info) {
959 .modalias = "spidev",
960 .max_speed_hz = 500000,
961 .bus_num = 0,
962 .chip_select = 0,
963 .mode = SPI_MODE_0,
964 .platform_data = &(struct fbtft_platform_data) {
965 .gpios = (const struct fbtft_gpio []) {
966 {},
967 },
968 }
969 }
970 }, {
971 .name = "ssd1331",
972 .spi = &(struct spi_board_info) {
973 .modalias = "fb_ssd1331",
974 .max_speed_hz = 20000000,
975 .mode = SPI_MODE_3,
976 .platform_data = &(struct fbtft_platform_data) {
977 .display = {
978 .buswidth = 8,
979 },
980 .gpios = (const struct fbtft_gpio []) {
981 { "reset", 24 },
982 { "dc", 25 },
983 {},
984 },
985 }
986 }
987 }, {
988 .name = "tinylcd35",
989 .spi = &(struct spi_board_info) {
990 .modalias = "fb_tinylcd",
991 .max_speed_hz = 32000000,
992 .mode = SPI_MODE_0,
993 .platform_data = &(struct fbtft_platform_data) {
994 .display = {
995 .buswidth = 8,
996 .backlight = 1,
997 },
998 .bgr = true,
999 .gpios = (const struct fbtft_gpio []) {
1000 { "reset", 25 },
1001 { "dc", 24 },
1002 { "led", 18 },
1003 {},
1004 },
1005 }
1006 }
1007 }, {
1008 .name = "tm022hdh26",
1009 .spi = &(struct spi_board_info) {
1010 .modalias = "fb_ili9341",
1011 .max_speed_hz = 32000000,
1012 .mode = SPI_MODE_0,
1013 .platform_data = &(struct fbtft_platform_data) {
1014 .display = {
1015 .buswidth = 8,
1016 .backlight = 1,
1017 },
1018 .bgr = true,
1019 .gpios = (const struct fbtft_gpio []) {
1020 { "reset", 25 },
1021 { "dc", 24 },
1022 { "led", 18 },
1023 {},
1024 },
1025 }
1026 }
1027 }, {
1028 .name = "tontec35_9481", /* boards before 02 July 2014 */
1029 .spi = &(struct spi_board_info) {
1030 .modalias = "fb_ili9481",
1031 .max_speed_hz = 128000000,
1032 .mode = SPI_MODE_3,
1033 .platform_data = &(struct fbtft_platform_data) {
1034 .display = {
1035 .buswidth = 8,
1036 .backlight = 1,
1037 },
1038 .bgr = true,
1039 .gpios = (const struct fbtft_gpio []) {
1040 { "reset", 15 },
1041 { "dc", 25 },
1042 { "led_", 18 },
1043 {},
1044 },
1045 }
1046 }
1047 }, {
1048 .name = "tontec35_9486", /* boards after 02 July 2014 */
1049 .spi = &(struct spi_board_info) {
1050 .modalias = "fb_ili9486",
1051 .max_speed_hz = 128000000,
1052 .mode = SPI_MODE_3,
1053 .platform_data = &(struct fbtft_platform_data) {
1054 .display = {
1055 .buswidth = 8,
1056 .backlight = 1,
1057 },
1058 .bgr = true,
1059 .gpios = (const struct fbtft_gpio []) {
1060 { "reset", 15 },
1061 { "dc", 25 },
1062 { "led_", 18 },
1063 {},
1064 },
1065 }
1066 }
1067 }, {
1068 .name = "upd161704",
1069 .spi = &(struct spi_board_info) {
1070 .modalias = "fb_upd161704",
1071 .max_speed_hz = 32000000,
1072 .mode = SPI_MODE_0,
1073 .platform_data = &(struct fbtft_platform_data) {
1074 .display = {
1075 .buswidth = 8,
1076 },
1077 .gpios = (const struct fbtft_gpio []) {
1078 { "reset", 24 },
1079 { "dc", 25 },
1080 {},
1081 },
1082 }
1083 }
1084 }, {
1085 .name = "waveshare32b",
1086 .spi = &(struct spi_board_info) {
1087 .modalias = "fb_ili9340",
1088 .max_speed_hz = 48000000,
1089 .mode = SPI_MODE_0,
1090 .platform_data = &(struct fbtft_platform_data) {
1091 .display = {
1092 .buswidth = 8,
1093 .backlight = 1,
1094 .init_sequence =
1095 waveshare32b_init_sequence,
1096 },
1097 .bgr = true,
1098 .gpios = (const struct fbtft_gpio []) {
1099 { "reset", 27 },
1100 { "dc", 22 },
1101 {},
1102 },
1103 }
1104 }
1105 }, {
1106 .name = "waveshare22",
1107 .spi = &(struct spi_board_info) {
1108 .modalias = "fb_bd663474",
1109 .max_speed_hz = 32000000,
1110 .mode = SPI_MODE_3,
1111 .platform_data = &(struct fbtft_platform_data) {
1112 .display = {
1113 .buswidth = 8,
1114 },
1115 .gpios = (const struct fbtft_gpio []) {
1116 { "reset", 24 },
1117 { "dc", 25 },
1118 {},
1119 },
1120 }
1121 }
1122 }, {
1123 /* This should be the last item.
1124 Used with the custom argument */
1125 .name = "",
1126 .spi = &(struct spi_board_info) {
1127 .modalias = "",
1128 .max_speed_hz = 0,
1129 .mode = SPI_MODE_0,
1130 .platform_data = &(struct fbtft_platform_data) {
1131 .gpios = (const struct fbtft_gpio []) {
1132 {},
1133 },
1134 }
1135 },
1136 .pdev = &(struct platform_device) {
1137 .name = "",
1138 .id = 0,
1139 .dev = {
1140 .release = fbtft_device_pdev_release,
1141 .platform_data = &(struct fbtft_platform_data) {
1142 .gpios = (const struct fbtft_gpio []) {
1143 {},
1144 },
1145 },
1146 },
1147 },
1148 }
1149 };
1150
1151 static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len)
1152 {
1153 u16 data;
1154 int i;
1155 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1156 static u16 prev_data;
1157 #endif
1158
1159 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
1160 "%s(len=%d): ", __func__, len);
1161
1162 while (len) {
1163 data = *(u16 *) buf;
1164
1165 /* Start writing by pulling down /WR */
1166 gpio_set_value(par->gpio.wr, 0);
1167
1168 /* Set data */
1169 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1170 if (data == prev_data) {
1171 gpio_set_value(par->gpio.wr, 0); /* used as delay */
1172 } else {
1173 for (i = 0; i < 16; i++) {
1174 if ((data & 1) != (prev_data & 1))
1175 gpio_set_value(par->gpio.db[i],
1176 data & 1);
1177 data >>= 1;
1178 prev_data >>= 1;
1179 }
1180 }
1181 #else
1182 for (i = 0; i < 16; i++) {
1183 gpio_set_value(par->gpio.db[i], data & 1);
1184 data >>= 1;
1185 }
1186 #endif
1187
1188 /* Pullup /WR */
1189 gpio_set_value(par->gpio.wr, 1);
1190
1191 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1192 prev_data = *(u16 *) buf;
1193 #endif
1194 buf += 2;
1195 len -= 2;
1196 }
1197
1198 return 0;
1199 }
1200
1201 static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
1202 int xs, int ys, int xe, int ye)
1203 {
1204 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
1205 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
1206 write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
1207 write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
1208 write_reg(par, 0x2C);
1209 }
1210
1211 /* used if gpios parameter is present */
1212 static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS+1] = { };
1213
1214 static void fbtft_device_pdev_release(struct device *dev)
1215 {
1216 /* Needed to silence this message:
1217 Device 'xxx' does not have a release() function, it is broken and must be fixed
1218 */
1219 }
1220
1221 static int spi_device_found(struct device *dev, void *data)
1222 {
1223 struct spi_device *spi = container_of(dev, struct spi_device, dev);
1224
1225 pr_info(DRVNAME": %s %s %dkHz %d bits mode=0x%02X\n",
1226 spi->modalias, dev_name(dev), spi->max_speed_hz/1000,
1227 spi->bits_per_word, spi->mode);
1228
1229 return 0;
1230 }
1231
1232 static void pr_spi_devices(void)
1233 {
1234 pr_info(DRVNAME": SPI devices registered:\n");
1235 bus_for_each_dev(&spi_bus_type, NULL, NULL, spi_device_found);
1236 }
1237
1238 static int p_device_found(struct device *dev, void *data)
1239 {
1240 struct platform_device
1241 *pdev = container_of(dev, struct platform_device, dev);
1242
1243 if (strstr(pdev->name, "fb"))
1244 pr_info(DRVNAME": %s id=%d pdata? %s\n",
1245 pdev->name, pdev->id,
1246 pdev->dev.platform_data ? "yes" : "no");
1247
1248 return 0;
1249 }
1250
1251 static void pr_p_devices(void)
1252 {
1253 pr_info(DRVNAME": 'fb' Platform devices registered:\n");
1254 bus_for_each_dev(&platform_bus_type, NULL, NULL, p_device_found);
1255 }
1256
1257 #ifdef MODULE
1258 static void fbtft_device_spi_delete(struct spi_master *master, unsigned cs)
1259 {
1260 struct device *dev;
1261 char str[32];
1262
1263 snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), cs);
1264
1265 dev = bus_find_device_by_name(&spi_bus_type, NULL, str);
1266 if (dev) {
1267 if (verbose)
1268 pr_info(DRVNAME": Deleting %s\n", str);
1269 device_del(dev);
1270 }
1271 }
1272
1273 static int fbtft_device_spi_device_register(struct spi_board_info *spi)
1274 {
1275 struct spi_master *master;
1276
1277 master = spi_busnum_to_master(spi->bus_num);
1278 if (!master) {
1279 pr_err(DRVNAME ": spi_busnum_to_master(%d) returned NULL\n",
1280 spi->bus_num);
1281 return -EINVAL;
1282 }
1283 /* make sure it's available */
1284 fbtft_device_spi_delete(master, spi->chip_select);
1285 spi_device = spi_new_device(master, spi);
1286 put_device(&master->dev);
1287 if (!spi_device) {
1288 pr_err(DRVNAME ": spi_new_device() returned NULL\n");
1289 return -EPERM;
1290 }
1291 return 0;
1292 }
1293 #else
1294 static int fbtft_device_spi_device_register(struct spi_board_info *spi)
1295 {
1296 return spi_register_board_info(spi, 1);
1297 }
1298 #endif
1299
1300 static int __init fbtft_device_init(void)
1301 {
1302 struct spi_board_info *spi = NULL;
1303 struct fbtft_platform_data *pdata;
1304 const struct fbtft_gpio *gpio = NULL;
1305 char *p_gpio, *p_name, *p_num;
1306 bool found = false;
1307 int i = 0;
1308 long val;
1309 int ret = 0;
1310
1311 pr_debug("\n\n"DRVNAME": init\n");
1312
1313 if (name == NULL) {
1314 #ifdef MODULE
1315 pr_err(DRVNAME": missing module parameter: 'name'\n");
1316 return -EINVAL;
1317 #else
1318 return 0;
1319 #endif
1320 }
1321
1322 if (init_num > FBTFT_MAX_INIT_SEQUENCE) {
1323 pr_err(DRVNAME
1324 ": init parameter: exceeded max array size: %d\n",
1325 FBTFT_MAX_INIT_SEQUENCE);
1326 return -EINVAL;
1327 }
1328
1329 /* parse module parameter: gpios */
1330 while ((p_gpio = strsep(&gpios, ","))) {
1331 if (strchr(p_gpio, ':') == NULL) {
1332 pr_err(DRVNAME
1333 ": error: missing ':' in gpios parameter: %s\n",
1334 p_gpio);
1335 return -EINVAL;
1336 }
1337 p_num = p_gpio;
1338 p_name = strsep(&p_num, ":");
1339 if (p_name == NULL || p_num == NULL) {
1340 pr_err(DRVNAME
1341 ": something bad happened parsing gpios parameter: %s\n",
1342 p_gpio);
1343 return -EINVAL;
1344 }
1345 ret = kstrtol(p_num, 10, &val);
1346 if (ret) {
1347 pr_err(DRVNAME
1348 ": could not parse number in gpios parameter: %s:%s\n",
1349 p_name, p_num);
1350 return -EINVAL;
1351 }
1352 strcpy(fbtft_device_param_gpios[i].name, p_name);
1353 fbtft_device_param_gpios[i++].gpio = (int) val;
1354 if (i == MAX_GPIOS) {
1355 pr_err(DRVNAME
1356 ": gpios parameter: exceeded max array size: %d\n",
1357 MAX_GPIOS);
1358 return -EINVAL;
1359 }
1360 }
1361 if (fbtft_device_param_gpios[0].name[0])
1362 gpio = fbtft_device_param_gpios;
1363
1364 if (verbose > 2)
1365 pr_spi_devices(); /* print list of registered SPI devices */
1366
1367 if (verbose > 2)
1368 pr_p_devices(); /* print list of 'fb' platform devices */
1369
1370 pr_debug(DRVNAME": name='%s', busnum=%d, cs=%d\n", name, busnum, cs);
1371
1372 if (rotate > 0 && rotate < 4) {
1373 rotate = (4 - rotate) * 90;
1374 pr_warn("argument 'rotate' should be an angle. Values 1-3 is deprecated. Setting it to %d.\n",
1375 rotate);
1376 }
1377 if (rotate != 0 && rotate != 90 && rotate != 180 && rotate != 270) {
1378 pr_warn("argument 'rotate' illegal value: %d. Setting it to 0.\n",
1379 rotate);
1380 rotate = 0;
1381 }
1382
1383 /* name=list lists all supported displays */
1384 if (strncmp(name, "list", 32) == 0) {
1385 pr_info(DRVNAME": Supported displays:\n");
1386
1387 for (i = 0; i < ARRAY_SIZE(displays); i++)
1388 pr_info(DRVNAME": %s\n", displays[i].name);
1389 return -ECANCELED;
1390 }
1391
1392 if (custom) {
1393 i = ARRAY_SIZE(displays) - 1;
1394 displays[i].name = name;
1395 if (speed == 0) {
1396 displays[i].pdev->name = name;
1397 displays[i].spi = NULL;
1398 } else {
1399 strncpy(displays[i].spi->modalias, name, SPI_NAME_SIZE);
1400 displays[i].pdev = NULL;
1401 }
1402 }
1403
1404 for (i = 0; i < ARRAY_SIZE(displays); i++) {
1405 if (strncmp(name, displays[i].name, 32) == 0) {
1406 if (displays[i].spi) {
1407 spi = displays[i].spi;
1408 spi->chip_select = cs;
1409 spi->bus_num = busnum;
1410 if (speed)
1411 spi->max_speed_hz = speed;
1412 if (mode != -1)
1413 spi->mode = mode;
1414 pdata = (void *)spi->platform_data;
1415 } else if (displays[i].pdev) {
1416 p_device = displays[i].pdev;
1417 pdata = p_device->dev.platform_data;
1418 } else {
1419 pr_err(DRVNAME": broken displays array\n");
1420 return -EINVAL;
1421 }
1422
1423 pdata->rotate = rotate;
1424 if (bgr == 0)
1425 pdata->bgr = false;
1426 else if (bgr == 1)
1427 pdata->bgr = true;
1428 if (startbyte)
1429 pdata->startbyte = startbyte;
1430 if (gamma)
1431 pdata->gamma = gamma;
1432 pdata->display.debug = debug;
1433 if (fps)
1434 pdata->fps = fps;
1435 if (txbuflen)
1436 pdata->txbuflen = txbuflen;
1437 if (init_num)
1438 pdata->display.init_sequence = init;
1439 if (gpio)
1440 pdata->gpios = gpio;
1441 if (custom) {
1442 pdata->display.width = width;
1443 pdata->display.height = height;
1444 pdata->display.buswidth = buswidth;
1445 pdata->display.backlight = 1;
1446 }
1447
1448 if (displays[i].spi) {
1449 ret = fbtft_device_spi_device_register(spi);
1450 if (ret) {
1451 pr_err(DRVNAME
1452 ": failed to register SPI device\n");
1453 return ret;
1454 }
1455 } else {
1456 ret = platform_device_register(p_device);
1457 if (ret < 0) {
1458 pr_err(DRVNAME
1459 ": platform_device_register() returned %d\n",
1460 ret);
1461 return ret;
1462 }
1463 }
1464 found = true;
1465 break;
1466 }
1467 }
1468
1469 if (!found) {
1470 pr_err(DRVNAME": display not supported: '%s'\n", name);
1471 return -EINVAL;
1472 }
1473
1474 if (verbose && pdata && pdata->gpios) {
1475 gpio = pdata->gpios;
1476 pr_info(DRVNAME": GPIOS used by '%s':\n", name);
1477 found = false;
1478 while (verbose && gpio->name[0]) {
1479 pr_info(DRVNAME": '%s' = GPIO%d\n",
1480 gpio->name, gpio->gpio);
1481 gpio++;
1482 found = true;
1483 }
1484 if (!found)
1485 pr_info(DRVNAME": (none)\n");
1486 }
1487
1488 if (spi_device && (verbose > 1))
1489 pr_spi_devices();
1490 if (p_device && (verbose > 1))
1491 pr_p_devices();
1492
1493 return 0;
1494 }
1495
1496 static void __exit fbtft_device_exit(void)
1497 {
1498 pr_debug(DRVNAME" - exit\n");
1499
1500 if (spi_device) {
1501 device_del(&spi_device->dev);
1502 kfree(spi_device);
1503 }
1504
1505 if (p_device)
1506 platform_device_unregister(p_device);
1507
1508 }
1509
1510 arch_initcall(fbtft_device_init);
1511 module_exit(fbtft_device_exit);
1512
1513 MODULE_DESCRIPTION("Add a FBTFT device.");
1514 MODULE_AUTHOR("Noralf Tronnes");
1515 MODULE_LICENSE("GPL");