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