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.
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>
28 static struct spi_device
*spi_device
;
29 static struct platform_device
*p_device
;
32 module_param(name
, charp
, 0);
33 MODULE_PARM_DESC(name
, "Devicename (required). name=list => list all supported devices.");
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");
40 static unsigned busnum
;
41 module_param(busnum
, uint
, 0);
42 MODULE_PARM_DESC(busnum
, "SPI bus number (default=0)");
45 module_param(cs
, uint
, 0);
46 MODULE_PARM_DESC(cs
, "SPI chip select (default=0)");
48 static unsigned speed
;
49 module_param(speed
, uint
, 0);
50 MODULE_PARM_DESC(speed
, "SPI speed (override device default)");
53 module_param(mode
, int, 0);
54 MODULE_PARM_DESC(mode
, "SPI mode (override device default)");
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)");
62 module_param(fps
, uint
, 0);
63 MODULE_PARM_DESC(fps
, "Frames per second (override driver default)");
66 module_param(gamma
, charp
, 0);
67 MODULE_PARM_DESC(gamma
,
68 "String representation of Gamma Curve(s). Driver specific.");
71 module_param(txbuflen
, int, 0);
72 MODULE_PARM_DESC(txbuflen
, "txbuflen (override driver default)");
75 module_param(bgr
, int, 0);
77 "BGR bit (supported by some drivers).");
79 static unsigned startbyte
;
80 module_param(startbyte
, uint
, 0);
81 MODULE_PARM_DESC(startbyte
, "Sets the Start byte used by some SPI displays.");
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");
87 static unsigned width
;
88 module_param(width
, uint
, 0);
89 MODULE_PARM_DESC(width
, "Display width, used with the custom argument");
91 static unsigned height
;
92 module_param(height
, uint
, 0);
93 MODULE_PARM_DESC(height
, "Display height, used with the custom argument");
95 static unsigned buswidth
= 8;
96 module_param(buswidth
, uint
, 0);
97 MODULE_PARM_DESC(buswidth
, "Display bus width, used with the custom argument");
99 static int init
[FBTFT_MAX_INIT_SEQUENCE
];
101 module_param_array(init
, int, &init_num
, 0);
102 MODULE_PARM_DESC(init
, "Init sequence, used with the custom argument");
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)");
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)");
114 struct fbtft_device_display
{
116 struct spi_board_info
*spi
;
117 struct platform_device
*pdev
;
120 static void fbtft_device_pdev_release(struct device
*dev
);
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
);
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"
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"
134 static int cberry28_init_sequence
[] = {
135 /* turn off sleep mode */
136 -1, MIPI_DCS_EXIT_SLEEP_MODE
,
139 /* set pixel format to RGB-565 */
140 -1, MIPI_DCS_SET_PIXEL_FORMAT
, MIPI_DCS_PIXEL_FMT_16BIT
,
142 -1, 0xB2, 0x0C, 0x0C, 0x00, 0x33, 0x33,
151 * VDV and VRH register values come from command write
154 -1, 0xC2, 0x01, 0xFF,
157 * VAP = 4.7V + (VCOM + VCOM offset + 0.5 * VDV)
158 * VAN = -4.7V + (VCOM + VCOM offset + 0.5 * VDV)
168 /* VCOM offset = 0V */
176 -1, 0xD0, 0xA4, 0xA1,
178 -1, MIPI_DCS_SET_DISPLAY_ON
,
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 };
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"
214 static int pitft_init_sequence
[] = {
215 -1, MIPI_DCS_SOFT_RESET
,
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,
224 -1, 0xEA, 0x00, 0x00,
227 -1, 0xC5, 0x3E, 0x28,
229 -1, MIPI_DCS_SET_PIXEL_FORMAT
, 0x55,
230 -1, 0xB1, 0x00, 0x18,
231 -1, 0xB6, 0x08, 0x82, 0x27,
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
,
240 -1, MIPI_DCS_SET_DISPLAY_ON
,
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,
254 -1, 0xC5, 0x3E, 0x28,
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,
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
,
268 -1, MIPI_DCS_SET_DISPLAY_ON
,
269 -1, MIPI_DCS_WRITE_MEMORY_START
,
273 /* Supported displays in alphabetical order */
274 static struct fbtft_device_display displays
[] = {
276 .name
= "adafruit18",
277 .spi
= &(struct spi_board_info
) {
278 .modalias
= "fb_st7735r",
279 .max_speed_hz
= 32000000,
281 .platform_data
= &(struct fbtft_platform_data
) {
286 .gpios
= (const struct fbtft_gpio
[]) {
292 .gamma
= ADAFRUIT18_GAMMA
,
296 .name
= "adafruit18_green",
297 .spi
= &(struct spi_board_info
) {
298 .modalias
= "fb_st7735r",
299 .max_speed_hz
= 4000000,
301 .platform_data
= &(struct fbtft_platform_data
) {
305 .fbtftops
.set_addr_win
=
306 adafruit18_green_tab_set_addr_win
,
309 .gpios
= (const struct fbtft_gpio
[]) {
315 .gamma
= ADAFRUIT18_GAMMA
,
319 .name
= "adafruit22",
320 .spi
= &(struct spi_board_info
) {
321 .modalias
= "fb_hx8340bn",
322 .max_speed_hz
= 32000000,
324 .platform_data
= &(struct fbtft_platform_data
) {
330 .gpios
= (const struct fbtft_gpio
[]) {
338 .name
= "adafruit22a",
339 .spi
= &(struct spi_board_info
) {
340 .modalias
= "fb_ili9340",
341 .max_speed_hz
= 32000000,
343 .platform_data
= &(struct fbtft_platform_data
) {
349 .gpios
= (const struct fbtft_gpio
[]) {
358 .name
= "adafruit28",
359 .spi
= &(struct spi_board_info
) {
360 .modalias
= "fb_ili9341",
361 .max_speed_hz
= 32000000,
363 .platform_data
= &(struct fbtft_platform_data
) {
369 .gpios
= (const struct fbtft_gpio
[]) {
378 .name
= "adafruit13m",
379 .spi
= &(struct spi_board_info
) {
380 .modalias
= "fb_ssd1306",
381 .max_speed_hz
= 16000000,
383 .platform_data
= &(struct fbtft_platform_data
) {
387 .gpios
= (const struct fbtft_gpio
[]) {
395 .name
= "admatec_c-berry28",
396 .spi
= &(struct spi_board_info
) {
397 .modalias
= "fb_st7789v",
398 .max_speed_hz
= 48000000,
400 .platform_data
= &(struct fbtft_platform_data
) {
404 .init_sequence
= cberry28_init_sequence
,
406 .gpios
= (const struct fbtft_gpio
[]) {
412 .gamma
= CBERRY28_GAMMA
,
416 .name
= "agm1264k-fl",
417 .pdev
= &(struct platform_device
) {
418 .name
= "fb_agm1264k-fl",
421 .release
= fbtft_device_pdev_release
,
422 .platform_data
= &(struct fbtft_platform_data
) {
425 .backlight
= FBTFT_ONBOARD_BACKLIGHT
,
427 .gpios
= (const struct fbtft_gpio
[]) {
435 .spi
= &(struct spi_board_info
) {
436 .modalias
= "fb_uc1701",
437 .max_speed_hz
= 8000000,
439 .platform_data
= &(struct fbtft_platform_data
) {
444 .gpios
= (const struct fbtft_gpio
[]) {
452 .name
= "er_tftm050_2",
453 .spi
= &(struct spi_board_info
) {
454 .modalias
= "fb_ra8875",
455 .max_speed_hz
= 5000000,
457 .platform_data
= &(struct fbtft_platform_data
) {
465 .gpios
= (const struct fbtft_gpio
[]) {
473 .name
= "er_tftm070_5",
474 .spi
= &(struct spi_board_info
) {
475 .modalias
= "fb_ra8875",
476 .max_speed_hz
= 5000000,
478 .platform_data
= &(struct fbtft_platform_data
) {
486 .gpios
= (const struct fbtft_gpio
[]) {
495 .spi
= &(struct spi_board_info
) {
496 .modalias
= "fb_uc1611",
497 .max_speed_hz
= 32000000,
499 .platform_data
= &(struct fbtft_platform_data
) {
503 .gpios
= (const struct fbtft_gpio
[]) {
510 .name
= "ew24ha0_9bit",
511 .spi
= &(struct spi_board_info
) {
512 .modalias
= "fb_uc1611",
513 .max_speed_hz
= 32000000,
515 .platform_data
= &(struct fbtft_platform_data
) {
519 .gpios
= (const struct fbtft_gpio
[]) {
526 .spi
= &(struct spi_board_info
) {
527 .modalias
= "flexfb",
528 .max_speed_hz
= 32000000,
530 .platform_data
= &(struct fbtft_platform_data
) {
531 .gpios
= (const struct fbtft_gpio
[]) {
540 .pdev
= &(struct platform_device
) {
544 .release
= fbtft_device_pdev_release
,
545 .platform_data
= &(struct fbtft_platform_data
) {
546 .gpios
= (const struct fbtft_gpio
[]) {
566 .name
= "freetronicsoled128",
567 .spi
= &(struct spi_board_info
) {
568 .modalias
= "fb_ssd1351",
569 .max_speed_hz
= 20000000,
571 .platform_data
= &(struct fbtft_platform_data
) {
574 .backlight
= FBTFT_ONBOARD_BACKLIGHT
,
577 .gpios
= (const struct fbtft_gpio
[]) {
586 .spi
= &(struct spi_board_info
) {
587 .modalias
= "fb_hx8353d",
588 .max_speed_hz
= 16000000,
590 .platform_data
= &(struct fbtft_platform_data
) {
595 .gpios
= (const struct fbtft_gpio
[]) {
605 .spi
= &(struct spi_board_info
) {
606 .modalias
= "fb_ili9320",
607 .max_speed_hz
= 32000000,
609 .platform_data
= &(struct fbtft_platform_data
) {
616 .gpios
= (const struct fbtft_gpio
[]) {
625 .spi
= &(struct spi_board_info
) {
626 .modalias
= "fb_ili9325",
627 .max_speed_hz
= 48000000,
629 .platform_data
= &(struct fbtft_platform_data
) {
633 .init_sequence
= hy28b_init_sequence
,
638 .gpios
= (const struct fbtft_gpio
[]) {
643 .gamma
= HY28B_GAMMA
,
648 .spi
= &(struct spi_board_info
) {
649 .modalias
= "fb_ili9481",
650 .max_speed_hz
= 32000000,
652 .platform_data
= &(struct fbtft_platform_data
) {
659 .gpios
= (const struct fbtft_gpio
[]) {
669 .pdev
= &(struct platform_device
) {
670 .name
= "fb_s6d1121",
673 .release
= fbtft_device_pdev_release
,
674 .platform_data
= &(struct fbtft_platform_data
) {
680 .gpios
= (const struct fbtft_gpio
[]) {
681 /* Wiring for LCD adapter kit */
683 { "dc", 0 }, /* rev 2: 2 */
684 { "wr", 1 }, /* rev 2: 3 */
688 { "db02", 21 }, /* rev 2: 27 */
701 .pdev
= &(struct platform_device
) {
702 .name
= "fb_ili9325",
705 .release
= fbtft_device_pdev_release
,
706 .platform_data
= &(struct fbtft_platform_data
) {
712 .gpios
= (const struct fbtft_gpio
[]) {
719 .name
= "itdb28_spi",
720 .spi
= &(struct spi_board_info
) {
721 .modalias
= "fb_ili9325",
722 .max_speed_hz
= 32000000,
724 .platform_data
= &(struct fbtft_platform_data
) {
730 .gpios
= (const struct fbtft_gpio
[]) {
738 .name
= "mi0283qt-2",
739 .spi
= &(struct spi_board_info
) {
740 .modalias
= "fb_hx8347d",
741 .max_speed_hz
= 32000000,
743 .platform_data
= &(struct fbtft_platform_data
) {
750 .gpios
= (const struct fbtft_gpio
[]) {
759 .name
= "mi0283qt-9a",
760 .spi
= &(struct spi_board_info
) {
761 .modalias
= "fb_ili9341",
762 .max_speed_hz
= 32000000,
764 .platform_data
= &(struct fbtft_platform_data
) {
770 .gpios
= (const struct fbtft_gpio
[]) {
778 .name
= "mi0283qt-v2",
779 .spi
= &(struct spi_board_info
) {
780 .modalias
= "fb_watterott",
781 .max_speed_hz
= 4000000,
783 .platform_data
= &(struct fbtft_platform_data
) {
784 .gpios
= (const struct fbtft_gpio
[]) {
792 .spi
= &(struct spi_board_info
) {
793 .modalias
= "fb_pcd8544",
794 .max_speed_hz
= 400000,
796 .platform_data
= &(struct fbtft_platform_data
) {
800 .gpios
= (const struct fbtft_gpio
[]) {
809 .name
= "nokia3310a",
810 .spi
= &(struct spi_board_info
) {
811 .modalias
= "fb_tls8204",
812 .max_speed_hz
= 1000000,
814 .platform_data
= &(struct fbtft_platform_data
) {
818 .gpios
= (const struct fbtft_gpio
[]) {
828 .spi
= &(struct spi_board_info
) {
829 .modalias
= "fb_ili9163",
830 .max_speed_hz
= 12000000,
832 .platform_data
= &(struct fbtft_platform_data
) {
838 .gpios
= (const struct fbtft_gpio
[]) {
846 .spi
= &(struct spi_board_info
) {
847 .modalias
= "fb_ili9486",
848 .max_speed_hz
= 32000000,
850 .platform_data
= &(struct fbtft_platform_data
) {
857 .gpios
= (const struct fbtft_gpio
[]) {
867 .spi
= &(struct spi_board_info
) {
868 .modalias
= "fb_ili9340",
869 .max_speed_hz
= 32000000,
872 .platform_data
= &(struct fbtft_platform_data
) {
876 .init_sequence
= pitft_init_sequence
,
879 .gpios
= (const struct fbtft_gpio
[]) {
887 .spi
= &(struct spi_board_info
) {
888 .modalias
= "fb_ssd1351",
889 .max_speed_hz
= 20000000,
891 .platform_data
= &(struct fbtft_platform_data
) {
896 .gpios
= (const struct fbtft_gpio
[]) {
901 .gamma
= "0 2 2 2 2 2 2 2 "
912 .name
= "rpi-display",
913 .spi
= &(struct spi_board_info
) {
914 .modalias
= "fb_ili9341",
915 .max_speed_hz
= 32000000,
917 .platform_data
= &(struct fbtft_platform_data
) {
923 .gpios
= (const struct fbtft_gpio
[]) {
933 .spi
= &(struct spi_board_info
) {
934 .modalias
= "fb_s6d02a1",
935 .max_speed_hz
= 32000000,
937 .platform_data
= &(struct fbtft_platform_data
) {
943 .gpios
= (const struct fbtft_gpio
[]) {
952 .name
= "sainsmart18",
953 .spi
= &(struct spi_board_info
) {
954 .modalias
= "fb_st7735r",
955 .max_speed_hz
= 32000000,
957 .platform_data
= &(struct fbtft_platform_data
) {
961 .gpios
= (const struct fbtft_gpio
[]) {
969 .name
= "sainsmart32",
970 .pdev
= &(struct platform_device
) {
971 .name
= "fb_ssd1289",
974 .release
= fbtft_device_pdev_release
,
975 .platform_data
= &(struct fbtft_platform_data
) {
978 .txbuflen
= -2, /* disable buffer */
980 .fbtftops
.write
= write_gpio16_wr_slow
,
983 .gpios
= (const struct fbtft_gpio
[]) {
990 .name
= "sainsmart32_fast",
991 .pdev
= &(struct platform_device
) {
992 .name
= "fb_ssd1289",
995 .release
= fbtft_device_pdev_release
,
996 .platform_data
= &(struct fbtft_platform_data
) {
999 .txbuflen
= -2, /* disable buffer */
1003 .gpios
= (const struct fbtft_gpio
[]) {
1010 .name
= "sainsmart32_latched",
1011 .pdev
= &(struct platform_device
) {
1012 .name
= "fb_ssd1289",
1015 .release
= fbtft_device_pdev_release
,
1016 .platform_data
= &(struct fbtft_platform_data
) {
1019 .txbuflen
= -2, /* disable buffer */
1022 fbtft_write_gpio16_wr_latched
,
1025 .gpios
= (const struct fbtft_gpio
[]) {
1032 .name
= "sainsmart32_spi",
1033 .spi
= &(struct spi_board_info
) {
1034 .modalias
= "fb_ssd1289",
1035 .max_speed_hz
= 16000000,
1037 .platform_data
= &(struct fbtft_platform_data
) {
1043 .gpios
= (const struct fbtft_gpio
[]) {
1052 .spi
= &(struct spi_board_info
) {
1053 .modalias
= "spidev",
1054 .max_speed_hz
= 500000,
1058 .platform_data
= &(struct fbtft_platform_data
) {
1059 .gpios
= (const struct fbtft_gpio
[]) {
1066 .spi
= &(struct spi_board_info
) {
1067 .modalias
= "fb_ssd1331",
1068 .max_speed_hz
= 20000000,
1070 .platform_data
= &(struct fbtft_platform_data
) {
1074 .gpios
= (const struct fbtft_gpio
[]) {
1082 .name
= "tinylcd35",
1083 .spi
= &(struct spi_board_info
) {
1084 .modalias
= "fb_tinylcd",
1085 .max_speed_hz
= 32000000,
1087 .platform_data
= &(struct fbtft_platform_data
) {
1093 .gpios
= (const struct fbtft_gpio
[]) {
1102 .name
= "tm022hdh26",
1103 .spi
= &(struct spi_board_info
) {
1104 .modalias
= "fb_ili9341",
1105 .max_speed_hz
= 32000000,
1107 .platform_data
= &(struct fbtft_platform_data
) {
1113 .gpios
= (const struct fbtft_gpio
[]) {
1122 .name
= "tontec35_9481", /* boards before 02 July 2014 */
1123 .spi
= &(struct spi_board_info
) {
1124 .modalias
= "fb_ili9481",
1125 .max_speed_hz
= 128000000,
1127 .platform_data
= &(struct fbtft_platform_data
) {
1133 .gpios
= (const struct fbtft_gpio
[]) {
1142 .name
= "tontec35_9486", /* boards after 02 July 2014 */
1143 .spi
= &(struct spi_board_info
) {
1144 .modalias
= "fb_ili9486",
1145 .max_speed_hz
= 128000000,
1147 .platform_data
= &(struct fbtft_platform_data
) {
1153 .gpios
= (const struct fbtft_gpio
[]) {
1162 .name
= "upd161704",
1163 .spi
= &(struct spi_board_info
) {
1164 .modalias
= "fb_upd161704",
1165 .max_speed_hz
= 32000000,
1167 .platform_data
= &(struct fbtft_platform_data
) {
1171 .gpios
= (const struct fbtft_gpio
[]) {
1179 .name
= "waveshare32b",
1180 .spi
= &(struct spi_board_info
) {
1181 .modalias
= "fb_ili9340",
1182 .max_speed_hz
= 48000000,
1184 .platform_data
= &(struct fbtft_platform_data
) {
1189 waveshare32b_init_sequence
,
1192 .gpios
= (const struct fbtft_gpio
[]) {
1200 .name
= "waveshare22",
1201 .spi
= &(struct spi_board_info
) {
1202 .modalias
= "fb_bd663474",
1203 .max_speed_hz
= 32000000,
1205 .platform_data
= &(struct fbtft_platform_data
) {
1209 .gpios
= (const struct fbtft_gpio
[]) {
1217 /* This should be the last item.
1218 Used with the custom argument */
1220 .spi
= &(struct spi_board_info
) {
1224 .platform_data
= &(struct fbtft_platform_data
) {
1225 .gpios
= (const struct fbtft_gpio
[]) {
1230 .pdev
= &(struct platform_device
) {
1234 .release
= fbtft_device_pdev_release
,
1235 .platform_data
= &(struct fbtft_platform_data
) {
1236 .gpios
= (const struct fbtft_gpio
[]) {
1245 static int write_gpio16_wr_slow(struct fbtft_par
*par
, void *buf
, size_t len
)
1249 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1250 static u16 prev_data
;
1253 fbtft_par_dbg_hex(DEBUG_WRITE
, par
, par
->info
->device
, u8
, buf
, len
,
1254 "%s(len=%d): ", __func__
, len
);
1259 /* Start writing by pulling down /WR */
1260 gpio_set_value(par
->gpio
.wr
, 0);
1263 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1264 if (data
== prev_data
) {
1265 gpio_set_value(par
->gpio
.wr
, 0); /* used as delay */
1267 for (i
= 0; i
< 16; i
++) {
1268 if ((data
& 1) != (prev_data
& 1))
1269 gpio_set_value(par
->gpio
.db
[i
],
1276 for (i
= 0; i
< 16; i
++) {
1277 gpio_set_value(par
->gpio
.db
[i
], data
& 1);
1283 gpio_set_value(par
->gpio
.wr
, 1);
1285 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
1286 prev_data
= *(u16
*)buf
;
1295 static void adafruit18_green_tab_set_addr_win(struct fbtft_par
*par
,
1296 int xs
, int ys
, int xe
, int ye
)
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);
1303 /* used if gpios parameter is present */
1304 static struct fbtft_gpio fbtft_device_param_gpios
[MAX_GPIOS
+ 1] = { };
1306 static void fbtft_device_pdev_release(struct device
*dev
)
1308 /* Needed to silence this message:
1309 Device 'xxx' does not have a release() function, it is broken and must be fixed
1313 static int spi_device_found(struct device
*dev
, void *data
)
1315 struct spi_device
*spi
= to_spi_device(dev
);
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
,
1324 static void pr_spi_devices(void)
1326 pr_debug("SPI devices registered:\n");
1327 bus_for_each_dev(&spi_bus_type
, NULL
, NULL
, spi_device_found
);
1330 static int p_device_found(struct device
*dev
, void *data
)
1332 struct platform_device
1333 *pdev
= to_platform_device(dev
);
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");
1342 static void pr_p_devices(void)
1344 pr_debug("'fb' Platform devices registered:\n");
1345 bus_for_each_dev(&platform_bus_type
, NULL
, NULL
, p_device_found
);
1349 static void fbtft_device_spi_delete(struct spi_master
*master
, unsigned cs
)
1354 snprintf(str
, sizeof(str
), "%s.%u", dev_name(&master
->dev
), cs
);
1356 dev
= bus_find_device_by_name(&spi_bus_type
, NULL
, str
);
1359 dev_info(dev
, "Deleting %s\n", str
);
1364 static int fbtft_device_spi_device_register(struct spi_board_info
*spi
)
1366 struct spi_master
*master
;
1368 master
= spi_busnum_to_master(spi
->bus_num
);
1370 pr_err("spi_busnum_to_master(%d) returned NULL\n",
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
);
1379 dev_err(&master
->dev
, "spi_new_device() returned NULL\n");
1385 static int fbtft_device_spi_device_register(struct spi_board_info
*spi
)
1387 return spi_register_board_info(spi
, 1);
1391 static int __init
fbtft_device_init(void)
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
;
1404 pr_err("missing module parameter: 'name'\n");
1411 if (init_num
> FBTFT_MAX_INIT_SEQUENCE
) {
1412 pr_err("init parameter: exceeded max array size: %d\n",
1413 FBTFT_MAX_INIT_SEQUENCE
);
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",
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",
1431 ret
= kstrtol(p_num
, 10, &val
);
1433 pr_err("could not parse number in gpios parameter: %s:%s\n",
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",
1446 if (fbtft_device_param_gpios
[0].name
[0])
1447 gpio
= fbtft_device_param_gpios
;
1450 pr_spi_devices(); /* print list of registered SPI devices */
1453 pr_p_devices(); /* print list of 'fb' platform devices */
1455 pr_debug("name='%s', busnum=%d, cs=%d\n", name
, busnum
, cs
);
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",
1462 if (rotate
!= 0 && rotate
!= 90 && rotate
!= 180 && rotate
!= 270) {
1463 pr_warn("argument 'rotate' illegal value: %d. Setting it to 0.\n",
1468 /* name=list lists all supported displays */
1469 if (strncmp(name
, "list", FBTFT_GPIO_NAME_SIZE
) == 0) {
1470 pr_info("Supported displays:\n");
1472 for (i
= 0; i
< ARRAY_SIZE(displays
); i
++)
1473 pr_info("%s\n", displays
[i
].name
);
1478 i
= ARRAY_SIZE(displays
) - 1;
1479 displays
[i
].name
= name
;
1481 displays
[i
].pdev
->name
= name
;
1482 displays
[i
].spi
= NULL
;
1484 strncpy(displays
[i
].spi
->modalias
, name
, SPI_NAME_SIZE
);
1485 displays
[i
].pdev
= NULL
;
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
;
1496 spi
->max_speed_hz
= speed
;
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
;
1504 pr_err("broken displays array\n");
1508 pdata
->rotate
= rotate
;
1514 pdata
->startbyte
= startbyte
;
1516 pdata
->gamma
= gamma
;
1517 pdata
->display
.debug
= debug
;
1521 pdata
->txbuflen
= txbuflen
;
1523 pdata
->display
.init_sequence
= init
;
1525 pdata
->gpios
= gpio
;
1527 pdata
->display
.width
= width
;
1528 pdata
->display
.height
= height
;
1529 pdata
->display
.buswidth
= buswidth
;
1530 pdata
->display
.backlight
= 1;
1533 if (displays
[i
].spi
) {
1534 ret
= fbtft_device_spi_device_register(spi
);
1536 pr_err("failed to register SPI device\n");
1540 ret
= platform_device_register(p_device
);
1542 pr_err("platform_device_register() returned %d\n",
1553 pr_err("display not supported: '%s'\n", name
);
1557 if (verbose
&& pdata
&& pdata
->gpios
) {
1558 gpio
= pdata
->gpios
;
1559 pr_info("GPIOS used by '%s':\n", name
);
1561 while (verbose
&& gpio
->name
[0]) {
1562 pr_info("'%s' = GPIO%d\n", gpio
->name
, gpio
->gpio
);
1567 pr_info("(none)\n");
1570 if (spi_device
&& (verbose
> 1))
1572 if (p_device
&& (verbose
> 1))
1578 static void __exit
fbtft_device_exit(void)
1581 device_del(&spi_device
->dev
);
1586 platform_device_unregister(p_device
);
1590 arch_initcall(fbtft_device_init
);
1591 module_exit(fbtft_device_exit
);
1593 MODULE_DESCRIPTION("Add a FBTFT device.");
1594 MODULE_AUTHOR("Noralf Tronnes");
1595 MODULE_LICENSE("GPL");