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