3 * Copyright (C) 2013, Noralf Tronnes
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.
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.
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.
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>
28 #define DRVNAME "fbtft_device"
32 struct spi_device *spi_device;
33 struct platform_device *p_device;
36 module_param(name, charp, 0);
37 MODULE_PARM_DESC(name, "Devicename (required). " \
38 "name=list => list all supported devices.");
40 static unsigned rotate;
41 module_param(rotate, uint, 0);
42 MODULE_PARM_DESC(rotate,
43 "Angle to rotate display counter clockwise: 0, 90, 180, 270");
45 static unsigned busnum;
46 module_param(busnum, uint, 0);
47 MODULE_PARM_DESC(busnum, "SPI bus number (default=0)");
50 module_param(cs, uint, 0);
51 MODULE_PARM_DESC(cs, "SPI chip select (default=0)");
53 static unsigned speed;
54 module_param(speed, uint, 0);
55 MODULE_PARM_DESC(speed, "SPI speed (override device default)");
58 module_param(mode, int, 0);
59 MODULE_PARM_DESC(mode, "SPI mode (override device default)");
62 module_param(gpios, charp, 0);
63 MODULE_PARM_DESC(gpios,
64 "List of gpios. Comma separated with the form: reset:23,dc:24 " \
65 "(when overriding the default, all gpios must be specified)");
68 module_param(fps, uint, 0);
69 MODULE_PARM_DESC(fps, "Frames per second (override driver default)");
72 module_param(gamma, charp, 0);
73 MODULE_PARM_DESC(gamma,
74 "String representation of Gamma Curve(s). Driver specific.");
77 module_param(txbuflen, int, 0);
78 MODULE_PARM_DESC(txbuflen, "txbuflen (override driver default)");
81 module_param(bgr, int, 0);
83 "BGR bit (supported by some drivers).");
85 static unsigned startbyte;
86 module_param(startbyte, uint, 0);
87 MODULE_PARM_DESC(startbyte, "Sets the Start byte used by some SPI displays.");
90 module_param(custom, bool, 0);
91 MODULE_PARM_DESC(custom, "Add a custom display device. " \
92 "Use speed= argument to make it a SPI device, else platform_device");
94 static unsigned width;
95 module_param(width, uint, 0);
96 MODULE_PARM_DESC(width, "Display width, used with the custom argument");
98 static unsigned height;
99 module_param(height, uint, 0);
100 MODULE_PARM_DESC(height, "Display height, used with the custom argument");
102 static unsigned buswidth = 8;
103 module_param(buswidth, uint, 0);
104 MODULE_PARM_DESC(buswidth, "Display bus width, used with the custom argument");
106 static int init[FBTFT_MAX_INIT_SEQUENCE];
108 module_param_array(init, int, &init_num, 0);
109 MODULE_PARM_DESC(init, "Init sequence, used with the custom argument");
111 static unsigned long debug;
112 module_param(debug, ulong , 0);
113 MODULE_PARM_DESC(debug,
114 "level: 0-7 (the remaining 29 bits is for advanced usage)");
116 static unsigned verbose = 3;
117 module_param(verbose, uint, 0);
118 MODULE_PARM_DESC(verbose,
119 "0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)");
122 struct fbtft_device_display {
124 struct spi_board_info *spi;
125 struct platform_device *pdev;
128 static void fbtft_device_pdev_release(struct device *dev);
130 static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len);
131 static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
132 int xs, int ys, int xe, int ye);
134 #define ADAFRUIT18_GAMMA \
135 "02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \
136 "03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10"
138 static int hy28b_init_sequence[] = {
139 -1,0x00e7,0x0010,-1,0x0000,0x0001,-1,0x0001,0x0100,-1,0x0002,0x0700,
140 -1,0x0003,0x1030,-1,0x0004,0x0000,-1,0x0008,0x0207,-1,0x0009,0x0000,
141 -1,0x000a,0x0000,-1,0x000c,0x0001,-1,0x000d,0x0000,-1,0x000f,0x0000,
142 -1,0x0010,0x0000,-1,0x0011,0x0007,-1,0x0012,0x0000,-1,0x0013,0x0000,
143 -2,50,-1,0x0010,0x1590,-1,0x0011,0x0227,-2,50,-1,0x0012,0x009c,-2,50,
144 -1,0x0013,0x1900,-1,0x0029,0x0023,-1,0x002b,0x000e,-2,50,
145 -1,0x0020,0x0000,-1,0x0021,0x0000,-2,50,-1,0x0050,0x0000,
146 -1,0x0051,0x00ef,-1,0x0052,0x0000,-1,0x0053,0x013f,-1,0x0060,0xa700,
147 -1,0x0061,0x0001,-1,0x006a,0x0000,-1,0x0080,0x0000,-1,0x0081,0x0000,
148 -1,0x0082,0x0000,-1,0x0083,0x0000,-1,0x0084,0x0000,-1,0x0085,0x0000,
149 -1,0x0090,0x0010,-1,0x0092,0x0000,-1,0x0093,0x0003,-1,0x0095,0x0110,
150 -1,0x0097,0x0000,-1,0x0098,0x0000,-1,0x0007,0x0133,-1,0x0020,0x0000,
151 -1,0x0021,0x0000,-2,100,-3 };
153 #define HY28B_GAMMA \
154 "04 1F 4 7 7 0 7 7 6 0\n" \
155 "0F 00 1 7 4 0 0 0 6 7"
157 static int pitft_init_sequence[] = {
158 -1,0x01,-2,5,-1,0x28,-1,0xEF,0x03,0x80,0x02,-1,0xCF,0x00,0xC1,0x30,
159 -1,0xED,0x64,0x03,0x12,0x81,-1,0xE8,0x85,0x00,0x78,
160 -1,0xCB,0x39,0x2C,0x00,0x34,0x02,-1,0xF7,0x20,-1,0xEA,0x00,0x00,
161 -1,0xC0,0x23,-1,0xC1,0x10,-1,0xC5,0x3e,0x28,-1,0xC7,0x86,-1,0x3A,0x55,
162 -1,0xB1,0x00,0x18,-1,0xB6,0x08,0x82,0x27,-1,0xF2,0x00,-1,0x26,0x01,
163 -1,0xE0,0x0F,0x31,0x2B,0x0C,0x0E,0x08,0x4E,0xF1,0x37,0x07,0x10,0x03,
164 0x0E,0x09,0x00,-1,0xE1,0x00,0x0E,0x14,0x03,0x11,0x07,0x31,0xC1,0x48,
165 0x08,0x0F,0x0C,0x31,0x36,0x0F,-1,0x11,-2,100,-1,0x29,-2,20,-3 };
167 static int waveshare32b_init_sequence[] = {
168 -1,0xCB,0x39,0x2C,0x00,0x34,0x02,-1,0xCF,0x00,0xC1,0x30,
169 -1,0xE8,0x85,0x00,0x78,-1,0xEA,0x00,0x00,-1,0xED,0x64,0x03,0x12,0x81,
170 -1,0xF7,0x20,-1,0xC0,0x23,-1,0xC1,0x10,-1,0xC5,0x3e,0x28,-1,0xC7,0x86,
171 -1,0x36,0x28,-1,0x3A,0x55,-1,0xB1,0x00,0x18,-1,0xB6,0x08,0x82,0x27,
172 -1,0xF2,0x00,-1,0x26,0x01,
173 -1,0xE0,0x0F,0x31,0x2B,0x0C,0x0E,0x08,0x4E,0xF1,0x37,0x07,0x10,0x03,0x0E,0x09,0x00,
174 -1,0xE1,0x00,0x0E,0x14,0x03,0x11,0x07,0x31,0xC1,0x48,0x08,0x0F,0x0C,0x31,0x36,0x0F,
175 -1,0x11,-2,120,-1,0x29,-1,0x2c,-3 };
177 /* Supported displays in alphabetical order */
178 static struct fbtft_device_display displays[] = {
180 .name = "adafruit18",
181 .spi = &(struct spi_board_info) {
182 .modalias = "fb_st7735r",
183 .max_speed_hz = 32000000,
185 .platform_data = &(struct fbtft_platform_data) {
190 .gpios = (const struct fbtft_gpio []) {
196 .gamma = ADAFRUIT18_GAMMA,
200 .name = "adafruit18_green",
201 .spi = &(struct spi_board_info) {
202 .modalias = "fb_st7735r",
203 .max_speed_hz = 4000000,
205 .platform_data = &(struct fbtft_platform_data) {
209 .fbtftops.set_addr_win = \
210 adafruit18_green_tab_set_addr_win,
213 .gpios = (const struct fbtft_gpio []) {
219 .gamma = ADAFRUIT18_GAMMA,
223 .name = "adafruit22",
224 .spi = &(struct spi_board_info) {
225 .modalias = "fb_hx8340bn",
226 .max_speed_hz = 32000000,
228 .platform_data = &(struct fbtft_platform_data) {
234 .gpios = (const struct fbtft_gpio []) {
242 .name = "adafruit22a",
243 .spi = &(struct spi_board_info) {
244 .modalias = "fb_ili9340",
245 .max_speed_hz = 32000000,
247 .platform_data = &(struct fbtft_platform_data) {
253 .gpios = (const struct fbtft_gpio []) {
262 .name = "adafruit28",
263 .spi = &(struct spi_board_info) {
264 .modalias = "fb_ili9341",
265 .max_speed_hz = 32000000,
267 .platform_data = &(struct fbtft_platform_data) {
273 .gpios = (const struct fbtft_gpio []) {
282 .name = "adafruit13m",
283 .spi = &(struct spi_board_info) {
284 .modalias = "fb_ssd1306",
285 .max_speed_hz = 16000000,
287 .platform_data = &(struct fbtft_platform_data) {
291 .gpios = (const struct fbtft_gpio []) {
299 .name = "agm1264k-fl",
300 .pdev = &(struct platform_device) {
301 .name = "fb_agm1264k-fl",
304 .release = fbtft_device_pdev_release,
305 .platform_data = &(struct fbtft_platform_data) {
308 .backlight = FBTFT_ONBOARD_BACKLIGHT,
310 .gpios = (const struct fbtft_gpio []) {
318 .spi = &(struct spi_board_info) {
319 .modalias = "fb_uc1701",
320 .max_speed_hz = 8000000,
322 .platform_data = &(struct fbtft_platform_data) {
327 .gpios = (const struct fbtft_gpio []) {
335 .name = "er_tftm050_2",
336 .spi = &(struct spi_board_info) {
337 .modalias = "fb_ra8875",
338 .max_speed_hz = 5000000,
340 .platform_data = &(struct fbtft_platform_data) {
348 .gpios = (const struct fbtft_gpio []) {
356 .name = "er_tftm070_5",
357 .spi = &(struct spi_board_info) {
358 .modalias = "fb_ra8875",
359 .max_speed_hz = 5000000,
361 .platform_data = &(struct fbtft_platform_data) {
369 .gpios = (const struct fbtft_gpio []) {
378 .spi = &(struct spi_board_info) {
379 .modalias = "flexfb",
380 .max_speed_hz = 32000000,
382 .platform_data = &(struct fbtft_platform_data) {
383 .gpios = (const struct fbtft_gpio []) {
392 .pdev = &(struct platform_device) {
396 .release = fbtft_device_pdev_release,
397 .platform_data = &(struct fbtft_platform_data) {
398 .gpios = (const struct fbtft_gpio []) {
418 .name = "freetronicsoled128",
419 .spi = &(struct spi_board_info) {
420 .modalias = "fb_ssd1351",
421 .max_speed_hz = 20000000,
423 .platform_data = &(struct fbtft_platform_data) {
426 .backlight = FBTFT_ONBOARD_BACKLIGHT,
429 .gpios = (const struct fbtft_gpio []) {
438 .spi = &(struct spi_board_info) {
439 .modalias = "fb_hx8353d",
440 .max_speed_hz = 16000000,
442 .platform_data = &(struct fbtft_platform_data) {
447 .gpios = (const struct fbtft_gpio []) {
457 .spi = &(struct spi_board_info) {
458 .modalias = "fb_ili9320",
459 .max_speed_hz = 32000000,
461 .platform_data = &(struct fbtft_platform_data) {
466 .startbyte = 0b01110000,
468 .gpios = (const struct fbtft_gpio []) {
477 .spi = &(struct spi_board_info) {
478 .modalias = "fb_ili9325",
479 .max_speed_hz = 48000000,
481 .platform_data = &(struct fbtft_platform_data) {
485 .init_sequence = hy28b_init_sequence,
487 .startbyte = 0b01110000,
490 .gpios = (const struct fbtft_gpio []) {
495 .gamma = HY28B_GAMMA,
500 .spi = &(struct spi_board_info) {
501 .modalias = "fb_ili9481",
502 .max_speed_hz = 32000000,
504 .platform_data = &(struct fbtft_platform_data) {
511 .gpios = (const struct fbtft_gpio []) {
521 .pdev = &(struct platform_device) {
522 .name = "fb_s6d1121",
525 .release = fbtft_device_pdev_release,
526 .platform_data = &(struct fbtft_platform_data) {
532 .gpios = (const struct fbtft_gpio []) {
533 /* Wiring for LCD adapter kit */
535 { "dc", 0 }, /* rev 2: 2 */
536 { "wr", 1 }, /* rev 2: 3 */
540 { "db02", 21 }, /* rev 2: 27 */
553 .pdev = &(struct platform_device) {
554 .name = "fb_ili9325",
557 .release = fbtft_device_pdev_release,
558 .platform_data = &(struct fbtft_platform_data) {
564 .gpios = (const struct fbtft_gpio []) {
571 .name = "itdb28_spi",
572 .spi = &(struct spi_board_info) {
573 .modalias = "fb_ili9325",
574 .max_speed_hz = 32000000,
576 .platform_data = &(struct fbtft_platform_data) {
582 .gpios = (const struct fbtft_gpio []) {
590 .name = "mi0283qt-2",
591 .spi = &(struct spi_board_info) {
592 .modalias = "fb_hx8347d",
593 .max_speed_hz = 32000000,
595 .platform_data = &(struct fbtft_platform_data) {
600 .startbyte = 0b01110000,
602 .gpios = (const struct fbtft_gpio []) {
611 .name = "mi0283qt-9a",
612 .spi = &(struct spi_board_info) {
613 .modalias = "fb_ili9341",
614 .max_speed_hz = 32000000,
616 .platform_data = &(struct fbtft_platform_data) {
622 .gpios = (const struct fbtft_gpio []) {
630 .name = "mi0283qt-v2",
631 .spi = &(struct spi_board_info) {
632 .modalias = "fb_watterott",
633 .max_speed_hz = 4000000,
635 .platform_data = &(struct fbtft_platform_data) {
636 .gpios = (const struct fbtft_gpio []) {
644 .spi = &(struct spi_board_info) {
645 .modalias = "fb_pcd8544",
646 .max_speed_hz = 400000,
648 .platform_data = &(struct fbtft_platform_data) {
652 .gpios = (const struct fbtft_gpio []) {
661 .name = "nokia3310a",
662 .spi = &(struct spi_board_info) {
663 .modalias = "fb_tls8204",
664 .max_speed_hz = 1000000,
666 .platform_data = &(struct fbtft_platform_data) {
670 .gpios = (const struct fbtft_gpio []) {
680 .spi = &(struct spi_board_info) {
681 .modalias = "fb_ili9486",
682 .max_speed_hz = 32000000,
684 .platform_data = &(struct fbtft_platform_data) {
691 .gpios = (const struct fbtft_gpio []) {
701 .spi = &(struct spi_board_info) {
702 .modalias = "fb_ili9340",
703 .max_speed_hz = 32000000,
706 .platform_data = &(struct fbtft_platform_data) {
710 .init_sequence = pitft_init_sequence,
713 .gpios = (const struct fbtft_gpio []) {
721 .spi = &(struct spi_board_info) {
722 .modalias = "fb_ssd1351",
723 .max_speed_hz = 20000000,
725 .platform_data = &(struct fbtft_platform_data) {
730 .gpios = (const struct fbtft_gpio []) {
735 .gamma = "0 2 2 2 2 2 2 2 " \
746 .name = "rpi-display",
747 .spi = &(struct spi_board_info) {
748 .modalias = "fb_ili9341",
749 .max_speed_hz = 32000000,
751 .platform_data = &(struct fbtft_platform_data) {
757 .gpios = (const struct fbtft_gpio []) {
767 .spi = &(struct spi_board_info) {
768 .modalias = "fb_s6d02a1",
769 .max_speed_hz = 32000000,
771 .platform_data = &(struct fbtft_platform_data) {
777 .gpios = (const struct fbtft_gpio []) {
786 .name = "sainsmart18",
787 .spi = &(struct spi_board_info) {
788 .modalias = "fb_st7735r",
789 .max_speed_hz = 32000000,
791 .platform_data = &(struct fbtft_platform_data) {
795 .gpios = (const struct fbtft_gpio []) {
803 .name = "sainsmart32",
804 .pdev = &(struct platform_device) {
805 .name = "fb_ssd1289",
808 .release = fbtft_device_pdev_release,
809 .platform_data = &(struct fbtft_platform_data) {
812 .txbuflen = -2, /* disable buffer */
814 .fbtftops.write = write_gpio16_wr_slow,
817 .gpios = (const struct fbtft_gpio []) {
824 .name = "sainsmart32_fast",
825 .pdev = &(struct platform_device) {
826 .name = "fb_ssd1289",
829 .release = fbtft_device_pdev_release,
830 .platform_data = &(struct fbtft_platform_data) {
833 .txbuflen = -2, /* disable buffer */
837 .gpios = (const struct fbtft_gpio []) {
844 .name = "sainsmart32_latched",
845 .pdev = &(struct platform_device) {
846 .name = "fb_ssd1289",
849 .release = fbtft_device_pdev_release,
850 .platform_data = &(struct fbtft_platform_data) {
853 .txbuflen = -2, /* disable buffer */
856 fbtft_write_gpio16_wr_latched,
859 .gpios = (const struct fbtft_gpio []) {
866 .name = "sainsmart32_spi",
867 .spi = &(struct spi_board_info) {
868 .modalias = "fb_ssd1289",
869 .max_speed_hz = 16000000,
871 .platform_data = &(struct fbtft_platform_data) {
877 .gpios = (const struct fbtft_gpio []) {
886 .spi = &(struct spi_board_info) {
887 .modalias = "spidev",
888 .max_speed_hz = 500000,
892 .platform_data = &(struct fbtft_platform_data) {
893 .gpios = (const struct fbtft_gpio []) {
900 .spi = &(struct spi_board_info) {
901 .modalias = "fb_ssd1331",
902 .max_speed_hz = 20000000,
904 .platform_data = &(struct fbtft_platform_data) {
908 .gpios = (const struct fbtft_gpio []) {
917 .spi = &(struct spi_board_info) {
918 .modalias = "fb_tinylcd",
919 .max_speed_hz = 32000000,
921 .platform_data = &(struct fbtft_platform_data) {
927 .gpios = (const struct fbtft_gpio []) {
936 .name = "tm022hdh26",
937 .spi = &(struct spi_board_info) {
938 .modalias = "fb_ili9341",
939 .max_speed_hz = 32000000,
941 .platform_data = &(struct fbtft_platform_data) {
947 .gpios = (const struct fbtft_gpio []) {
956 .name = "tontec35_9481", /* boards before 02 July 2014 */
957 .spi = &(struct spi_board_info) {
958 .modalias = "fb_ili9481",
959 .max_speed_hz = 128000000,
961 .platform_data = &(struct fbtft_platform_data) {
967 .gpios = (const struct fbtft_gpio []) {
976 .name = "tontec35_9486", /* boards after 02 July 2014 */
977 .spi = &(struct spi_board_info) {
978 .modalias = "fb_ili9486",
979 .max_speed_hz = 128000000,
981 .platform_data = &(struct fbtft_platform_data) {
987 .gpios = (const struct fbtft_gpio []) {
997 .spi = &(struct spi_board_info) {
998 .modalias = "fb_upd161704",
999 .max_speed_hz = 32000000,
1001 .platform_data = &(struct fbtft_platform_data) {
1005 .gpios = (const struct fbtft_gpio []) {
1013 .name = "waveshare32b",
1014 .spi = &(struct spi_board_info) {
1015 .modalias = "fb_ili9340",
1016 .max_speed_hz = 48000000,
1018 .platform_data = &(struct fbtft_platform_data) {
1022 .init_sequence = waveshare32b_init_sequence,
1025 .gpios = (const struct fbtft_gpio []) {
1033 .name = "waveshare22",
1034 .spi = &(struct spi_board_info) {
1035 .modalias = "fb_bd663474",
1036 .max_speed_hz = 32000000,
1038 .platform_data = &(struct fbtft_platform_data) {
1042 .gpios = (const struct fbtft_gpio []) {
1050 /* This should be the last item.
1051 Used with the custom argument */
1053 .spi = &(struct spi_board_info) {
1057 .platform_data = &(struct fbtft_platform_data) {
1058 .gpios = (const struct fbtft_gpio []) {
1063 .pdev = &(struct platform_device) {
1067 .release = fbtft_device_pdev_release,
1068 .platform_data = &(struct fbtft_platform_data) {
1069 .gpios = (const struct fbtft_gpio []) {
1078 static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len)
1082 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1083 static u16 prev_data;
1086 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
1087 "%s(len=%d): ", __func__, len);
1090 data = *(u16 *) buf;
1092 /* Start writing by pulling down /WR */
1093 gpio_set_value(par->gpio.wr, 0);
1096 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1097 if (data == prev_data) {
1098 gpio_set_value(par->gpio.wr, 0); /* used as delay */
1100 for (i = 0; i < 16; i++) {
1101 if ((data & 1) != (prev_data & 1))
1102 gpio_set_value(par->gpio.db[i],
1109 for (i = 0; i < 16; i++) {
1110 gpio_set_value(par->gpio.db[i], (data & 1));
1116 gpio_set_value(par->gpio.wr, 1);
1118 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1119 prev_data = *(u16 *) buf;
1128 static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
1129 int xs, int ys, int xe, int ye)
1131 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
1132 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
1133 write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
1134 write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
1135 write_reg(par, 0x2C);
1138 /* used if gpios parameter is present */
1139 static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS+1] = { };
1141 static void fbtft_device_pdev_release(struct device *dev)
1143 /* Needed to silence this message:
1144 Device 'xxx' does not have a release() function, it is broken and must be fixed
1148 static int spi_device_found(struct device *dev, void *data)
1150 struct spi_device *spi = container_of(dev, struct spi_device, dev);
1152 pr_info(DRVNAME": %s %s %dkHz %d bits mode=0x%02X\n",
1153 spi->modalias, dev_name(dev), spi->max_speed_hz/1000,
1154 spi->bits_per_word, spi->mode);
1159 static void pr_spi_devices(void)
1161 pr_info(DRVNAME": SPI devices registered:\n");
1162 bus_for_each_dev(&spi_bus_type, NULL, NULL, spi_device_found);
1165 static int p_device_found(struct device *dev, void *data)
1167 struct platform_device
1168 *pdev = container_of(dev, struct platform_device, dev);
1170 if (strstr(pdev->name, "fb"))
1171 pr_info(DRVNAME": %s id=%d pdata? %s\n",
1172 pdev->name, pdev->id,
1173 pdev->dev.platform_data ? "yes" : "no");
1178 static void pr_p_devices(void)
1180 pr_info(DRVNAME": 'fb' Platform devices registered:\n");
1181 bus_for_each_dev(&platform_bus_type, NULL, NULL, p_device_found);
1185 static void fbtft_device_spi_delete(struct spi_master *master, unsigned cs)
1190 snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), cs);
1192 dev = bus_find_device_by_name(&spi_bus_type, NULL, str);
1195 pr_info(DRVNAME": Deleting %s\n", str);
1200 static int fbtft_device_spi_device_register(struct spi_board_info *spi)
1202 struct spi_master *master;
1204 master = spi_busnum_to_master(spi->bus_num);
1206 pr_err(DRVNAME ": spi_busnum_to_master(%d) returned NULL\n",
1210 /* make sure it's available */
1211 fbtft_device_spi_delete(master, spi->chip_select);
1212 spi_device = spi_new_device(master, spi);
1213 put_device(&master->dev);
1215 pr_err(DRVNAME ": spi_new_device() returned NULL\n");
1221 static int fbtft_device_spi_device_register(struct spi_board_info *spi)
1223 return spi_register_board_info(spi, 1);
1227 static int __init fbtft_device_init(void)
1229 struct spi_board_info *spi = NULL;
1230 struct fbtft_platform_data *pdata;
1231 const struct fbtft_gpio *gpio = NULL;
1232 char *p_gpio, *p_name, *p_num;
1238 pr_debug("\n\n"DRVNAME": init\n");
1242 pr_err(DRVNAME": missing module parameter: 'name'\n");
1249 if (init_num > FBTFT_MAX_INIT_SEQUENCE) {
1251 ": init parameter: exceeded max array size: %d\n",
1252 FBTFT_MAX_INIT_SEQUENCE);
1256 /* parse module parameter: gpios */
1257 while ((p_gpio = strsep(&gpios, ","))) {
1258 if (strchr(p_gpio, ':') == NULL) {
1260 ": error: missing ':' in gpios parameter: %s\n",
1265 p_name = strsep(&p_num, ":");
1266 if (p_name == NULL || p_num == NULL) {
1268 ": something bad happened parsing gpios parameter: %s\n",
1272 ret = kstrtol(p_num, 10, &val);
1275 ": could not parse number in gpios parameter: %s:%s\n",
1279 strcpy(fbtft_device_param_gpios[i].name, p_name);
1280 fbtft_device_param_gpios[i++].gpio = (int) val;
1281 if (i == MAX_GPIOS) {
1283 ": gpios parameter: exceeded max array size: %d\n",
1288 if (fbtft_device_param_gpios[0].name[0])
1289 gpio = fbtft_device_param_gpios;
1292 pr_spi_devices(); /* print list of registered SPI devices */
1295 pr_p_devices(); /* print list of 'fb' platform devices */
1297 pr_debug(DRVNAME": name='%s', busnum=%d, cs=%d\n", name, busnum, cs);
1299 if (rotate > 0 && rotate < 4) {
1300 rotate = (4 - rotate) * 90;
1301 pr_warn("argument 'rotate' should be an angle. Values 1-3 is deprecated. Setting it to %d.\n",
1304 if (rotate != 0 && rotate != 90 && rotate != 180 && rotate != 270) {
1305 pr_warn("argument 'rotate' illegal value: %d. Setting it to 0.\n",
1310 /* name=list lists all supported displays */
1311 if (strncmp(name, "list", 32) == 0) {
1312 pr_info(DRVNAME": Supported displays:\n");
1314 for (i = 0; i < ARRAY_SIZE(displays); i++)
1315 pr_info(DRVNAME": %s\n", displays[i].name);
1320 i = ARRAY_SIZE(displays) - 1;
1321 displays[i].name = name;
1323 displays[i].pdev->name = name;
1324 displays[i].spi = NULL;
1326 strncpy(displays[i].spi->modalias, name, SPI_NAME_SIZE);
1327 displays[i].pdev = NULL;
1331 for (i = 0; i < ARRAY_SIZE(displays); i++) {
1332 if (strncmp(name, displays[i].name, 32) == 0) {
1333 if (displays[i].spi) {
1334 spi = displays[i].spi;
1335 spi->chip_select = cs;
1336 spi->bus_num = busnum;
1338 spi->max_speed_hz = speed;
1341 pdata = (void *)spi->platform_data;
1342 } else if (displays[i].pdev) {
1343 p_device = displays[i].pdev;
1344 pdata = p_device->dev.platform_data;
1346 pr_err(DRVNAME": broken displays array\n");
1350 pdata->rotate = rotate;
1356 pdata->startbyte = startbyte;
1358 pdata->gamma = gamma;
1359 pdata->display.debug = debug;
1363 pdata->txbuflen = txbuflen;
1365 pdata->display.init_sequence = init;
1367 pdata->gpios = gpio;
1369 pdata->display.width = width;
1370 pdata->display.height = height;
1371 pdata->display.buswidth = buswidth;
1372 pdata->display.backlight = 1;
1375 if (displays[i].spi) {
1376 ret = fbtft_device_spi_device_register(spi);
1379 ": failed to register SPI device\n");
1385 ret = platform_device_register(p_device);
1388 ": platform_device_register() returned %d\n",
1399 pr_err(DRVNAME": display not supported: '%s'\n", name);
1403 if (verbose && pdata && pdata->gpios) {
1404 gpio = pdata->gpios;
1405 pr_info(DRVNAME": GPIOS used by '%s':\n", name);
1407 while (verbose && gpio->name[0]) {
1408 pr_info(DRVNAME": '%s' = GPIO%d\n",
1409 gpio->name, gpio->gpio);
1414 pr_info(DRVNAME": (none)\n");
1417 if (spi_device && (verbose > 1))
1419 if (p_device && (verbose > 1))
1425 static void __exit fbtft_device_exit(void)
1427 pr_debug(DRVNAME" - exit\n");
1430 device_del(&spi_device->dev);
1435 platform_device_unregister(p_device);
1439 arch_initcall(fbtft_device_init);
1440 module_exit(fbtft_device_exit);
1442 MODULE_DESCRIPTION("Add a FBTFT device.");
1443 MODULE_AUTHOR("Noralf Tronnes");
1444 MODULE_LICENSE("GPL");