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