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 static struct spi_device
*spi_device
;
33 static struct platform_device
*p_device
;
36 module_param(name
, charp
, 0);
37 MODULE_PARM_DESC(name
, "Devicename (required). name=list => list all supported devices.");
39 static unsigned rotate
;
40 module_param(rotate
, uint
, 0);
41 MODULE_PARM_DESC(rotate
,
42 "Angle to rotate display counter clockwise: 0, 90, 180, 270");
44 static unsigned busnum
;
45 module_param(busnum
, uint
, 0);
46 MODULE_PARM_DESC(busnum
, "SPI bus number (default=0)");
49 module_param(cs
, uint
, 0);
50 MODULE_PARM_DESC(cs
, "SPI chip select (default=0)");
52 static unsigned speed
;
53 module_param(speed
, uint
, 0);
54 MODULE_PARM_DESC(speed
, "SPI speed (override device default)");
57 module_param(mode
, int, 0);
58 MODULE_PARM_DESC(mode
, "SPI mode (override device default)");
61 module_param(gpios
, charp
, 0);
62 MODULE_PARM_DESC(gpios
,
63 "List of gpios. Comma separated with the form: reset:23,dc:24 (when overriding the default, all gpios must be specified)");
66 module_param(fps
, uint
, 0);
67 MODULE_PARM_DESC(fps
, "Frames per second (override driver default)");
70 module_param(gamma
, charp
, 0);
71 MODULE_PARM_DESC(gamma
,
72 "String representation of Gamma Curve(s). Driver specific.");
75 module_param(txbuflen
, int, 0);
76 MODULE_PARM_DESC(txbuflen
, "txbuflen (override driver default)");
79 module_param(bgr
, int, 0);
81 "BGR bit (supported by some drivers).");
83 static unsigned startbyte
;
84 module_param(startbyte
, uint
, 0);
85 MODULE_PARM_DESC(startbyte
, "Sets the Start byte used by some SPI displays.");
88 module_param(custom
, bool, 0);
89 MODULE_PARM_DESC(custom
, "Add a custom display device. Use speed= argument to make it a SPI device, else platform_device");
91 static unsigned width
;
92 module_param(width
, uint
, 0);
93 MODULE_PARM_DESC(width
, "Display width, used with the custom argument");
95 static unsigned height
;
96 module_param(height
, uint
, 0);
97 MODULE_PARM_DESC(height
, "Display height, used with the custom argument");
99 static unsigned buswidth
= 8;
100 module_param(buswidth
, uint
, 0);
101 MODULE_PARM_DESC(buswidth
, "Display bus width, used with the custom argument");
103 static int init
[FBTFT_MAX_INIT_SEQUENCE
];
105 module_param_array(init
, int, &init_num
, 0);
106 MODULE_PARM_DESC(init
, "Init sequence, used with the custom argument");
108 static unsigned long debug
;
109 module_param(debug
, ulong
, 0);
110 MODULE_PARM_DESC(debug
,
111 "level: 0-7 (the remaining 29 bits is for advanced usage)");
113 static unsigned verbose
= 3;
114 module_param(verbose
, uint
, 0);
115 MODULE_PARM_DESC(verbose
,
116 "0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)");
119 struct fbtft_device_display
{
121 struct spi_board_info
*spi
;
122 struct platform_device
*pdev
;
125 static void fbtft_device_pdev_release(struct device
*dev
);
127 static int write_gpio16_wr_slow(struct fbtft_par
*par
, void *buf
, size_t len
);
128 static void adafruit18_green_tab_set_addr_win(struct fbtft_par
*par
,
129 int xs
, int ys
, int xe
, int ye
);
131 #define ADAFRUIT18_GAMMA \
132 "02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \
133 "03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10"
135 static int hy28b_init_sequence
[] = {
136 -1, 0x00e7, 0x0010, -1, 0x0000, 0x0001,
137 -1, 0x0001, 0x0100, -1, 0x0002, 0x0700,
138 -1, 0x0003, 0x1030, -1, 0x0004, 0x0000,
139 -1, 0x0008, 0x0207, -1, 0x0009, 0x0000,
140 -1, 0x000a, 0x0000, -1, 0x000c, 0x0001,
141 -1, 0x000d, 0x0000, -1, 0x000f, 0x0000,
142 -1, 0x0010, 0x0000, -1, 0x0011, 0x0007,
143 -1, 0x0012, 0x0000, -1, 0x0013, 0x0000,
144 -2, 50, -1, 0x0010, 0x1590, -1, 0x0011,
145 0x0227, -2, 50, -1, 0x0012, 0x009c, -2, 50,
146 -1, 0x0013, 0x1900, -1, 0x0029, 0x0023,
147 -1, 0x002b, 0x000e, -2, 50,
148 -1, 0x0020, 0x0000, -1, 0x0021, 0x0000,
149 -2, 50, -1, 0x0050, 0x0000,
150 -1, 0x0051, 0x00ef, -1, 0x0052, 0x0000,
151 -1, 0x0053, 0x013f, -1, 0x0060, 0xa700,
152 -1, 0x0061, 0x0001, -1, 0x006a, 0x0000,
153 -1, 0x0080, 0x0000, -1, 0x0081, 0x0000,
154 -1, 0x0082, 0x0000, -1, 0x0083, 0x0000,
155 -1, 0x0084, 0x0000, -1, 0x0085, 0x0000,
156 -1, 0x0090, 0x0010, -1, 0x0092, 0x0000,
157 -1, 0x0093, 0x0003, -1, 0x0095, 0x0110,
158 -1, 0x0097, 0x0000, -1, 0x0098, 0x0000,
159 -1, 0x0007, 0x0133, -1, 0x0020, 0x0000,
160 -1, 0x0021, 0x0000, -2, 100, -3 };
162 #define HY28B_GAMMA \
163 "04 1F 4 7 7 0 7 7 6 0\n" \
164 "0F 00 1 7 4 0 0 0 6 7"
166 static int pitft_init_sequence
[] = {
167 -1, 0x01, -2, 5, -1, 0x28, -1, 0xEF,
168 0x03, 0x80, 0x02, -1, 0xCF, 0x00, 0xC1, 0x30,
169 -1, 0xED, 0x64, 0x03, 0x12, 0x81,
170 -1, 0xE8, 0x85, 0x00, 0x78,
171 -1, 0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02,
172 -1, 0xF7, 0x20, -1, 0xEA, 0x00, 0x00,
173 -1, 0xC0, 0x23, -1, 0xC1, 0x10, -1, 0xC5,
174 0x3e, 0x28, -1, 0xC7, 0x86, -1, 0x3A, 0x55,
175 -1, 0xB1, 0x00, 0x18, -1, 0xB6, 0x08, 0x82,
176 0x27, -1, 0xF2, 0x00, -1, 0x26, 0x01,
177 -1, 0xE0, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08,
178 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03,
179 0x0E, 0x09, 0x00, -1, 0xE1, 0x00, 0x0E, 0x14,
180 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48,
181 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, -1,
182 0x11, -2, 100, -1, 0x29, -2, 20, -3 };
184 static int waveshare32b_init_sequence
[] = {
185 -1, 0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02,
186 -1, 0xCF, 0x00, 0xC1, 0x30,
187 -1, 0xE8, 0x85, 0x00, 0x78, -1, 0xEA, 0x00,
188 0x00, -1, 0xED, 0x64, 0x03, 0x12, 0x81,
189 -1, 0xF7, 0x20, -1, 0xC0, 0x23, -1, 0xC1,
190 0x10, -1, 0xC5, 0x3e, 0x28, -1, 0xC7, 0x86,
191 -1, 0x36, 0x28, -1, 0x3A, 0x55, -1, 0xB1, 0x00,
192 0x18, -1, 0xB6, 0x08, 0x82, 0x27,
193 -1, 0xF2, 0x00, -1, 0x26, 0x01,
194 -1, 0xE0, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E,
195 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
196 -1, 0xE1, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31,
197 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
198 -1, 0x11, -2, 120, -1, 0x29, -1, 0x2c, -3 };
200 /* Supported displays in alphabetical order */
201 static struct fbtft_device_display displays
[] = {
203 .name
= "adafruit18",
204 .spi
= &(struct spi_board_info
) {
205 .modalias
= "fb_st7735r",
206 .max_speed_hz
= 32000000,
208 .platform_data
= &(struct fbtft_platform_data
) {
213 .gpios
= (const struct fbtft_gpio
[]) {
219 .gamma
= ADAFRUIT18_GAMMA
,
223 .name
= "adafruit18_green",
224 .spi
= &(struct spi_board_info
) {
225 .modalias
= "fb_st7735r",
226 .max_speed_hz
= 4000000,
228 .platform_data
= &(struct fbtft_platform_data
) {
232 .fbtftops
.set_addr_win
=
233 adafruit18_green_tab_set_addr_win
,
236 .gpios
= (const struct fbtft_gpio
[]) {
242 .gamma
= ADAFRUIT18_GAMMA
,
246 .name
= "adafruit22",
247 .spi
= &(struct spi_board_info
) {
248 .modalias
= "fb_hx8340bn",
249 .max_speed_hz
= 32000000,
251 .platform_data
= &(struct fbtft_platform_data
) {
257 .gpios
= (const struct fbtft_gpio
[]) {
265 .name
= "adafruit22a",
266 .spi
= &(struct spi_board_info
) {
267 .modalias
= "fb_ili9340",
268 .max_speed_hz
= 32000000,
270 .platform_data
= &(struct fbtft_platform_data
) {
276 .gpios
= (const struct fbtft_gpio
[]) {
285 .name
= "adafruit28",
286 .spi
= &(struct spi_board_info
) {
287 .modalias
= "fb_ili9341",
288 .max_speed_hz
= 32000000,
290 .platform_data
= &(struct fbtft_platform_data
) {
296 .gpios
= (const struct fbtft_gpio
[]) {
305 .name
= "adafruit13m",
306 .spi
= &(struct spi_board_info
) {
307 .modalias
= "fb_ssd1306",
308 .max_speed_hz
= 16000000,
310 .platform_data
= &(struct fbtft_platform_data
) {
314 .gpios
= (const struct fbtft_gpio
[]) {
322 .name
= "agm1264k-fl",
323 .pdev
= &(struct platform_device
) {
324 .name
= "fb_agm1264k-fl",
327 .release
= fbtft_device_pdev_release
,
328 .platform_data
= &(struct fbtft_platform_data
) {
331 .backlight
= FBTFT_ONBOARD_BACKLIGHT
,
333 .gpios
= (const struct fbtft_gpio
[]) {
341 .spi
= &(struct spi_board_info
) {
342 .modalias
= "fb_uc1701",
343 .max_speed_hz
= 8000000,
345 .platform_data
= &(struct fbtft_platform_data
) {
350 .gpios
= (const struct fbtft_gpio
[]) {
358 .name
= "er_tftm050_2",
359 .spi
= &(struct spi_board_info
) {
360 .modalias
= "fb_ra8875",
361 .max_speed_hz
= 5000000,
363 .platform_data
= &(struct fbtft_platform_data
) {
371 .gpios
= (const struct fbtft_gpio
[]) {
379 .name
= "er_tftm070_5",
380 .spi
= &(struct spi_board_info
) {
381 .modalias
= "fb_ra8875",
382 .max_speed_hz
= 5000000,
384 .platform_data
= &(struct fbtft_platform_data
) {
392 .gpios
= (const struct fbtft_gpio
[]) {
401 .spi
= &(struct spi_board_info
) {
402 .modalias
= "fb_uc1611",
403 .max_speed_hz
= 32000000,
405 .platform_data
= &(struct fbtft_platform_data
) {
409 .gpios
= (const struct fbtft_gpio
[]) {
416 .name
= "ew24ha0_9bit",
417 .spi
= &(struct spi_board_info
) {
418 .modalias
= "fb_uc1611",
419 .max_speed_hz
= 32000000,
421 .platform_data
= &(struct fbtft_platform_data
) {
425 .gpios
= (const struct fbtft_gpio
[]) {
432 .spi
= &(struct spi_board_info
) {
433 .modalias
= "flexfb",
434 .max_speed_hz
= 32000000,
436 .platform_data
= &(struct fbtft_platform_data
) {
437 .gpios
= (const struct fbtft_gpio
[]) {
446 .pdev
= &(struct platform_device
) {
450 .release
= fbtft_device_pdev_release
,
451 .platform_data
= &(struct fbtft_platform_data
) {
452 .gpios
= (const struct fbtft_gpio
[]) {
472 .name
= "freetronicsoled128",
473 .spi
= &(struct spi_board_info
) {
474 .modalias
= "fb_ssd1351",
475 .max_speed_hz
= 20000000,
477 .platform_data
= &(struct fbtft_platform_data
) {
480 .backlight
= FBTFT_ONBOARD_BACKLIGHT
,
483 .gpios
= (const struct fbtft_gpio
[]) {
492 .spi
= &(struct spi_board_info
) {
493 .modalias
= "fb_hx8353d",
494 .max_speed_hz
= 16000000,
496 .platform_data
= &(struct fbtft_platform_data
) {
501 .gpios
= (const struct fbtft_gpio
[]) {
511 .spi
= &(struct spi_board_info
) {
512 .modalias
= "fb_ili9320",
513 .max_speed_hz
= 32000000,
515 .platform_data
= &(struct fbtft_platform_data
) {
522 .gpios
= (const struct fbtft_gpio
[]) {
531 .spi
= &(struct spi_board_info
) {
532 .modalias
= "fb_ili9325",
533 .max_speed_hz
= 48000000,
535 .platform_data
= &(struct fbtft_platform_data
) {
539 .init_sequence
= hy28b_init_sequence
,
544 .gpios
= (const struct fbtft_gpio
[]) {
549 .gamma
= HY28B_GAMMA
,
554 .spi
= &(struct spi_board_info
) {
555 .modalias
= "fb_ili9481",
556 .max_speed_hz
= 32000000,
558 .platform_data
= &(struct fbtft_platform_data
) {
565 .gpios
= (const struct fbtft_gpio
[]) {
575 .pdev
= &(struct platform_device
) {
576 .name
= "fb_s6d1121",
579 .release
= fbtft_device_pdev_release
,
580 .platform_data
= &(struct fbtft_platform_data
) {
586 .gpios
= (const struct fbtft_gpio
[]) {
587 /* Wiring for LCD adapter kit */
589 { "dc", 0 }, /* rev 2: 2 */
590 { "wr", 1 }, /* rev 2: 3 */
594 { "db02", 21 }, /* rev 2: 27 */
607 .pdev
= &(struct platform_device
) {
608 .name
= "fb_ili9325",
611 .release
= fbtft_device_pdev_release
,
612 .platform_data
= &(struct fbtft_platform_data
) {
618 .gpios
= (const struct fbtft_gpio
[]) {
625 .name
= "itdb28_spi",
626 .spi
= &(struct spi_board_info
) {
627 .modalias
= "fb_ili9325",
628 .max_speed_hz
= 32000000,
630 .platform_data
= &(struct fbtft_platform_data
) {
636 .gpios
= (const struct fbtft_gpio
[]) {
644 .name
= "mi0283qt-2",
645 .spi
= &(struct spi_board_info
) {
646 .modalias
= "fb_hx8347d",
647 .max_speed_hz
= 32000000,
649 .platform_data
= &(struct fbtft_platform_data
) {
656 .gpios
= (const struct fbtft_gpio
[]) {
665 .name
= "mi0283qt-9a",
666 .spi
= &(struct spi_board_info
) {
667 .modalias
= "fb_ili9341",
668 .max_speed_hz
= 32000000,
670 .platform_data
= &(struct fbtft_platform_data
) {
676 .gpios
= (const struct fbtft_gpio
[]) {
684 .name
= "mi0283qt-v2",
685 .spi
= &(struct spi_board_info
) {
686 .modalias
= "fb_watterott",
687 .max_speed_hz
= 4000000,
689 .platform_data
= &(struct fbtft_platform_data
) {
690 .gpios
= (const struct fbtft_gpio
[]) {
698 .spi
= &(struct spi_board_info
) {
699 .modalias
= "fb_pcd8544",
700 .max_speed_hz
= 400000,
702 .platform_data
= &(struct fbtft_platform_data
) {
706 .gpios
= (const struct fbtft_gpio
[]) {
715 .name
= "nokia3310a",
716 .spi
= &(struct spi_board_info
) {
717 .modalias
= "fb_tls8204",
718 .max_speed_hz
= 1000000,
720 .platform_data
= &(struct fbtft_platform_data
) {
724 .gpios
= (const struct fbtft_gpio
[]) {
734 .spi
= &(struct spi_board_info
) {
735 .modalias
= "fb_ili9163",
736 .max_speed_hz
= 12000000,
738 .platform_data
= &(struct fbtft_platform_data
) {
744 .gpios
= (const struct fbtft_gpio
[]) {
752 .spi
= &(struct spi_board_info
) {
753 .modalias
= "fb_ili9486",
754 .max_speed_hz
= 32000000,
756 .platform_data
= &(struct fbtft_platform_data
) {
763 .gpios
= (const struct fbtft_gpio
[]) {
773 .spi
= &(struct spi_board_info
) {
774 .modalias
= "fb_ili9340",
775 .max_speed_hz
= 32000000,
778 .platform_data
= &(struct fbtft_platform_data
) {
782 .init_sequence
= pitft_init_sequence
,
785 .gpios
= (const struct fbtft_gpio
[]) {
793 .spi
= &(struct spi_board_info
) {
794 .modalias
= "fb_ssd1351",
795 .max_speed_hz
= 20000000,
797 .platform_data
= &(struct fbtft_platform_data
) {
802 .gpios
= (const struct fbtft_gpio
[]) {
807 .gamma
= "0 2 2 2 2 2 2 2 "
818 .name
= "rpi-display",
819 .spi
= &(struct spi_board_info
) {
820 .modalias
= "fb_ili9341",
821 .max_speed_hz
= 32000000,
823 .platform_data
= &(struct fbtft_platform_data
) {
829 .gpios
= (const struct fbtft_gpio
[]) {
839 .spi
= &(struct spi_board_info
) {
840 .modalias
= "fb_s6d02a1",
841 .max_speed_hz
= 32000000,
843 .platform_data
= &(struct fbtft_platform_data
) {
849 .gpios
= (const struct fbtft_gpio
[]) {
858 .name
= "sainsmart18",
859 .spi
= &(struct spi_board_info
) {
860 .modalias
= "fb_st7735r",
861 .max_speed_hz
= 32000000,
863 .platform_data
= &(struct fbtft_platform_data
) {
867 .gpios
= (const struct fbtft_gpio
[]) {
875 .name
= "sainsmart32",
876 .pdev
= &(struct platform_device
) {
877 .name
= "fb_ssd1289",
880 .release
= fbtft_device_pdev_release
,
881 .platform_data
= &(struct fbtft_platform_data
) {
884 .txbuflen
= -2, /* disable buffer */
886 .fbtftops
.write
= write_gpio16_wr_slow
,
889 .gpios
= (const struct fbtft_gpio
[]) {
896 .name
= "sainsmart32_fast",
897 .pdev
= &(struct platform_device
) {
898 .name
= "fb_ssd1289",
901 .release
= fbtft_device_pdev_release
,
902 .platform_data
= &(struct fbtft_platform_data
) {
905 .txbuflen
= -2, /* disable buffer */
909 .gpios
= (const struct fbtft_gpio
[]) {
916 .name
= "sainsmart32_latched",
917 .pdev
= &(struct platform_device
) {
918 .name
= "fb_ssd1289",
921 .release
= fbtft_device_pdev_release
,
922 .platform_data
= &(struct fbtft_platform_data
) {
925 .txbuflen
= -2, /* disable buffer */
928 fbtft_write_gpio16_wr_latched
,
931 .gpios
= (const struct fbtft_gpio
[]) {
938 .name
= "sainsmart32_spi",
939 .spi
= &(struct spi_board_info
) {
940 .modalias
= "fb_ssd1289",
941 .max_speed_hz
= 16000000,
943 .platform_data
= &(struct fbtft_platform_data
) {
949 .gpios
= (const struct fbtft_gpio
[]) {
958 .spi
= &(struct spi_board_info
) {
959 .modalias
= "spidev",
960 .max_speed_hz
= 500000,
964 .platform_data
= &(struct fbtft_platform_data
) {
965 .gpios
= (const struct fbtft_gpio
[]) {
972 .spi
= &(struct spi_board_info
) {
973 .modalias
= "fb_ssd1331",
974 .max_speed_hz
= 20000000,
976 .platform_data
= &(struct fbtft_platform_data
) {
980 .gpios
= (const struct fbtft_gpio
[]) {
989 .spi
= &(struct spi_board_info
) {
990 .modalias
= "fb_tinylcd",
991 .max_speed_hz
= 32000000,
993 .platform_data
= &(struct fbtft_platform_data
) {
999 .gpios
= (const struct fbtft_gpio
[]) {
1008 .name
= "tm022hdh26",
1009 .spi
= &(struct spi_board_info
) {
1010 .modalias
= "fb_ili9341",
1011 .max_speed_hz
= 32000000,
1013 .platform_data
= &(struct fbtft_platform_data
) {
1019 .gpios
= (const struct fbtft_gpio
[]) {
1028 .name
= "tontec35_9481", /* boards before 02 July 2014 */
1029 .spi
= &(struct spi_board_info
) {
1030 .modalias
= "fb_ili9481",
1031 .max_speed_hz
= 128000000,
1033 .platform_data
= &(struct fbtft_platform_data
) {
1039 .gpios
= (const struct fbtft_gpio
[]) {
1048 .name
= "tontec35_9486", /* boards after 02 July 2014 */
1049 .spi
= &(struct spi_board_info
) {
1050 .modalias
= "fb_ili9486",
1051 .max_speed_hz
= 128000000,
1053 .platform_data
= &(struct fbtft_platform_data
) {
1059 .gpios
= (const struct fbtft_gpio
[]) {
1068 .name
= "upd161704",
1069 .spi
= &(struct spi_board_info
) {
1070 .modalias
= "fb_upd161704",
1071 .max_speed_hz
= 32000000,
1073 .platform_data
= &(struct fbtft_platform_data
) {
1077 .gpios
= (const struct fbtft_gpio
[]) {
1085 .name
= "waveshare32b",
1086 .spi
= &(struct spi_board_info
) {
1087 .modalias
= "fb_ili9340",
1088 .max_speed_hz
= 48000000,
1090 .platform_data
= &(struct fbtft_platform_data
) {
1095 waveshare32b_init_sequence
,
1098 .gpios
= (const struct fbtft_gpio
[]) {
1106 .name
= "waveshare22",
1107 .spi
= &(struct spi_board_info
) {
1108 .modalias
= "fb_bd663474",
1109 .max_speed_hz
= 32000000,
1111 .platform_data
= &(struct fbtft_platform_data
) {
1115 .gpios
= (const struct fbtft_gpio
[]) {
1123 /* This should be the last item.
1124 Used with the custom argument */
1126 .spi
= &(struct spi_board_info
) {
1130 .platform_data
= &(struct fbtft_platform_data
) {
1131 .gpios
= (const struct fbtft_gpio
[]) {
1136 .pdev
= &(struct platform_device
) {
1140 .release
= fbtft_device_pdev_release
,
1141 .platform_data
= &(struct fbtft_platform_data
) {
1142 .gpios
= (const struct fbtft_gpio
[]) {
1151 static int write_gpio16_wr_slow(struct fbtft_par
*par
, void *buf
, size_t len
)
1155 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1156 static u16 prev_data
;
1159 fbtft_par_dbg_hex(DEBUG_WRITE
, par
, par
->info
->device
, u8
, buf
, len
,
1160 "%s(len=%d): ", __func__
, len
);
1163 data
= *(u16
*) buf
;
1165 /* Start writing by pulling down /WR */
1166 gpio_set_value(par
->gpio
.wr
, 0);
1169 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1170 if (data
== prev_data
) {
1171 gpio_set_value(par
->gpio
.wr
, 0); /* used as delay */
1173 for (i
= 0; i
< 16; i
++) {
1174 if ((data
& 1) != (prev_data
& 1))
1175 gpio_set_value(par
->gpio
.db
[i
],
1182 for (i
= 0; i
< 16; i
++) {
1183 gpio_set_value(par
->gpio
.db
[i
], data
& 1);
1189 gpio_set_value(par
->gpio
.wr
, 1);
1191 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1192 prev_data
= *(u16
*) buf
;
1201 static void adafruit18_green_tab_set_addr_win(struct fbtft_par
*par
,
1202 int xs
, int ys
, int xe
, int ye
)
1204 fbtft_par_dbg(DEBUG_SET_ADDR_WIN
, par
,
1205 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__
, xs
, ys
, xe
, ye
);
1206 write_reg(par
, 0x2A, 0, xs
+ 2, 0, xe
+ 2);
1207 write_reg(par
, 0x2B, 0, ys
+ 1, 0, ye
+ 1);
1208 write_reg(par
, 0x2C);
1211 /* used if gpios parameter is present */
1212 static struct fbtft_gpio fbtft_device_param_gpios
[MAX_GPIOS
+1] = { };
1214 static void fbtft_device_pdev_release(struct device
*dev
)
1216 /* Needed to silence this message:
1217 Device 'xxx' does not have a release() function, it is broken and must be fixed
1221 static int spi_device_found(struct device
*dev
, void *data
)
1223 struct spi_device
*spi
= container_of(dev
, struct spi_device
, dev
);
1225 pr_info(DRVNAME
": %s %s %dkHz %d bits mode=0x%02X\n",
1226 spi
->modalias
, dev_name(dev
), spi
->max_speed_hz
/1000,
1227 spi
->bits_per_word
, spi
->mode
);
1232 static void pr_spi_devices(void)
1234 pr_info(DRVNAME
": SPI devices registered:\n");
1235 bus_for_each_dev(&spi_bus_type
, NULL
, NULL
, spi_device_found
);
1238 static int p_device_found(struct device
*dev
, void *data
)
1240 struct platform_device
1241 *pdev
= container_of(dev
, struct platform_device
, dev
);
1243 if (strstr(pdev
->name
, "fb"))
1244 pr_info(DRVNAME
": %s id=%d pdata? %s\n",
1245 pdev
->name
, pdev
->id
,
1246 pdev
->dev
.platform_data
? "yes" : "no");
1251 static void pr_p_devices(void)
1253 pr_info(DRVNAME
": 'fb' Platform devices registered:\n");
1254 bus_for_each_dev(&platform_bus_type
, NULL
, NULL
, p_device_found
);
1258 static void fbtft_device_spi_delete(struct spi_master
*master
, unsigned cs
)
1263 snprintf(str
, sizeof(str
), "%s.%u", dev_name(&master
->dev
), cs
);
1265 dev
= bus_find_device_by_name(&spi_bus_type
, NULL
, str
);
1268 pr_info(DRVNAME
": Deleting %s\n", str
);
1273 static int fbtft_device_spi_device_register(struct spi_board_info
*spi
)
1275 struct spi_master
*master
;
1277 master
= spi_busnum_to_master(spi
->bus_num
);
1279 pr_err(DRVNAME
": spi_busnum_to_master(%d) returned NULL\n",
1283 /* make sure it's available */
1284 fbtft_device_spi_delete(master
, spi
->chip_select
);
1285 spi_device
= spi_new_device(master
, spi
);
1286 put_device(&master
->dev
);
1288 pr_err(DRVNAME
": spi_new_device() returned NULL\n");
1294 static int fbtft_device_spi_device_register(struct spi_board_info
*spi
)
1296 return spi_register_board_info(spi
, 1);
1300 static int __init
fbtft_device_init(void)
1302 struct spi_board_info
*spi
= NULL
;
1303 struct fbtft_platform_data
*pdata
;
1304 const struct fbtft_gpio
*gpio
= NULL
;
1305 char *p_gpio
, *p_name
, *p_num
;
1311 pr_debug("\n\n"DRVNAME
": init\n");
1315 pr_err(DRVNAME
": missing module parameter: 'name'\n");
1322 if (init_num
> FBTFT_MAX_INIT_SEQUENCE
) {
1324 ": init parameter: exceeded max array size: %d\n",
1325 FBTFT_MAX_INIT_SEQUENCE
);
1329 /* parse module parameter: gpios */
1330 while ((p_gpio
= strsep(&gpios
, ","))) {
1331 if (strchr(p_gpio
, ':') == NULL
) {
1333 ": error: missing ':' in gpios parameter: %s\n",
1338 p_name
= strsep(&p_num
, ":");
1339 if (p_name
== NULL
|| p_num
== NULL
) {
1341 ": something bad happened parsing gpios parameter: %s\n",
1345 ret
= kstrtol(p_num
, 10, &val
);
1348 ": could not parse number in gpios parameter: %s:%s\n",
1352 strcpy(fbtft_device_param_gpios
[i
].name
, p_name
);
1353 fbtft_device_param_gpios
[i
++].gpio
= (int) val
;
1354 if (i
== MAX_GPIOS
) {
1356 ": gpios parameter: exceeded max array size: %d\n",
1361 if (fbtft_device_param_gpios
[0].name
[0])
1362 gpio
= fbtft_device_param_gpios
;
1365 pr_spi_devices(); /* print list of registered SPI devices */
1368 pr_p_devices(); /* print list of 'fb' platform devices */
1370 pr_debug(DRVNAME
": name='%s', busnum=%d, cs=%d\n", name
, busnum
, cs
);
1372 if (rotate
> 0 && rotate
< 4) {
1373 rotate
= (4 - rotate
) * 90;
1374 pr_warn("argument 'rotate' should be an angle. Values 1-3 is deprecated. Setting it to %d.\n",
1377 if (rotate
!= 0 && rotate
!= 90 && rotate
!= 180 && rotate
!= 270) {
1378 pr_warn("argument 'rotate' illegal value: %d. Setting it to 0.\n",
1383 /* name=list lists all supported displays */
1384 if (strncmp(name
, "list", 32) == 0) {
1385 pr_info(DRVNAME
": Supported displays:\n");
1387 for (i
= 0; i
< ARRAY_SIZE(displays
); i
++)
1388 pr_info(DRVNAME
": %s\n", displays
[i
].name
);
1393 i
= ARRAY_SIZE(displays
) - 1;
1394 displays
[i
].name
= name
;
1396 displays
[i
].pdev
->name
= name
;
1397 displays
[i
].spi
= NULL
;
1399 strncpy(displays
[i
].spi
->modalias
, name
, SPI_NAME_SIZE
);
1400 displays
[i
].pdev
= NULL
;
1404 for (i
= 0; i
< ARRAY_SIZE(displays
); i
++) {
1405 if (strncmp(name
, displays
[i
].name
, 32) == 0) {
1406 if (displays
[i
].spi
) {
1407 spi
= displays
[i
].spi
;
1408 spi
->chip_select
= cs
;
1409 spi
->bus_num
= busnum
;
1411 spi
->max_speed_hz
= speed
;
1414 pdata
= (void *)spi
->platform_data
;
1415 } else if (displays
[i
].pdev
) {
1416 p_device
= displays
[i
].pdev
;
1417 pdata
= p_device
->dev
.platform_data
;
1419 pr_err(DRVNAME
": broken displays array\n");
1423 pdata
->rotate
= rotate
;
1429 pdata
->startbyte
= startbyte
;
1431 pdata
->gamma
= gamma
;
1432 pdata
->display
.debug
= debug
;
1436 pdata
->txbuflen
= txbuflen
;
1438 pdata
->display
.init_sequence
= init
;
1440 pdata
->gpios
= gpio
;
1442 pdata
->display
.width
= width
;
1443 pdata
->display
.height
= height
;
1444 pdata
->display
.buswidth
= buswidth
;
1445 pdata
->display
.backlight
= 1;
1448 if (displays
[i
].spi
) {
1449 ret
= fbtft_device_spi_device_register(spi
);
1452 ": failed to register SPI device\n");
1456 ret
= platform_device_register(p_device
);
1459 ": platform_device_register() returned %d\n",
1470 pr_err(DRVNAME
": display not supported: '%s'\n", name
);
1474 if (verbose
&& pdata
&& pdata
->gpios
) {
1475 gpio
= pdata
->gpios
;
1476 pr_info(DRVNAME
": GPIOS used by '%s':\n", name
);
1478 while (verbose
&& gpio
->name
[0]) {
1479 pr_info(DRVNAME
": '%s' = GPIO%d\n",
1480 gpio
->name
, gpio
->gpio
);
1485 pr_info(DRVNAME
": (none)\n");
1488 if (spi_device
&& (verbose
> 1))
1490 if (p_device
&& (verbose
> 1))
1496 static void __exit
fbtft_device_exit(void)
1498 pr_debug(DRVNAME
" - exit\n");
1501 device_del(&spi_device
->dev
);
1506 platform_device_unregister(p_device
);
1510 arch_initcall(fbtft_device_init
);
1511 module_exit(fbtft_device_exit
);
1513 MODULE_DESCRIPTION("Add a FBTFT device.");
1514 MODULE_AUTHOR("Noralf Tronnes");
1515 MODULE_LICENSE("GPL");