]>
Commit | Line | Data |
---|---|---|
8f7fdaaf TP |
1 | /* |
2 | * FB driver for the ILI9340 LCD Controller | |
3 | * | |
4 | * Copyright (C) 2013 Noralf Tronnes | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, write to the Free Software | |
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
19 | */ | |
20 | ||
21 | #include <linux/module.h> | |
22 | #include <linux/kernel.h> | |
23 | #include <linux/init.h> | |
24 | #include <linux/gpio.h> | |
25 | #include <linux/delay.h> | |
26 | ||
27 | #include "fbtft.h" | |
28 | ||
29 | #define DRVNAME "fb_ili9340" | |
30 | #define WIDTH 240 | |
31 | #define HEIGHT 320 | |
32 | ||
33 | ||
34 | /* Init sequence taken from: Arduino Library for the Adafruit 2.2" display */ | |
35 | static int init_display(struct fbtft_par *par) | |
36 | { | |
37 | fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__); | |
38 | ||
39 | par->fbtftops.reset(par); | |
40 | ||
41 | write_reg(par, 0xEF, 0x03, 0x80, 0x02); | |
43da0d92 AM |
42 | write_reg(par, 0xCF, 0x00, 0XC1, 0X30); |
43 | write_reg(par, 0xED, 0x64, 0x03, 0X12, 0X81); | |
44 | write_reg(par, 0xE8, 0x85, 0x00, 0x78); | |
45 | write_reg(par, 0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02); | |
8f7fdaaf | 46 | write_reg(par, 0xF7, 0x20); |
43da0d92 | 47 | write_reg(par, 0xEA, 0x00, 0x00); |
8f7fdaaf TP |
48 | |
49 | /* Power Control 1 */ | |
50 | write_reg(par, 0xC0, 0x23); | |
51 | ||
52 | /* Power Control 2 */ | |
53 | write_reg(par, 0xC1, 0x10); | |
54 | ||
55 | /* VCOM Control 1 */ | |
56 | write_reg(par, 0xC5, 0x3e, 0x28); | |
57 | ||
58 | /* VCOM Control 2 */ | |
59 | write_reg(par, 0xC7, 0x86); | |
60 | ||
61 | /* COLMOD: Pixel Format Set */ | |
62 | /* 16 bits/pixel */ | |
63 | write_reg(par, 0x3A, 0x55); | |
64 | ||
65 | /* Frame Rate Control */ | |
66 | /* Division ratio = fosc, Frame Rate = 79Hz */ | |
67 | write_reg(par, 0xB1, 0x00, 0x18); | |
68 | ||
69 | /* Display Function Control */ | |
70 | write_reg(par, 0xB6, 0x08, 0x82, 0x27); | |
71 | ||
72 | /* Gamma Function Disable */ | |
73 | write_reg(par, 0xF2, 0x00); | |
74 | ||
75 | /* Gamma curve selected */ | |
76 | write_reg(par, 0x26, 0x01); | |
77 | ||
78 | /* Positive Gamma Correction */ | |
79 | write_reg(par, 0xE0, | |
80 | 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, | |
81 | 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00); | |
82 | ||
83 | /* Negative Gamma Correction */ | |
84 | write_reg(par, 0xE1, | |
85 | 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, | |
86 | 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F); | |
87 | ||
88 | /* Sleep OUT */ | |
89 | write_reg(par, 0x11); | |
90 | ||
91 | mdelay(120); | |
92 | ||
93 | /* Display ON */ | |
94 | write_reg(par, 0x29); | |
95 | ||
96 | return 0; | |
97 | } | |
98 | ||
99 | static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye) | |
100 | { | |
101 | fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, | |
102 | "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye); | |
103 | ||
104 | /* Column address */ | |
105 | write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF); | |
106 | ||
92def781 | 107 | /* Row address */ |
8f7fdaaf TP |
108 | write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF); |
109 | ||
110 | /* Memory write */ | |
111 | write_reg(par, 0x2C); | |
112 | } | |
113 | ||
114 | #define ILI9340_MADCTL_MV 0x20 | |
115 | #define ILI9340_MADCTL_MX 0x40 | |
116 | #define ILI9340_MADCTL_MY 0x80 | |
117 | static int set_var(struct fbtft_par *par) | |
118 | { | |
119 | u8 val; | |
120 | ||
121 | fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__); | |
122 | ||
123 | switch (par->info->var.rotate) { | |
124 | case 270: | |
125 | val = ILI9340_MADCTL_MV; | |
126 | break; | |
127 | case 180: | |
128 | val = ILI9340_MADCTL_MY; | |
129 | break; | |
130 | case 90: | |
131 | val = ILI9340_MADCTL_MV | ILI9340_MADCTL_MY | ILI9340_MADCTL_MX; | |
132 | break; | |
133 | default: | |
134 | val = ILI9340_MADCTL_MX; | |
135 | break; | |
136 | } | |
137 | /* Memory Access Control */ | |
138 | write_reg(par, 0x36, val | (par->bgr << 3)); | |
139 | ||
140 | return 0; | |
141 | } | |
142 | ||
143 | ||
144 | static struct fbtft_display display = { | |
145 | .regwidth = 8, | |
146 | .width = WIDTH, | |
147 | .height = HEIGHT, | |
148 | .fbtftops = { | |
149 | .init_display = init_display, | |
150 | .set_addr_win = set_addr_win, | |
151 | .set_var = set_var, | |
152 | }, | |
153 | }; | |
154 | FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9340", &display); | |
155 | ||
156 | MODULE_ALIAS("spi:" DRVNAME); | |
157 | MODULE_ALIAS("platform:" DRVNAME); | |
158 | MODULE_ALIAS("spi:ili9340"); | |
159 | MODULE_ALIAS("platform:ili9340"); | |
160 | ||
161 | MODULE_DESCRIPTION("FB driver for the ILI9340 LCD Controller"); | |
162 | MODULE_AUTHOR("Noralf Tronnes"); | |
163 | MODULE_LICENSE("GPL"); |