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