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). " \
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,
140 -1, 0x0001, 0x0100, -1, 0x0002, 0x0700,
141 -1, 0x0003, 0x1030, -1, 0x0004, 0x0000,
142 -1, 0x0008, 0x0207, -1, 0x0009, 0x0000,
143 -1, 0x000a, 0x0000, -1, 0x000c, 0x0001,
144 -1, 0x000d, 0x0000, -1, 0x000f, 0x0000,
145 -1, 0x0010, 0x0000, -1, 0x0011, 0x0007,
146 -1, 0x0012, 0x0000, -1, 0x0013, 0x0000,
147 -2, 50, -1, 0x0010, 0x1590, -1, 0x0011,
148 0x0227, -2, 50, -1, 0x0012, 0x009c, -2, 50,
149 -1, 0x0013, 0x1900, -1, 0x0029, 0x0023,
150 -1, 0x002b, 0x000e, -2, 50,
151 -1, 0x0020, 0x0000, -1, 0x0021, 0x0000,
152 -2, 50, -1, 0x0050, 0x0000,
153 -1, 0x0051, 0x00ef, -1, 0x0052, 0x0000,
154 -1, 0x0053, 0x013f, -1, 0x0060, 0xa700,
155 -1, 0x0061, 0x0001, -1, 0x006a, 0x0000,
156 -1, 0x0080, 0x0000, -1, 0x0081, 0x0000,
157 -1, 0x0082, 0x0000, -1, 0x0083, 0x0000,
158 -1, 0x0084, 0x0000, -1, 0x0085, 0x0000,
159 -1, 0x0090, 0x0010, -1, 0x0092, 0x0000,
160 -1, 0x0093, 0x0003, -1, 0x0095, 0x0110,
161 -1, 0x0097, 0x0000, -1, 0x0098, 0x0000,
162 -1, 0x0007, 0x0133, -1, 0x0020, 0x0000,
163 -1, 0x0021, 0x0000, -2, 100, -3 };
165 #define HY28B_GAMMA \
166 "04 1F 4 7 7 0 7 7 6 0\n" \
167 "0F 00 1 7 4 0 0 0 6 7"
169 static int pitft_init_sequence[] = {
170 -1, 0x01, -2, 5, -1, 0x28, -1, 0xEF,
171 0x03, 0x80, 0x02, -1, 0xCF, 0x00, 0xC1, 0x30,
172 -1, 0xED, 0x64, 0x03, 0x12, 0x81,
173 -1, 0xE8, 0x85, 0x00, 0x78,
174 -1, 0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02,
175 -1, 0xF7, 0x20, -1, 0xEA, 0x00, 0x00,
176 -1, 0xC0, 0x23, -1, 0xC1, 0x10, -1, 0xC5,
177 0x3e, 0x28, -1, 0xC7, 0x86, -1, 0x3A, 0x55,
178 -1, 0xB1, 0x00, 0x18, -1, 0xB6, 0x08, 0x82,
179 0x27, -1, 0xF2, 0x00, -1, 0x26, 0x01,
180 -1, 0xE0, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08,
181 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03,
182 0x0E, 0x09, 0x00, -1, 0xE1, 0x00, 0x0E, 0x14,
183 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48,
184 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, -1,
185 0x11, -2, 100, -1, 0x29, -2, 20, -3 };
187 static int waveshare32b_init_sequence[] = {
188 -1, 0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02,
189 -1, 0xCF, 0x00, 0xC1, 0x30,
190 -1, 0xE8, 0x85, 0x00, 0x78, -1, 0xEA, 0x00,
191 0x00, -1, 0xED, 0x64, 0x03, 0x12, 0x81,
192 -1, 0xF7, 0x20, -1, 0xC0, 0x23, -1, 0xC1,
193 0x10, -1, 0xC5, 0x3e, 0x28, -1, 0xC7, 0x86,
194 -1, 0x36, 0x28, -1, 0x3A, 0x55, -1, 0xB1, 0x00,
195 0x18, -1, 0xB6, 0x08, 0x82, 0x27,
196 -1, 0xF2, 0x00, -1, 0x26, 0x01,
197 -1, 0xE0, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E,
198 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
199 -1, 0xE1, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31,
200 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
201 -1, 0x11, -2, 120, -1, 0x29, -1, 0x2c, -3 };
203 /* Supported displays in alphabetical order */
204 static struct fbtft_device_display displays[] = {
206 .name = "adafruit18",
207 .spi = &(struct spi_board_info) {
208 .modalias = "fb_st7735r",
209 .max_speed_hz = 32000000,
211 .platform_data = &(struct fbtft_platform_data) {
216 .gpios = (const struct fbtft_gpio []) {
222 .gamma = ADAFRUIT18_GAMMA,
226 .name = "adafruit18_green",
227 .spi = &(struct spi_board_info) {
228 .modalias = "fb_st7735r",
229 .max_speed_hz = 4000000,
231 .platform_data = &(struct fbtft_platform_data) {
235 .fbtftops.set_addr_win = \
236 adafruit18_green_tab_set_addr_win,
239 .gpios = (const struct fbtft_gpio []) {
245 .gamma = ADAFRUIT18_GAMMA,
249 .name = "adafruit22",
250 .spi = &(struct spi_board_info) {
251 .modalias = "fb_hx8340bn",
252 .max_speed_hz = 32000000,
254 .platform_data = &(struct fbtft_platform_data) {
260 .gpios = (const struct fbtft_gpio []) {
268 .name = "adafruit22a",
269 .spi = &(struct spi_board_info) {
270 .modalias = "fb_ili9340",
271 .max_speed_hz = 32000000,
273 .platform_data = &(struct fbtft_platform_data) {
279 .gpios = (const struct fbtft_gpio []) {
288 .name = "adafruit28",
289 .spi = &(struct spi_board_info) {
290 .modalias = "fb_ili9341",
291 .max_speed_hz = 32000000,
293 .platform_data = &(struct fbtft_platform_data) {
299 .gpios = (const struct fbtft_gpio []) {
308 .name = "adafruit13m",
309 .spi = &(struct spi_board_info) {
310 .modalias = "fb_ssd1306",
311 .max_speed_hz = 16000000,
313 .platform_data = &(struct fbtft_platform_data) {
317 .gpios = (const struct fbtft_gpio []) {
325 .name = "agm1264k-fl",
326 .pdev = &(struct platform_device) {
327 .name = "fb_agm1264k-fl",
330 .release = fbtft_device_pdev_release,
331 .platform_data = &(struct fbtft_platform_data) {
334 .backlight = FBTFT_ONBOARD_BACKLIGHT,
336 .gpios = (const struct fbtft_gpio []) {
344 .spi = &(struct spi_board_info) {
345 .modalias = "fb_uc1701",
346 .max_speed_hz = 8000000,
348 .platform_data = &(struct fbtft_platform_data) {
353 .gpios = (const struct fbtft_gpio []) {
361 .name = "er_tftm050_2",
362 .spi = &(struct spi_board_info) {
363 .modalias = "fb_ra8875",
364 .max_speed_hz = 5000000,
366 .platform_data = &(struct fbtft_platform_data) {
374 .gpios = (const struct fbtft_gpio []) {
382 .name = "er_tftm070_5",
383 .spi = &(struct spi_board_info) {
384 .modalias = "fb_ra8875",
385 .max_speed_hz = 5000000,
387 .platform_data = &(struct fbtft_platform_data) {
395 .gpios = (const struct fbtft_gpio []) {
404 .spi = &(struct spi_board_info) {
405 .modalias = "flexfb",
406 .max_speed_hz = 32000000,
408 .platform_data = &(struct fbtft_platform_data) {
409 .gpios = (const struct fbtft_gpio []) {
418 .pdev = &(struct platform_device) {
422 .release = fbtft_device_pdev_release,
423 .platform_data = &(struct fbtft_platform_data) {
424 .gpios = (const struct fbtft_gpio []) {
444 .name = "freetronicsoled128",
445 .spi = &(struct spi_board_info) {
446 .modalias = "fb_ssd1351",
447 .max_speed_hz = 20000000,
449 .platform_data = &(struct fbtft_platform_data) {
452 .backlight = FBTFT_ONBOARD_BACKLIGHT,
455 .gpios = (const struct fbtft_gpio []) {
464 .spi = &(struct spi_board_info) {
465 .modalias = "fb_hx8353d",
466 .max_speed_hz = 16000000,
468 .platform_data = &(struct fbtft_platform_data) {
473 .gpios = (const struct fbtft_gpio []) {
483 .spi = &(struct spi_board_info) {
484 .modalias = "fb_ili9320",
485 .max_speed_hz = 32000000,
487 .platform_data = &(struct fbtft_platform_data) {
494 .gpios = (const struct fbtft_gpio []) {
503 .spi = &(struct spi_board_info) {
504 .modalias = "fb_ili9325",
505 .max_speed_hz = 48000000,
507 .platform_data = &(struct fbtft_platform_data) {
511 .init_sequence = hy28b_init_sequence,
516 .gpios = (const struct fbtft_gpio []) {
521 .gamma = HY28B_GAMMA,
526 .spi = &(struct spi_board_info) {
527 .modalias = "fb_ili9481",
528 .max_speed_hz = 32000000,
530 .platform_data = &(struct fbtft_platform_data) {
537 .gpios = (const struct fbtft_gpio []) {
547 .pdev = &(struct platform_device) {
548 .name = "fb_s6d1121",
551 .release = fbtft_device_pdev_release,
552 .platform_data = &(struct fbtft_platform_data) {
558 .gpios = (const struct fbtft_gpio []) {
559 /* Wiring for LCD adapter kit */
561 { "dc", 0 }, /* rev 2: 2 */
562 { "wr", 1 }, /* rev 2: 3 */
566 { "db02", 21 }, /* rev 2: 27 */
579 .pdev = &(struct platform_device) {
580 .name = "fb_ili9325",
583 .release = fbtft_device_pdev_release,
584 .platform_data = &(struct fbtft_platform_data) {
590 .gpios = (const struct fbtft_gpio []) {
597 .name = "itdb28_spi",
598 .spi = &(struct spi_board_info) {
599 .modalias = "fb_ili9325",
600 .max_speed_hz = 32000000,
602 .platform_data = &(struct fbtft_platform_data) {
608 .gpios = (const struct fbtft_gpio []) {
616 .name = "mi0283qt-2",
617 .spi = &(struct spi_board_info) {
618 .modalias = "fb_hx8347d",
619 .max_speed_hz = 32000000,
621 .platform_data = &(struct fbtft_platform_data) {
628 .gpios = (const struct fbtft_gpio []) {
637 .name = "mi0283qt-9a",
638 .spi = &(struct spi_board_info) {
639 .modalias = "fb_ili9341",
640 .max_speed_hz = 32000000,
642 .platform_data = &(struct fbtft_platform_data) {
648 .gpios = (const struct fbtft_gpio []) {
656 .name = "mi0283qt-v2",
657 .spi = &(struct spi_board_info) {
658 .modalias = "fb_watterott",
659 .max_speed_hz = 4000000,
661 .platform_data = &(struct fbtft_platform_data) {
662 .gpios = (const struct fbtft_gpio []) {
670 .spi = &(struct spi_board_info) {
671 .modalias = "fb_pcd8544",
672 .max_speed_hz = 400000,
674 .platform_data = &(struct fbtft_platform_data) {
678 .gpios = (const struct fbtft_gpio []) {
687 .name = "nokia3310a",
688 .spi = &(struct spi_board_info) {
689 .modalias = "fb_tls8204",
690 .max_speed_hz = 1000000,
692 .platform_data = &(struct fbtft_platform_data) {
696 .gpios = (const struct fbtft_gpio []) {
706 .spi = &(struct spi_board_info) {
707 .modalias = "fb_ili9163",
708 .max_speed_hz = 12000000,
710 .platform_data = &(struct fbtft_platform_data) {
716 .gpios = (const struct fbtft_gpio []) {
724 .spi = &(struct spi_board_info) {
725 .modalias = "fb_ili9486",
726 .max_speed_hz = 32000000,
728 .platform_data = &(struct fbtft_platform_data) {
735 .gpios = (const struct fbtft_gpio []) {
745 .spi = &(struct spi_board_info) {
746 .modalias = "fb_ili9340",
747 .max_speed_hz = 32000000,
750 .platform_data = &(struct fbtft_platform_data) {
754 .init_sequence = pitft_init_sequence,
757 .gpios = (const struct fbtft_gpio []) {
765 .spi = &(struct spi_board_info) {
766 .modalias = "fb_ssd1351",
767 .max_speed_hz = 20000000,
769 .platform_data = &(struct fbtft_platform_data) {
774 .gpios = (const struct fbtft_gpio []) {
779 .gamma = "0 2 2 2 2 2 2 2 " \
790 .name = "rpi-display",
791 .spi = &(struct spi_board_info) {
792 .modalias = "fb_ili9341",
793 .max_speed_hz = 32000000,
795 .platform_data = &(struct fbtft_platform_data) {
801 .gpios = (const struct fbtft_gpio []) {
811 .spi = &(struct spi_board_info) {
812 .modalias = "fb_s6d02a1",
813 .max_speed_hz = 32000000,
815 .platform_data = &(struct fbtft_platform_data) {
821 .gpios = (const struct fbtft_gpio []) {
830 .name = "sainsmart18",
831 .spi = &(struct spi_board_info) {
832 .modalias = "fb_st7735r",
833 .max_speed_hz = 32000000,
835 .platform_data = &(struct fbtft_platform_data) {
839 .gpios = (const struct fbtft_gpio []) {
847 .name = "sainsmart32",
848 .pdev = &(struct platform_device) {
849 .name = "fb_ssd1289",
852 .release = fbtft_device_pdev_release,
853 .platform_data = &(struct fbtft_platform_data) {
856 .txbuflen = -2, /* disable buffer */
858 .fbtftops.write = write_gpio16_wr_slow,
861 .gpios = (const struct fbtft_gpio []) {
868 .name = "sainsmart32_fast",
869 .pdev = &(struct platform_device) {
870 .name = "fb_ssd1289",
873 .release = fbtft_device_pdev_release,
874 .platform_data = &(struct fbtft_platform_data) {
877 .txbuflen = -2, /* disable buffer */
881 .gpios = (const struct fbtft_gpio []) {
888 .name = "sainsmart32_latched",
889 .pdev = &(struct platform_device) {
890 .name = "fb_ssd1289",
893 .release = fbtft_device_pdev_release,
894 .platform_data = &(struct fbtft_platform_data) {
897 .txbuflen = -2, /* disable buffer */
900 fbtft_write_gpio16_wr_latched,
903 .gpios = (const struct fbtft_gpio []) {
910 .name = "sainsmart32_spi",
911 .spi = &(struct spi_board_info) {
912 .modalias = "fb_ssd1289",
913 .max_speed_hz = 16000000,
915 .platform_data = &(struct fbtft_platform_data) {
921 .gpios = (const struct fbtft_gpio []) {
930 .spi = &(struct spi_board_info) {
931 .modalias = "spidev",
932 .max_speed_hz = 500000,
936 .platform_data = &(struct fbtft_platform_data) {
937 .gpios = (const struct fbtft_gpio []) {
944 .spi = &(struct spi_board_info) {
945 .modalias = "fb_ssd1331",
946 .max_speed_hz = 20000000,
948 .platform_data = &(struct fbtft_platform_data) {
952 .gpios = (const struct fbtft_gpio []) {
961 .spi = &(struct spi_board_info) {
962 .modalias = "fb_tinylcd",
963 .max_speed_hz = 32000000,
965 .platform_data = &(struct fbtft_platform_data) {
971 .gpios = (const struct fbtft_gpio []) {
980 .name = "tm022hdh26",
981 .spi = &(struct spi_board_info) {
982 .modalias = "fb_ili9341",
983 .max_speed_hz = 32000000,
985 .platform_data = &(struct fbtft_platform_data) {
991 .gpios = (const struct fbtft_gpio []) {
1000 .name = "tontec35_9481", /* boards before 02 July 2014 */
1001 .spi = &(struct spi_board_info) {
1002 .modalias = "fb_ili9481",
1003 .max_speed_hz = 128000000,
1005 .platform_data = &(struct fbtft_platform_data) {
1011 .gpios = (const struct fbtft_gpio []) {
1020 .name = "tontec35_9486", /* boards after 02 July 2014 */
1021 .spi = &(struct spi_board_info) {
1022 .modalias = "fb_ili9486",
1023 .max_speed_hz = 128000000,
1025 .platform_data = &(struct fbtft_platform_data) {
1031 .gpios = (const struct fbtft_gpio []) {
1040 .name = "upd161704",
1041 .spi = &(struct spi_board_info) {
1042 .modalias = "fb_upd161704",
1043 .max_speed_hz = 32000000,
1045 .platform_data = &(struct fbtft_platform_data) {
1049 .gpios = (const struct fbtft_gpio []) {
1057 .name = "waveshare32b",
1058 .spi = &(struct spi_board_info) {
1059 .modalias = "fb_ili9340",
1060 .max_speed_hz = 48000000,
1062 .platform_data = &(struct fbtft_platform_data) {
1066 .init_sequence = waveshare32b_init_sequence,
1069 .gpios = (const struct fbtft_gpio []) {
1077 .name = "waveshare22",
1078 .spi = &(struct spi_board_info) {
1079 .modalias = "fb_bd663474",
1080 .max_speed_hz = 32000000,
1082 .platform_data = &(struct fbtft_platform_data) {
1086 .gpios = (const struct fbtft_gpio []) {
1094 /* This should be the last item.
1095 Used with the custom argument */
1097 .spi = &(struct spi_board_info) {
1101 .platform_data = &(struct fbtft_platform_data) {
1102 .gpios = (const struct fbtft_gpio []) {
1107 .pdev = &(struct platform_device) {
1111 .release = fbtft_device_pdev_release,
1112 .platform_data = &(struct fbtft_platform_data) {
1113 .gpios = (const struct fbtft_gpio []) {
1122 static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len)
1126 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1127 static u16 prev_data;
1130 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
1131 "%s(len=%d): ", __func__, len);
1134 data = *(u16 *) buf;
1136 /* Start writing by pulling down /WR */
1137 gpio_set_value(par->gpio.wr, 0);
1140 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1141 if (data == prev_data) {
1142 gpio_set_value(par->gpio.wr, 0); /* used as delay */
1144 for (i = 0; i < 16; i++) {
1145 if ((data & 1) != (prev_data & 1))
1146 gpio_set_value(par->gpio.db[i],
1153 for (i = 0; i < 16; i++) {
1154 gpio_set_value(par->gpio.db[i], data & 1);
1160 gpio_set_value(par->gpio.wr, 1);
1162 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1163 prev_data = *(u16 *) buf;
1172 static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
1173 int xs, int ys, int xe, int ye)
1175 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
1176 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
1177 write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
1178 write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
1179 write_reg(par, 0x2C);
1182 /* used if gpios parameter is present */
1183 static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS+1] = { };
1185 static void fbtft_device_pdev_release(struct device *dev)
1187 /* Needed to silence this message:
1188 Device 'xxx' does not have a release() function, it is broken and must be fixed
1192 static int spi_device_found(struct device *dev, void *data)
1194 struct spi_device *spi = container_of(dev, struct spi_device, dev);
1196 pr_info(DRVNAME": %s %s %dkHz %d bits mode=0x%02X\n",
1197 spi->modalias, dev_name(dev), spi->max_speed_hz/1000,
1198 spi->bits_per_word, spi->mode);
1203 static void pr_spi_devices(void)
1205 pr_info(DRVNAME": SPI devices registered:\n");
1206 bus_for_each_dev(&spi_bus_type, NULL, NULL, spi_device_found);
1209 static int p_device_found(struct device *dev, void *data)
1211 struct platform_device
1212 *pdev = container_of(dev, struct platform_device, dev);
1214 if (strstr(pdev->name, "fb"))
1215 pr_info(DRVNAME": %s id=%d pdata? %s\n",
1216 pdev->name, pdev->id,
1217 pdev->dev.platform_data ? "yes" : "no");
1222 static void pr_p_devices(void)
1224 pr_info(DRVNAME": 'fb' Platform devices registered:\n");
1225 bus_for_each_dev(&platform_bus_type, NULL, NULL, p_device_found);
1229 static void fbtft_device_spi_delete(struct spi_master *master, unsigned cs)
1234 snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), cs);
1236 dev = bus_find_device_by_name(&spi_bus_type, NULL, str);
1239 pr_info(DRVNAME": Deleting %s\n", str);
1244 static int fbtft_device_spi_device_register(struct spi_board_info *spi)
1246 struct spi_master *master;
1248 master = spi_busnum_to_master(spi->bus_num);
1250 pr_err(DRVNAME ": spi_busnum_to_master(%d) returned NULL\n",
1254 /* make sure it's available */
1255 fbtft_device_spi_delete(master, spi->chip_select);
1256 spi_device = spi_new_device(master, spi);
1257 put_device(&master->dev);
1259 pr_err(DRVNAME ": spi_new_device() returned NULL\n");
1265 static int fbtft_device_spi_device_register(struct spi_board_info *spi)
1267 return spi_register_board_info(spi, 1);
1271 static int __init fbtft_device_init(void)
1273 struct spi_board_info *spi = NULL;
1274 struct fbtft_platform_data *pdata;
1275 const struct fbtft_gpio *gpio = NULL;
1276 char *p_gpio, *p_name, *p_num;
1282 pr_debug("\n\n"DRVNAME": init\n");
1286 pr_err(DRVNAME": missing module parameter: 'name'\n");
1293 if (init_num > FBTFT_MAX_INIT_SEQUENCE) {
1295 ": init parameter: exceeded max array size: %d\n",
1296 FBTFT_MAX_INIT_SEQUENCE);
1300 /* parse module parameter: gpios */
1301 while ((p_gpio = strsep(&gpios, ","))) {
1302 if (strchr(p_gpio, ':') == NULL) {
1304 ": error: missing ':' in gpios parameter: %s\n",
1309 p_name = strsep(&p_num, ":");
1310 if (p_name == NULL || p_num == NULL) {
1312 ": something bad happened parsing gpios parameter: %s\n",
1316 ret = kstrtol(p_num, 10, &val);
1319 ": could not parse number in gpios parameter: %s:%s\n",
1323 strcpy(fbtft_device_param_gpios[i].name, p_name);
1324 fbtft_device_param_gpios[i++].gpio = (int) val;
1325 if (i == MAX_GPIOS) {
1327 ": gpios parameter: exceeded max array size: %d\n",
1332 if (fbtft_device_param_gpios[0].name[0])
1333 gpio = fbtft_device_param_gpios;
1336 pr_spi_devices(); /* print list of registered SPI devices */
1339 pr_p_devices(); /* print list of 'fb' platform devices */
1341 pr_debug(DRVNAME": name='%s', busnum=%d, cs=%d\n", name, busnum, cs);
1343 if (rotate > 0 && rotate < 4) {
1344 rotate = (4 - rotate) * 90;
1345 pr_warn("argument 'rotate' should be an angle. Values 1-3 is deprecated. Setting it to %d.\n",
1348 if (rotate != 0 && rotate != 90 && rotate != 180 && rotate != 270) {
1349 pr_warn("argument 'rotate' illegal value: %d. Setting it to 0.\n",
1354 /* name=list lists all supported displays */
1355 if (strncmp(name, "list", 32) == 0) {
1356 pr_info(DRVNAME": Supported displays:\n");
1358 for (i = 0; i < ARRAY_SIZE(displays); i++)
1359 pr_info(DRVNAME": %s\n", displays[i].name);
1364 i = ARRAY_SIZE(displays) - 1;
1365 displays[i].name = name;
1367 displays[i].pdev->name = name;
1368 displays[i].spi = NULL;
1370 strncpy(displays[i].spi->modalias, name, SPI_NAME_SIZE);
1371 displays[i].pdev = NULL;
1375 for (i = 0; i < ARRAY_SIZE(displays); i++) {
1376 if (strncmp(name, displays[i].name, 32) == 0) {
1377 if (displays[i].spi) {
1378 spi = displays[i].spi;
1379 spi->chip_select = cs;
1380 spi->bus_num = busnum;
1382 spi->max_speed_hz = speed;
1385 pdata = (void *)spi->platform_data;
1386 } else if (displays[i].pdev) {
1387 p_device = displays[i].pdev;
1388 pdata = p_device->dev.platform_data;
1390 pr_err(DRVNAME": broken displays array\n");
1394 pdata->rotate = rotate;
1400 pdata->startbyte = startbyte;
1402 pdata->gamma = gamma;
1403 pdata->display.debug = debug;
1407 pdata->txbuflen = txbuflen;
1409 pdata->display.init_sequence = init;
1411 pdata->gpios = gpio;
1413 pdata->display.width = width;
1414 pdata->display.height = height;
1415 pdata->display.buswidth = buswidth;
1416 pdata->display.backlight = 1;
1419 if (displays[i].spi) {
1420 ret = fbtft_device_spi_device_register(spi);
1423 ": failed to register SPI device\n");
1429 ret = platform_device_register(p_device);
1432 ": platform_device_register() returned %d\n",
1443 pr_err(DRVNAME": display not supported: '%s'\n", name);
1447 if (verbose && pdata && pdata->gpios) {
1448 gpio = pdata->gpios;
1449 pr_info(DRVNAME": GPIOS used by '%s':\n", name);
1451 while (verbose && gpio->name[0]) {
1452 pr_info(DRVNAME": '%s' = GPIO%d\n",
1453 gpio->name, gpio->gpio);
1458 pr_info(DRVNAME": (none)\n");
1461 if (spi_device && (verbose > 1))
1463 if (p_device && (verbose > 1))
1469 static void __exit fbtft_device_exit(void)
1471 pr_debug(DRVNAME" - exit\n");
1474 device_del(&spi_device->dev);
1479 platform_device_unregister(p_device);
1483 arch_initcall(fbtft_device_init);
1484 module_exit(fbtft_device_exit);
1486 MODULE_DESCRIPTION("Add a FBTFT device.");
1487 MODULE_AUTHOR("Noralf Tronnes");
1488 MODULE_LICENSE("GPL");