intel_pstate: fix PCT_TO_HWP macro
[linux-2.6-block.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 = "flexfb",
401                 .spi = &(struct spi_board_info) {
402                         .modalias = "flexfb",
403                         .max_speed_hz = 32000000,
404                         .mode = SPI_MODE_0,
405                         .platform_data = &(struct fbtft_platform_data) {
406                                 .gpios = (const struct fbtft_gpio []) {
407                                         { "reset", 25 },
408                                         { "dc", 24 },
409                                         {},
410                                 },
411                         }
412                 }
413         }, {
414                 .name = "flexpfb",
415                 .pdev = &(struct platform_device) {
416                         .name = "flexpfb",
417                         .id = 0,
418                         .dev = {
419                         .release = fbtft_device_pdev_release,
420                         .platform_data = &(struct fbtft_platform_data) {
421                                 .gpios = (const struct fbtft_gpio []) {
422                                         { "reset", 17 },
423                                         { "dc", 1 },
424                                         { "wr", 0 },
425                                         { "cs", 21 },
426                                         { "db00", 9 },
427                                         { "db01", 11 },
428                                         { "db02", 18 },
429                                         { "db03", 23 },
430                                         { "db04", 24 },
431                                         { "db05", 25 },
432                                         { "db06", 8 },
433                                         { "db07", 7 },
434                                         { "led", 4 },
435                                         {},
436                                 },
437                         },
438                         }
439                 }
440         }, {
441                 .name = "freetronicsoled128",
442                 .spi = &(struct spi_board_info) {
443                         .modalias = "fb_ssd1351",
444                         .max_speed_hz = 20000000,
445                         .mode = SPI_MODE_0,
446                         .platform_data = &(struct fbtft_platform_data) {
447                                 .display = {
448                                         .buswidth = 8,
449                                         .backlight = FBTFT_ONBOARD_BACKLIGHT,
450                                 },
451                                 .bgr = true,
452                                 .gpios = (const struct fbtft_gpio []) {
453                                         { "reset", 24 },
454                                         { "dc", 25 },
455                                         {},
456                                 },
457                         }
458                 }
459         }, {
460                 .name = "hx8353d",
461                 .spi = &(struct spi_board_info) {
462                         .modalias = "fb_hx8353d",
463                         .max_speed_hz = 16000000,
464                         .mode = SPI_MODE_0,
465                         .platform_data = &(struct fbtft_platform_data) {
466                                 .display = {
467                                         .buswidth = 8,
468                                         .backlight = 1,
469                                 },
470                                 .gpios = (const struct fbtft_gpio []) {
471                                         { "reset", 25 },
472                                         { "dc", 24 },
473                                         { "led", 23 },
474                                         {},
475                                 },
476                         }
477                 }
478         }, {
479                 .name = "hy28a",
480                 .spi = &(struct spi_board_info) {
481                         .modalias = "fb_ili9320",
482                         .max_speed_hz = 32000000,
483                         .mode = SPI_MODE_3,
484                         .platform_data = &(struct fbtft_platform_data) {
485                                 .display = {
486                                         .buswidth = 8,
487                                         .backlight = 1,
488                                 },
489                                 .startbyte = 0x70,
490                                 .bgr = true,
491                                 .gpios = (const struct fbtft_gpio []) {
492                                         { "reset", 25 },
493                                         { "led", 18 },
494                                         {},
495                                 },
496                         }
497                 }
498         }, {
499                 .name = "hy28b",
500                 .spi = &(struct spi_board_info) {
501                         .modalias = "fb_ili9325",
502                         .max_speed_hz = 48000000,
503                         .mode = SPI_MODE_3,
504                         .platform_data = &(struct fbtft_platform_data) {
505                                 .display = {
506                                         .buswidth = 8,
507                                         .backlight = 1,
508                                         .init_sequence = hy28b_init_sequence,
509                                 },
510                                 .startbyte = 0x70,
511                                 .bgr = true,
512                                 .fps = 50,
513                                 .gpios = (const struct fbtft_gpio []) {
514                                         { "reset", 25 },
515                                         { "led", 18 },
516                                         {},
517                                 },
518                                 .gamma = HY28B_GAMMA,
519                         }
520                 }
521         }, {
522                 .name = "ili9481",
523                 .spi = &(struct spi_board_info) {
524                         .modalias = "fb_ili9481",
525                         .max_speed_hz = 32000000,
526                         .mode = SPI_MODE_0,
527                         .platform_data = &(struct fbtft_platform_data) {
528                                 .display = {
529                                         .regwidth = 16,
530                                         .buswidth = 8,
531                                         .backlight = 1,
532                                 },
533                                 .bgr = true,
534                                 .gpios = (const struct fbtft_gpio []) {
535                                         { "reset", 25 },
536                                         { "dc", 24 },
537                                         { "led", 22 },
538                                         {},
539                                 },
540                         }
541                 }
542         }, {
543                 .name = "itdb24",
544                 .pdev = &(struct platform_device) {
545                         .name = "fb_s6d1121",
546                         .id = 0,
547                         .dev = {
548                         .release = fbtft_device_pdev_release,
549                         .platform_data = &(struct fbtft_platform_data) {
550                                 .display = {
551                                         .buswidth = 8,
552                                         .backlight = 1,
553                                 },
554                                 .bgr = false,
555                                 .gpios = (const struct fbtft_gpio []) {
556                                         /* Wiring for LCD adapter kit */
557                                         { "reset", 7 },
558                                         { "dc", 0 },    /* rev 2: 2 */
559                                         { "wr", 1 },    /* rev 2: 3 */
560                                         { "cs", 8 },
561                                         { "db00", 17 },
562                                         { "db01", 18 },
563                                         { "db02", 21 }, /* rev 2: 27 */
564                                         { "db03", 22 },
565                                         { "db04", 23 },
566                                         { "db05", 24 },
567                                         { "db06", 25 },
568                                         { "db07", 4 },
569                                         {}
570                                 },
571                         },
572                         }
573                 }
574         }, {
575                 .name = "itdb28",
576                 .pdev = &(struct platform_device) {
577                         .name = "fb_ili9325",
578                         .id = 0,
579                         .dev = {
580                         .release = fbtft_device_pdev_release,
581                         .platform_data = &(struct fbtft_platform_data) {
582                                 .display = {
583                                         .buswidth = 8,
584                                         .backlight = 1,
585                                 },
586                                 .bgr = true,
587                                 .gpios = (const struct fbtft_gpio []) {
588                                         {},
589                                 },
590                         },
591                         }
592                 }
593         }, {
594                 .name = "itdb28_spi",
595                 .spi = &(struct spi_board_info) {
596                         .modalias = "fb_ili9325",
597                         .max_speed_hz = 32000000,
598                         .mode = SPI_MODE_0,
599                         .platform_data = &(struct fbtft_platform_data) {
600                                 .display = {
601                                         .buswidth = 8,
602                                         .backlight = 1,
603                                 },
604                                 .bgr = true,
605                                 .gpios = (const struct fbtft_gpio []) {
606                                         { "reset", 25 },
607                                         { "dc", 24 },
608                                         {},
609                                 },
610                         }
611                 }
612         }, {
613                 .name = "mi0283qt-2",
614                 .spi = &(struct spi_board_info) {
615                         .modalias = "fb_hx8347d",
616                         .max_speed_hz = 32000000,
617                         .mode = SPI_MODE_0,
618                         .platform_data = &(struct fbtft_platform_data) {
619                                 .display = {
620                                         .buswidth = 8,
621                                         .backlight = 1,
622                                 },
623                                 .startbyte = 0x70,
624                                 .bgr = true,
625                                 .gpios = (const struct fbtft_gpio []) {
626                                         { "reset", 25 },
627                                         { "dc", 24 },
628                                         { "led", 18 },
629                                         {},
630                                 },
631                         }
632                 }
633         }, {
634                 .name = "mi0283qt-9a",
635                 .spi = &(struct spi_board_info) {
636                         .modalias = "fb_ili9341",
637                         .max_speed_hz = 32000000,
638                         .mode = SPI_MODE_0,
639                         .platform_data = &(struct fbtft_platform_data) {
640                                 .display = {
641                                         .buswidth = 9,
642                                         .backlight = 1,
643                                 },
644                                 .bgr = true,
645                                 .gpios = (const struct fbtft_gpio []) {
646                                         { "reset", 25 },
647                                         { "led", 18 },
648                                         {},
649                                 },
650                         }
651                 }
652         }, {
653                 .name = "mi0283qt-v2",
654                 .spi = &(struct spi_board_info) {
655                         .modalias = "fb_watterott",
656                         .max_speed_hz = 4000000,
657                         .mode = SPI_MODE_3,
658                         .platform_data = &(struct fbtft_platform_data) {
659                                 .gpios = (const struct fbtft_gpio []) {
660                                         { "reset", 25 },
661                                         {},
662                                 },
663                         }
664                 }
665         }, {
666                 .name = "nokia3310",
667                 .spi = &(struct spi_board_info) {
668                         .modalias = "fb_pcd8544",
669                         .max_speed_hz = 400000,
670                         .mode = SPI_MODE_0,
671                         .platform_data = &(struct fbtft_platform_data) {
672                                 .display = {
673                                         .buswidth = 8,
674                                 },
675                                 .gpios = (const struct fbtft_gpio []) {
676                                         { "reset", 25 },
677                                         { "dc", 24 },
678                                         { "led", 23 },
679                                         {},
680                                 },
681                         }
682                 }
683         }, {
684                 .name = "nokia3310a",
685                 .spi = &(struct spi_board_info) {
686                         .modalias = "fb_tls8204",
687                         .max_speed_hz = 1000000,
688                         .mode = SPI_MODE_0,
689                         .platform_data = &(struct fbtft_platform_data) {
690                                 .display = {
691                                         .buswidth = 8,
692                                 },
693                                 .gpios = (const struct fbtft_gpio []) {
694                                         { "reset", 25 },
695                                         { "dc", 24 },
696                                         { "led", 23 },
697                                         {},
698                                 },
699                         }
700                 }
701         }, {
702                 .name = "nokia5110",
703                 .spi = &(struct spi_board_info) {
704                         .modalias = "fb_ili9163",
705                         .max_speed_hz = 12000000,
706                         .mode = SPI_MODE_0,
707                         .platform_data = &(struct fbtft_platform_data) {
708                                 .display = {
709                                         .buswidth = 8,
710                                         .backlight = 1,
711                                 },
712                                 .bgr = true,
713                                 .gpios = (const struct fbtft_gpio []) {
714                                         {},
715                                 },
716                         }
717                 }
718         }, {
719
720                 .name = "piscreen",
721                 .spi = &(struct spi_board_info) {
722                         .modalias = "fb_ili9486",
723                         .max_speed_hz = 32000000,
724                         .mode = SPI_MODE_0,
725                         .platform_data = &(struct fbtft_platform_data) {
726                                 .display = {
727                                         .regwidth = 16,
728                                         .buswidth = 8,
729                                         .backlight = 1,
730                                 },
731                                 .bgr = true,
732                                 .gpios = (const struct fbtft_gpio []) {
733                                         { "reset", 25 },
734                                         { "dc", 24 },
735                                         { "led", 22 },
736                                         {},
737                                 },
738                         }
739                 }
740         }, {
741                 .name = "pitft",
742                 .spi = &(struct spi_board_info) {
743                         .modalias = "fb_ili9340",
744                         .max_speed_hz = 32000000,
745                         .mode = SPI_MODE_0,
746                         .chip_select = 0,
747                         .platform_data = &(struct fbtft_platform_data) {
748                                 .display = {
749                                         .buswidth = 8,
750                                         .backlight = 1,
751                                         .init_sequence = pitft_init_sequence,
752                                 },
753                                 .bgr = true,
754                                 .gpios = (const struct fbtft_gpio []) {
755                                         { "dc", 25 },
756                                         {},
757                                 },
758                         }
759                 }
760         }, {
761                 .name = "pioled",
762                 .spi = &(struct spi_board_info) {
763                         .modalias = "fb_ssd1351",
764                         .max_speed_hz = 20000000,
765                         .mode = SPI_MODE_0,
766                         .platform_data = &(struct fbtft_platform_data) {
767                                 .display = {
768                                         .buswidth = 8,
769                                 },
770                                 .bgr = true,
771                                 .gpios = (const struct fbtft_gpio []) {
772                                         { "reset", 24 },
773                                         { "dc", 25 },
774                                         {},
775                                 },
776                                 .gamma =        "0 2 2 2 2 2 2 2 "
777                                                 "2 2 2 2 2 2 2 2 "
778                                                 "2 2 2 2 2 2 2 2 "
779                                                 "2 2 2 2 2 2 2 3 "
780                                                 "3 3 3 3 3 3 3 3 "
781                                                 "3 3 3 3 3 3 3 3 "
782                                                 "3 3 3 4 4 4 4 4 "
783                                                 "4 4 4 4 4 4 4"
784                         }
785                 }
786         }, {
787                 .name = "rpi-display",
788                 .spi = &(struct spi_board_info) {
789                         .modalias = "fb_ili9341",
790                         .max_speed_hz = 32000000,
791                         .mode = SPI_MODE_0,
792                         .platform_data = &(struct fbtft_platform_data) {
793                                 .display = {
794                                         .buswidth = 8,
795                                         .backlight = 1,
796                                 },
797                                 .bgr = true,
798                                 .gpios = (const struct fbtft_gpio []) {
799                                         { "reset", 23 },
800                                         { "dc", 24 },
801                                         { "led", 18 },
802                                         {},
803                                 },
804                         }
805                 }
806         }, {
807                 .name = "s6d02a1",
808                 .spi = &(struct spi_board_info) {
809                         .modalias = "fb_s6d02a1",
810                         .max_speed_hz = 32000000,
811                         .mode = SPI_MODE_0,
812                         .platform_data = &(struct fbtft_platform_data) {
813                                 .display = {
814                                         .buswidth = 8,
815                                         .backlight = 1,
816                                 },
817                                 .bgr = true,
818                                 .gpios = (const struct fbtft_gpio []) {
819                                         { "reset", 25 },
820                                         { "dc", 24 },
821                                         { "led", 23 },
822                                         {},
823                                 },
824                         }
825                 }
826         }, {
827                 .name = "sainsmart18",
828                 .spi = &(struct spi_board_info) {
829                         .modalias = "fb_st7735r",
830                         .max_speed_hz = 32000000,
831                         .mode = SPI_MODE_0,
832                         .platform_data = &(struct fbtft_platform_data) {
833                                 .display = {
834                                         .buswidth = 8,
835                                 },
836                                 .gpios = (const struct fbtft_gpio []) {
837                                         { "reset", 25 },
838                                         { "dc", 24 },
839                                         {},
840                                 },
841                         }
842                 }
843         }, {
844                 .name = "sainsmart32",
845                 .pdev = &(struct platform_device) {
846                         .name = "fb_ssd1289",
847                         .id = 0,
848                         .dev = {
849                         .release = fbtft_device_pdev_release,
850                         .platform_data = &(struct fbtft_platform_data) {
851                                 .display = {
852                                         .buswidth = 16,
853                                         .txbuflen = -2, /* disable buffer */
854                                         .backlight = 1,
855                                         .fbtftops.write = write_gpio16_wr_slow,
856                                 },
857                                 .bgr = true,
858                                 .gpios = (const struct fbtft_gpio []) {
859                                         {},
860                                 },
861                         },
862                 },
863                 }
864         }, {
865                 .name = "sainsmart32_fast",
866                 .pdev = &(struct platform_device) {
867                         .name = "fb_ssd1289",
868                         .id = 0,
869                         .dev = {
870                         .release = fbtft_device_pdev_release,
871                         .platform_data = &(struct fbtft_platform_data) {
872                                 .display = {
873                                         .buswidth = 16,
874                                         .txbuflen = -2, /* disable buffer */
875                                         .backlight = 1,
876                                 },
877                                 .bgr = true,
878                                 .gpios = (const struct fbtft_gpio []) {
879                                         {},
880                                 },
881                         },
882                 },
883                 }
884         }, {
885                 .name = "sainsmart32_latched",
886                 .pdev = &(struct platform_device) {
887                         .name = "fb_ssd1289",
888                         .id = 0,
889                         .dev = {
890                         .release = fbtft_device_pdev_release,
891                         .platform_data = &(struct fbtft_platform_data) {
892                                 .display = {
893                                         .buswidth = 16,
894                                         .txbuflen = -2, /* disable buffer */
895                                         .backlight = 1,
896                                         .fbtftops.write =
897                                                 fbtft_write_gpio16_wr_latched,
898                                 },
899                                 .bgr = true,
900                                 .gpios = (const struct fbtft_gpio []) {
901                                         {},
902                                 },
903                         },
904                 },
905                 }
906         }, {
907                 .name = "sainsmart32_spi",
908                 .spi = &(struct spi_board_info) {
909                         .modalias = "fb_ssd1289",
910                         .max_speed_hz = 16000000,
911                         .mode = SPI_MODE_0,
912                         .platform_data = &(struct fbtft_platform_data) {
913                                 .display = {
914                                         .buswidth = 8,
915                                         .backlight = 1,
916                                 },
917                                 .bgr = true,
918                                 .gpios = (const struct fbtft_gpio []) {
919                                         { "reset", 25 },
920                                         { "dc", 24 },
921                                         {},
922                                 },
923                         }
924                 }
925         }, {
926                 .name = "spidev",
927                 .spi = &(struct spi_board_info) {
928                         .modalias = "spidev",
929                         .max_speed_hz = 500000,
930                         .bus_num = 0,
931                         .chip_select = 0,
932                         .mode = SPI_MODE_0,
933                         .platform_data = &(struct fbtft_platform_data) {
934                                 .gpios = (const struct fbtft_gpio []) {
935                                         {},
936                                 },
937                         }
938                 }
939         }, {
940                 .name = "ssd1331",
941                 .spi = &(struct spi_board_info) {
942                         .modalias = "fb_ssd1331",
943                         .max_speed_hz = 20000000,
944                         .mode = SPI_MODE_3,
945                         .platform_data = &(struct fbtft_platform_data) {
946                                 .display = {
947                                         .buswidth = 8,
948                                 },
949                                 .gpios = (const struct fbtft_gpio []) {
950                                         { "reset", 24 },
951                                         { "dc", 25 },
952                                         {},
953                                 },
954                         }
955                 }
956         }, {
957                 .name = "tinylcd35",
958                 .spi = &(struct spi_board_info) {
959                         .modalias = "fb_tinylcd",
960                         .max_speed_hz = 32000000,
961                         .mode = SPI_MODE_0,
962                         .platform_data = &(struct fbtft_platform_data) {
963                                 .display = {
964                                         .buswidth = 8,
965                                         .backlight = 1,
966                                 },
967                                 .bgr = true,
968                                 .gpios = (const struct fbtft_gpio []) {
969                                         { "reset", 25 },
970                                         { "dc", 24 },
971                                         { "led", 18 },
972                                         {},
973                                 },
974                         }
975                 }
976         }, {
977                 .name = "tm022hdh26",
978                 .spi = &(struct spi_board_info) {
979                         .modalias = "fb_ili9341",
980                         .max_speed_hz = 32000000,
981                         .mode = SPI_MODE_0,
982                         .platform_data = &(struct fbtft_platform_data) {
983                                 .display = {
984                                         .buswidth = 8,
985                                         .backlight = 1,
986                                 },
987                                 .bgr = true,
988                                 .gpios = (const struct fbtft_gpio []) {
989                                         { "reset", 25 },
990                                         { "dc", 24 },
991                                         { "led", 18 },
992                                         {},
993                                 },
994                         }
995                 }
996         }, {
997                 .name = "tontec35_9481", /* boards before 02 July 2014 */
998                 .spi = &(struct spi_board_info) {
999                         .modalias = "fb_ili9481",
1000                         .max_speed_hz = 128000000,
1001                         .mode = SPI_MODE_3,
1002                         .platform_data = &(struct fbtft_platform_data) {
1003                                 .display = {
1004                                         .buswidth = 8,
1005                                         .backlight = 1,
1006                                 },
1007                                 .bgr = true,
1008                                 .gpios = (const struct fbtft_gpio []) {
1009                                         { "reset", 15 },
1010                                         { "dc", 25 },
1011                                         { "led_", 18 },
1012                                         {},
1013                                 },
1014                         }
1015                 }
1016         }, {
1017                 .name = "tontec35_9486", /* boards after 02 July 2014 */
1018                 .spi = &(struct spi_board_info) {
1019                         .modalias = "fb_ili9486",
1020                         .max_speed_hz = 128000000,
1021                         .mode = SPI_MODE_3,
1022                         .platform_data = &(struct fbtft_platform_data) {
1023                                 .display = {
1024                                         .buswidth = 8,
1025                                         .backlight = 1,
1026                                 },
1027                                 .bgr = true,
1028                                 .gpios = (const struct fbtft_gpio []) {
1029                                         { "reset", 15 },
1030                                         { "dc", 25 },
1031                                         { "led_", 18 },
1032                                         {},
1033                                 },
1034                         }
1035                 }
1036         }, {
1037                 .name = "upd161704",
1038                 .spi = &(struct spi_board_info) {
1039                         .modalias = "fb_upd161704",
1040                         .max_speed_hz = 32000000,
1041                         .mode = SPI_MODE_0,
1042                         .platform_data = &(struct fbtft_platform_data) {
1043                                 .display = {
1044                                         .buswidth = 8,
1045                                 },
1046                                 .gpios = (const struct fbtft_gpio []) {
1047                                         { "reset", 24 },
1048                                         { "dc", 25 },
1049                                         {},
1050                                 },
1051                         }
1052                 }
1053         }, {
1054                 .name = "waveshare32b",
1055                 .spi = &(struct spi_board_info) {
1056                         .modalias = "fb_ili9340",
1057                         .max_speed_hz = 48000000,
1058                         .mode = SPI_MODE_0,
1059                         .platform_data = &(struct fbtft_platform_data) {
1060                                 .display = {
1061                                         .buswidth = 8,
1062                                         .backlight = 1,
1063                                         .init_sequence =
1064                                                 waveshare32b_init_sequence,
1065                                 },
1066                                 .bgr = true,
1067                                 .gpios = (const struct fbtft_gpio []) {
1068                                         { "reset", 27 },
1069                                         { "dc", 22 },
1070                                         {},
1071                                 },
1072                         }
1073                 }
1074         }, {
1075                 .name = "waveshare22",
1076                 .spi = &(struct spi_board_info) {
1077                         .modalias = "fb_bd663474",
1078                         .max_speed_hz = 32000000,
1079                         .mode = SPI_MODE_3,
1080                         .platform_data = &(struct fbtft_platform_data) {
1081                                 .display = {
1082                                         .buswidth = 8,
1083                                 },
1084                                 .gpios = (const struct fbtft_gpio []) {
1085                                         { "reset", 24 },
1086                                         { "dc", 25 },
1087                                         {},
1088                                 },
1089                         }
1090                 }
1091         }, {
1092                 /* This should be the last item.
1093                    Used with the custom argument */
1094                 .name = "",
1095                 .spi = &(struct spi_board_info) {
1096                         .modalias = "",
1097                         .max_speed_hz = 0,
1098                         .mode = SPI_MODE_0,
1099                         .platform_data = &(struct fbtft_platform_data) {
1100                                 .gpios = (const struct fbtft_gpio []) {
1101                                         {},
1102                                 },
1103                         }
1104                 },
1105                 .pdev = &(struct platform_device) {
1106                         .name = "",
1107                         .id = 0,
1108                         .dev = {
1109                         .release = fbtft_device_pdev_release,
1110                         .platform_data = &(struct fbtft_platform_data) {
1111                                 .gpios = (const struct fbtft_gpio []) {
1112                                         {},
1113                                 },
1114                         },
1115                 },
1116                 },
1117         }
1118 };
1119
1120 static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len)
1121 {
1122         u16 data;
1123         int i;
1124 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1125         static u16 prev_data;
1126 #endif
1127
1128         fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
1129                 "%s(len=%d): ", __func__, len);
1130
1131         while (len) {
1132                 data = *(u16 *) buf;
1133
1134                 /* Start writing by pulling down /WR */
1135                 gpio_set_value(par->gpio.wr, 0);
1136
1137                 /* Set data */
1138 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1139                 if (data == prev_data) {
1140                         gpio_set_value(par->gpio.wr, 0); /* used as delay */
1141                 } else {
1142                         for (i = 0; i < 16; i++) {
1143                                 if ((data & 1) != (prev_data & 1))
1144                                         gpio_set_value(par->gpio.db[i],
1145                                                                 data & 1);
1146                                 data >>= 1;
1147                                 prev_data >>= 1;
1148                         }
1149                 }
1150 #else
1151                 for (i = 0; i < 16; i++) {
1152                         gpio_set_value(par->gpio.db[i], data & 1);
1153                         data >>= 1;
1154                 }
1155 #endif
1156
1157                 /* Pullup /WR */
1158                 gpio_set_value(par->gpio.wr, 1);
1159
1160 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1161                 prev_data = *(u16 *) buf;
1162 #endif
1163                 buf += 2;
1164                 len -= 2;
1165         }
1166
1167         return 0;
1168 }
1169
1170 static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
1171                                                 int xs, int ys, int xe, int ye)
1172 {
1173         fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
1174                 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
1175         write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
1176         write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
1177         write_reg(par, 0x2C);
1178 }
1179
1180 /* used if gpios parameter is present */
1181 static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS+1] = { };
1182
1183 static void fbtft_device_pdev_release(struct device *dev)
1184 {
1185 /* Needed to silence this message:
1186 Device 'xxx' does not have a release() function, it is broken and must be fixed
1187 */
1188 }
1189
1190 static int spi_device_found(struct device *dev, void *data)
1191 {
1192         struct spi_device *spi = container_of(dev, struct spi_device, dev);
1193
1194         pr_info(DRVNAME":      %s %s %dkHz %d bits mode=0x%02X\n",
1195                 spi->modalias, dev_name(dev), spi->max_speed_hz/1000,
1196                 spi->bits_per_word, spi->mode);
1197
1198         return 0;
1199 }
1200
1201 static void pr_spi_devices(void)
1202 {
1203         pr_info(DRVNAME":  SPI devices registered:\n");
1204         bus_for_each_dev(&spi_bus_type, NULL, NULL, spi_device_found);
1205 }
1206
1207 static int p_device_found(struct device *dev, void *data)
1208 {
1209         struct platform_device
1210         *pdev = container_of(dev, struct platform_device, dev);
1211
1212         if (strstr(pdev->name, "fb"))
1213                 pr_info(DRVNAME":      %s id=%d pdata? %s\n",
1214                                 pdev->name, pdev->id,
1215                                 pdev->dev.platform_data ? "yes" : "no");
1216
1217         return 0;
1218 }
1219
1220 static void pr_p_devices(void)
1221 {
1222         pr_info(DRVNAME":  'fb' Platform devices registered:\n");
1223         bus_for_each_dev(&platform_bus_type, NULL, NULL, p_device_found);
1224 }
1225
1226 #ifdef MODULE
1227 static void fbtft_device_spi_delete(struct spi_master *master, unsigned cs)
1228 {
1229         struct device *dev;
1230         char str[32];
1231
1232         snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), cs);
1233
1234         dev = bus_find_device_by_name(&spi_bus_type, NULL, str);
1235         if (dev) {
1236                 if (verbose)
1237                         pr_info(DRVNAME": Deleting %s\n", str);
1238                 device_del(dev);
1239         }
1240 }
1241
1242 static int fbtft_device_spi_device_register(struct spi_board_info *spi)
1243 {
1244         struct spi_master *master;
1245
1246         master = spi_busnum_to_master(spi->bus_num);
1247         if (!master) {
1248                 pr_err(DRVNAME ":  spi_busnum_to_master(%d) returned NULL\n",
1249                                                                 spi->bus_num);
1250                 return -EINVAL;
1251         }
1252         /* make sure it's available */
1253         fbtft_device_spi_delete(master, spi->chip_select);
1254         spi_device = spi_new_device(master, spi);
1255         put_device(&master->dev);
1256         if (!spi_device) {
1257                 pr_err(DRVNAME ":    spi_new_device() returned NULL\n");
1258                 return -EPERM;
1259         }
1260         return 0;
1261 }
1262 #else
1263 static int fbtft_device_spi_device_register(struct spi_board_info *spi)
1264 {
1265         return spi_register_board_info(spi, 1);
1266 }
1267 #endif
1268
1269 static int __init fbtft_device_init(void)
1270 {
1271         struct spi_board_info *spi = NULL;
1272         struct fbtft_platform_data *pdata;
1273         const struct fbtft_gpio *gpio = NULL;
1274         char *p_gpio, *p_name, *p_num;
1275         bool found = false;
1276         int i = 0;
1277         long val;
1278         int ret = 0;
1279
1280         pr_debug("\n\n"DRVNAME": init\n");
1281
1282         if (name == NULL) {
1283 #ifdef MODULE
1284                 pr_err(DRVNAME":  missing module parameter: 'name'\n");
1285                 return -EINVAL;
1286 #else
1287                 return 0;
1288 #endif
1289         }
1290
1291         if (init_num > FBTFT_MAX_INIT_SEQUENCE) {
1292                 pr_err(DRVNAME
1293                         ":  init parameter: exceeded max array size: %d\n",
1294                         FBTFT_MAX_INIT_SEQUENCE);
1295                 return -EINVAL;
1296         }
1297
1298         /* parse module parameter: gpios */
1299         while ((p_gpio = strsep(&gpios, ","))) {
1300                 if (strchr(p_gpio, ':') == NULL) {
1301                         pr_err(DRVNAME
1302                                 ":  error: missing ':' in gpios parameter: %s\n",
1303                                 p_gpio);
1304                         return -EINVAL;
1305                 }
1306                 p_num = p_gpio;
1307                 p_name = strsep(&p_num, ":");
1308                 if (p_name == NULL || p_num == NULL) {
1309                         pr_err(DRVNAME
1310                                 ":  something bad happened parsing gpios parameter: %s\n",
1311                                 p_gpio);
1312                         return -EINVAL;
1313                 }
1314                 ret = kstrtol(p_num, 10, &val);
1315                 if (ret) {
1316                         pr_err(DRVNAME
1317                                 ":  could not parse number in gpios parameter: %s:%s\n",
1318                                 p_name, p_num);
1319                         return -EINVAL;
1320                 }
1321                 strcpy(fbtft_device_param_gpios[i].name, p_name);
1322                 fbtft_device_param_gpios[i++].gpio = (int) val;
1323                 if (i == MAX_GPIOS) {
1324                         pr_err(DRVNAME
1325                                 ":  gpios parameter: exceeded max array size: %d\n",
1326                                 MAX_GPIOS);
1327                         return -EINVAL;
1328                 }
1329         }
1330         if (fbtft_device_param_gpios[0].name[0])
1331                 gpio = fbtft_device_param_gpios;
1332
1333         if (verbose > 2)
1334                 pr_spi_devices(); /* print list of registered SPI devices */
1335
1336         if (verbose > 2)
1337                 pr_p_devices(); /* print list of 'fb' platform devices */
1338
1339         pr_debug(DRVNAME":  name='%s', busnum=%d, cs=%d\n", name, busnum, cs);
1340
1341         if (rotate > 0 && rotate < 4) {
1342                 rotate = (4 - rotate) * 90;
1343                 pr_warn("argument 'rotate' should be an angle. Values 1-3 is deprecated. Setting it to %d.\n",
1344                         rotate);
1345         }
1346         if (rotate != 0 && rotate != 90 && rotate != 180 && rotate != 270) {
1347                 pr_warn("argument 'rotate' illegal value: %d. Setting it to 0.\n",
1348                         rotate);
1349                 rotate = 0;
1350         }
1351
1352         /* name=list lists all supported displays */
1353         if (strncmp(name, "list", 32) == 0) {
1354                 pr_info(DRVNAME":  Supported displays:\n");
1355
1356                 for (i = 0; i < ARRAY_SIZE(displays); i++)
1357                         pr_info(DRVNAME":      %s\n", displays[i].name);
1358                 return -ECANCELED;
1359         }
1360
1361         if (custom) {
1362                 i = ARRAY_SIZE(displays) - 1;
1363                 displays[i].name = name;
1364                 if (speed == 0) {
1365                         displays[i].pdev->name = name;
1366                         displays[i].spi = NULL;
1367                 } else {
1368                         strncpy(displays[i].spi->modalias, name, SPI_NAME_SIZE);
1369                         displays[i].pdev = NULL;
1370                 }
1371         }
1372
1373         for (i = 0; i < ARRAY_SIZE(displays); i++) {
1374                 if (strncmp(name, displays[i].name, 32) == 0) {
1375                         if (displays[i].spi) {
1376                                 spi = displays[i].spi;
1377                                 spi->chip_select = cs;
1378                                 spi->bus_num = busnum;
1379                                 if (speed)
1380                                         spi->max_speed_hz = speed;
1381                                 if (mode != -1)
1382                                         spi->mode = mode;
1383                                 pdata = (void *)spi->platform_data;
1384                         } else if (displays[i].pdev) {
1385                                 p_device = displays[i].pdev;
1386                                 pdata = p_device->dev.platform_data;
1387                         } else {
1388                                 pr_err(DRVNAME": broken displays array\n");
1389                                 return -EINVAL;
1390                         }
1391
1392                         pdata->rotate = rotate;
1393                         if (bgr == 0)
1394                                 pdata->bgr = false;
1395                         else if (bgr == 1)
1396                                 pdata->bgr = true;
1397                         if (startbyte)
1398                                 pdata->startbyte = startbyte;
1399                         if (gamma)
1400                                 pdata->gamma = gamma;
1401                         pdata->display.debug = debug;
1402                         if (fps)
1403                                 pdata->fps = fps;
1404                         if (txbuflen)
1405                                 pdata->txbuflen = txbuflen;
1406                         if (init_num)
1407                                 pdata->display.init_sequence = init;
1408                         if (gpio)
1409                                 pdata->gpios = gpio;
1410                         if (custom) {
1411                                 pdata->display.width = width;
1412                                 pdata->display.height = height;
1413                                 pdata->display.buswidth = buswidth;
1414                                 pdata->display.backlight = 1;
1415                         }
1416
1417                         if (displays[i].spi) {
1418                                 ret = fbtft_device_spi_device_register(spi);
1419                                 if (ret) {
1420                                         pr_err(DRVNAME
1421                                                 ": failed to register SPI device\n");
1422                                         return ret;
1423                                 }
1424                         } else {
1425                                 ret = platform_device_register(p_device);
1426                                 if (ret < 0) {
1427                                         pr_err(DRVNAME
1428                                                 ":    platform_device_register() returned %d\n",
1429                                                 ret);
1430                                         return ret;
1431                                 }
1432                         }
1433                         found = true;
1434                         break;
1435                 }
1436         }
1437
1438         if (!found) {
1439                 pr_err(DRVNAME":  display not supported: '%s'\n", name);
1440                 return -EINVAL;
1441         }
1442
1443         if (verbose && pdata && pdata->gpios) {
1444                 gpio = pdata->gpios;
1445                 pr_info(DRVNAME":  GPIOS used by '%s':\n", name);
1446                 found = false;
1447                 while (verbose && gpio->name[0]) {
1448                         pr_info(DRVNAME":    '%s' = GPIO%d\n",
1449                                 gpio->name, gpio->gpio);
1450                         gpio++;
1451                         found = true;
1452                 }
1453                 if (!found)
1454                         pr_info(DRVNAME":    (none)\n");
1455         }
1456
1457         if (spi_device && (verbose > 1))
1458                 pr_spi_devices();
1459         if (p_device && (verbose > 1))
1460                 pr_p_devices();
1461
1462         return 0;
1463 }
1464
1465 static void __exit fbtft_device_exit(void)
1466 {
1467         pr_debug(DRVNAME" - exit\n");
1468
1469         if (spi_device) {
1470                 device_del(&spi_device->dev);
1471                 kfree(spi_device);
1472         }
1473
1474         if (p_device)
1475                 platform_device_unregister(p_device);
1476
1477 }
1478
1479 arch_initcall(fbtft_device_init);
1480 module_exit(fbtft_device_exit);
1481
1482 MODULE_DESCRIPTION("Add a FBTFT device.");
1483 MODULE_AUTHOR("Noralf Tronnes");
1484 MODULE_LICENSE("GPL");