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