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