blob: 709492e560b61b64a52502e360d0fdbcebd05ee2 [file] [log] [blame]
Thomas Petazzoni9b78e452014-12-31 10:11:18 +01001/*
2 * FB driver for the ILI9341 LCD display controller
3 *
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.
Masanari Iida92def782015-03-21 11:48:37 +09007 * This is done by transferring eight 9-bit words in 9 bytes.
Thomas Petazzoni9b78e452014-12-31 10:11:18 +01008 *
9 * Copyright (C) 2013 Christian Vogelgsang
10 * Based on adafruit22fb.c by Noralf Tronnes
11 *
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.
16 *
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.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31
32#include "fbtft.h"
33
34#define DRVNAME "fb_ili9341"
35#define WIDTH 240
36#define HEIGHT 320
37#define TXBUFLEN (4 * PAGE_SIZE)
38#define DEFAULT_GAMMA "1F 1A 18 0A 0F 06 45 87 32 0A 07 02 07 05 00\n" \
39 "00 25 27 05 10 09 3A 78 4D 05 18 0D 38 3A 1F"
40
41
42static int init_display(struct fbtft_par *par)
43{
44 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
45
46 par->fbtftops.reset(par);
47
48 /* startup sequence for MI0283QT-9A */
49 write_reg(par, 0x01); /* software reset */
50 mdelay(5);
51 write_reg(par, 0x28); /* display off */
52 /* --------------------------------------------------------- */
53 write_reg(par, 0xCF, 0x00, 0x83, 0x30);
54 write_reg(par, 0xED, 0x64, 0x03, 0x12, 0x81);
55 write_reg(par, 0xE8, 0x85, 0x01, 0x79);
56 write_reg(par, 0xCB, 0x39, 0X2C, 0x00, 0x34, 0x02);
57 write_reg(par, 0xF7, 0x20);
58 write_reg(par, 0xEA, 0x00, 0x00);
59 /* ------------power control-------------------------------- */
60 write_reg(par, 0xC0, 0x26);
61 write_reg(par, 0xC1, 0x11);
62 /* ------------VCOM --------- */
63 write_reg(par, 0xC5, 0x35, 0x3E);
64 write_reg(par, 0xC7, 0xBE);
65 /* ------------memory access control------------------------ */
66 write_reg(par, 0x3A, 0x55); /* 16bit pixel */
67 /* ------------frame rate----------------------------------- */
68 write_reg(par, 0xB1, 0x00, 0x1B);
69 /* ------------Gamma---------------------------------------- */
70 /* write_reg(par, 0xF2, 0x08); */ /* Gamma Function Disable */
71 write_reg(par, 0x26, 0x01);
72 /* ------------display-------------------------------------- */
73 write_reg(par, 0xB7, 0x07); /* entry mode set */
74 write_reg(par, 0xB6, 0x0A, 0x82, 0x27, 0x00);
75 write_reg(par, 0x11); /* sleep out */
76 mdelay(100);
77 write_reg(par, 0x29); /* display on */
78 mdelay(20);
79
80 return 0;
81}
82
83static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
84{
85 fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
86 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
87
88 /* Column address set */
89 write_reg(par, 0x2A,
90 (xs >> 8) & 0xFF, xs & 0xFF, (xe >> 8) & 0xFF, xe & 0xFF);
91
Masanari Iida92def782015-03-21 11:48:37 +090092 /* Row address set */
Thomas Petazzoni9b78e452014-12-31 10:11:18 +010093 write_reg(par, 0x2B,
94 (ys >> 8) & 0xFF, ys & 0xFF, (ye >> 8) & 0xFF, ye & 0xFF);
95
96 /* Memory write */
97 write_reg(par, 0x2C);
98}
99
100#define MEM_Y (7) /* MY row address order */
101#define MEM_X (6) /* MX column address order */
102#define MEM_V (5) /* MV row / column exchange */
103#define MEM_L (4) /* ML vertical refresh order */
104#define MEM_H (2) /* MH horizontal refresh order */
105#define MEM_BGR (3) /* RGB-BGR Order */
106static int set_var(struct fbtft_par *par)
107{
108 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
109
110 switch (par->info->var.rotate) {
111 case 0:
112 write_reg(par, 0x36, (1 << MEM_X) | (par->bgr << MEM_BGR));
113 break;
114 case 270:
115 write_reg(par, 0x36,
116 (1<<MEM_V) | (1 << MEM_L) | (par->bgr << MEM_BGR));
117 break;
118 case 180:
119 write_reg(par, 0x36, (1 << MEM_Y) | (par->bgr << MEM_BGR));
120 break;
121 case 90:
122 write_reg(par, 0x36, (1 << MEM_Y) | (1 << MEM_X) |
123 (1 << MEM_V) | (par->bgr << MEM_BGR));
124 break;
125 }
126
127 return 0;
128}
129
130/*
131 Gamma string format:
132 Positive: Par1 Par2 [...] Par15
133 Negative: Par1 Par2 [...] Par15
134*/
135#define CURVE(num, idx) curves[num*par->gamma.num_values + idx]
136static int set_gamma(struct fbtft_par *par, unsigned long *curves)
137{
138 int i;
139
140 fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
141
142 for (i = 0; i < par->gamma.num_curves; i++)
143 write_reg(par, 0xE0 + i,
144 CURVE(i, 0), CURVE(i, 1), CURVE(i, 2),
145 CURVE(i, 3), CURVE(i, 4), CURVE(i, 5),
146 CURVE(i, 6), CURVE(i, 7), CURVE(i, 8),
147 CURVE(i, 9), CURVE(i, 10), CURVE(i, 11),
148 CURVE(i, 12), CURVE(i, 13), CURVE(i, 14));
149
150 return 0;
151}
152#undef CURVE
153
154
155static struct fbtft_display display = {
156 .regwidth = 8,
157 .width = WIDTH,
158 .height = HEIGHT,
159 .txbuflen = TXBUFLEN,
160 .gamma_num = 2,
161 .gamma_len = 15,
162 .gamma = DEFAULT_GAMMA,
163 .fbtftops = {
164 .init_display = init_display,
165 .set_addr_win = set_addr_win,
166 .set_var = set_var,
167 .set_gamma = set_gamma,
168 },
169};
170FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9341", &display);
171
172MODULE_ALIAS("spi:" DRVNAME);
173MODULE_ALIAS("platform:" DRVNAME);
174MODULE_ALIAS("spi:ili9341");
175MODULE_ALIAS("platform:ili9341");
176
177MODULE_DESCRIPTION("FB driver for the ILI9341 LCD display controller");
178MODULE_AUTHOR("Christian Vogelgsang");
179MODULE_LICENSE("GPL");