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