2 * FB driver for the ILI9341 LCD display controller
4 * This display uses 9-bit SPI: Data/Command bit + 8 data bits
5 * For platforms that doesn't support 9-bit, the driver is capable
6 * of emulating this using 8-bit transfer.
7 * This is done by transferring eight 9-bit words in 9 bytes.
9 * Copyright (C) 2013 Christian Vogelgsang
10 * Based on adafruit22fb.c by Noralf Tronnes
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
23 #include <linux/module.h>
24 #include <linux/kernel.h>
25 #include <linux/init.h>
26 #include <linux/delay.h>
27 #include <video/mipi_display.h>
31 #define DRVNAME "fb_ili9341"
34 #define TXBUFLEN (4 * PAGE_SIZE)
35 #define DEFAULT_GAMMA "1F 1A 18 0A 0F 06 45 87 32 0A 07 02 07 05 00\n" \
36 "00 25 27 05 10 09 3A 78 4D 05 18 0D 38 3A 1F"
38 static int init_display(struct fbtft_par
*par
)
40 par
->fbtftops
.reset(par
);
42 /* startup sequence for MI0283QT-9A */
43 write_reg(par
, MIPI_DCS_SOFT_RESET
);
45 write_reg(par
, MIPI_DCS_SET_DISPLAY_OFF
);
46 /* --------------------------------------------------------- */
47 write_reg(par
, 0xCF, 0x00, 0x83, 0x30);
48 write_reg(par
, 0xED, 0x64, 0x03, 0x12, 0x81);
49 write_reg(par
, 0xE8, 0x85, 0x01, 0x79);
50 write_reg(par
, 0xCB, 0x39, 0X2C, 0x00, 0x34, 0x02);
51 write_reg(par
, 0xF7, 0x20);
52 write_reg(par
, 0xEA, 0x00, 0x00);
53 /* ------------power control-------------------------------- */
54 write_reg(par
, 0xC0, 0x26);
55 write_reg(par
, 0xC1, 0x11);
56 /* ------------VCOM --------- */
57 write_reg(par
, 0xC5, 0x35, 0x3E);
58 write_reg(par
, 0xC7, 0xBE);
59 /* ------------memory access control------------------------ */
60 write_reg(par
, MIPI_DCS_SET_PIXEL_FORMAT
, 0x55); /* 16bit pixel */
61 /* ------------frame rate----------------------------------- */
62 write_reg(par
, 0xB1, 0x00, 0x1B);
63 /* ------------Gamma---------------------------------------- */
64 /* write_reg(par, 0xF2, 0x08); */ /* Gamma Function Disable */
65 write_reg(par
, MIPI_DCS_SET_GAMMA_CURVE
, 0x01);
66 /* ------------display-------------------------------------- */
67 write_reg(par
, 0xB7, 0x07); /* entry mode set */
68 write_reg(par
, 0xB6, 0x0A, 0x82, 0x27, 0x00);
69 write_reg(par
, MIPI_DCS_EXIT_SLEEP_MODE
);
71 write_reg(par
, MIPI_DCS_SET_DISPLAY_ON
);
77 static void set_addr_win(struct fbtft_par
*par
, int xs
, int ys
, int xe
, int ye
)
79 write_reg(par
, MIPI_DCS_SET_COLUMN_ADDRESS
,
80 (xs
>> 8) & 0xFF, xs
& 0xFF, (xe
>> 8) & 0xFF, xe
& 0xFF);
82 write_reg(par
, MIPI_DCS_SET_PAGE_ADDRESS
,
83 (ys
>> 8) & 0xFF, ys
& 0xFF, (ye
>> 8) & 0xFF, ye
& 0xFF);
85 write_reg(par
, MIPI_DCS_WRITE_MEMORY_START
);
88 #define MEM_Y BIT(7) /* MY row address order */
89 #define MEM_X BIT(6) /* MX column address order */
90 #define MEM_V BIT(5) /* MV row / column exchange */
91 #define MEM_L BIT(4) /* ML vertical refresh order */
92 #define MEM_H BIT(2) /* MH horizontal refresh order */
93 #define MEM_BGR (3) /* RGB-BGR Order */
94 static int set_var(struct fbtft_par
*par
)
96 switch (par
->info
->var
.rotate
) {
98 write_reg(par
, MIPI_DCS_SET_ADDRESS_MODE
,
99 MEM_X
| (par
->bgr
<< MEM_BGR
));
102 write_reg(par
, MIPI_DCS_SET_ADDRESS_MODE
,
103 MEM_V
| MEM_L
| (par
->bgr
<< MEM_BGR
));
106 write_reg(par
, MIPI_DCS_SET_ADDRESS_MODE
,
107 MEM_Y
| (par
->bgr
<< MEM_BGR
));
110 write_reg(par
, MIPI_DCS_SET_ADDRESS_MODE
,
111 MEM_Y
| MEM_X
| MEM_V
| (par
->bgr
<< MEM_BGR
));
119 * Gamma string format:
120 * Positive: Par1 Par2 [...] Par15
121 * Negative: Par1 Par2 [...] Par15
123 #define CURVE(num, idx) curves[num * par->gamma.num_values + idx]
124 static int set_gamma(struct fbtft_par
*par
, u32
*curves
)
128 for (i
= 0; i
< par
->gamma
.num_curves
; i
++)
129 write_reg(par
, 0xE0 + i
,
130 CURVE(i
, 0), CURVE(i
, 1), CURVE(i
, 2),
131 CURVE(i
, 3), CURVE(i
, 4), CURVE(i
, 5),
132 CURVE(i
, 6), CURVE(i
, 7), CURVE(i
, 8),
133 CURVE(i
, 9), CURVE(i
, 10), CURVE(i
, 11),
134 CURVE(i
, 12), CURVE(i
, 13), CURVE(i
, 14));
141 static struct fbtft_display display
= {
145 .txbuflen
= TXBUFLEN
,
148 .gamma
= DEFAULT_GAMMA
,
150 .init_display
= init_display
,
151 .set_addr_win
= set_addr_win
,
153 .set_gamma
= set_gamma
,
157 FBTFT_REGISTER_DRIVER(DRVNAME
, "ilitek,ili9341", &display
);
159 MODULE_ALIAS("spi:" DRVNAME
);
160 MODULE_ALIAS("platform:" DRVNAME
);
161 MODULE_ALIAS("spi:ili9341");
162 MODULE_ALIAS("platform:ili9341");
164 MODULE_DESCRIPTION("FB driver for the ILI9341 LCD display controller");
165 MODULE_AUTHOR("Christian Vogelgsang");
166 MODULE_LICENSE("GPL");