1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/vmalloc.h>
26#include <linux/spi/spi.h>
27#include <linux/delay.h>
28#include <video/mipi_display.h>
29
30#include "fbtft.h"
31
32#define DRVNAME "fb_hx8340bn"
33#define WIDTH 176
34#define HEIGHT 220
35#define TXBUFLEN (4 * PAGE_SIZE)
36#define DEFAULT_GAMMA "1 3 0E 5 0 2 09 0 6 1 7 1 0 2 2\n" \
37 "3 3 17 8 4 7 05 7 6 0 3 1 6 0 0 "
38
39static bool emulate;
40module_param(emulate, bool, 0);
41MODULE_PARM_DESC(emulate, "Force emulation in 9-bit mode");
42
43static int init_display(struct fbtft_par *par)
44{
45 par->fbtftops.reset(par);
46
47
48
49
50
51
52
53
54 write_reg(par, 0xC1, 0xFF, 0x83, 0x40);
55
56
57
58
59
60
61
62 write_reg(par, 0x11);
63 mdelay(150);
64
65
66 write_reg(par, 0xCA, 0x70, 0x00, 0xD9);
67
68
69
70
71
72
73
74 write_reg(par, 0xB0, 0x01, 0x11);
75
76
77 write_reg(par, 0xC9, 0x90, 0x49, 0x10, 0x28, 0x28, 0x10, 0x00, 0x06);
78 mdelay(20);
79
80
81
82
83
84
85
86
87 write_reg(par, 0xB5, 0x35, 0x20, 0x45);
88
89
90
91
92
93
94
95
96 write_reg(par, 0xB4, 0x33, 0x25, 0x4C);
97 mdelay(10);
98
99
100
101
102
103
104
105 write_reg(par, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT);
106
107
108
109
110
111
112 write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
113 mdelay(10);
114
115 return 0;
116}
117
118static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
119{
120 write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS, 0x00, xs, 0x00, xe);
121 write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS, 0x00, ys, 0x00, ye);
122 write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
123}
124
125static int set_var(struct fbtft_par *par)
126{
127
128
129#define MY BIT(7)
130#define MX BIT(6)
131#define MV BIT(5)
132 switch (par->info->var.rotate) {
133 case 0:
134 write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, par->bgr << 3);
135 break;
136 case 270:
137 write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
138 MX | MV | (par->bgr << 3));
139 break;
140 case 180:
141 write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
142 MX | MY | (par->bgr << 3));
143 break;
144 case 90:
145 write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
146 MY | MV | (par->bgr << 3));
147 break;
148 }
149
150 return 0;
151}
152
153
154
155
156
157
158
159
160#define CURVE(num, idx) curves[num * par->gamma.num_values + idx]
161static int set_gamma(struct fbtft_par *par, unsigned long *curves)
162{
163 unsigned long mask[] = {
164 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x0f, 0x1f, 0x07, 0x07, 0x07,
165 0x07, 0x07, 0x07, 0x03, 0x03, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f,
166 0x0f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00,
167 };
168 int i, j;
169
170
171 for (i = 0; i < par->gamma.num_curves; i++)
172 for (j = 0; j < par->gamma.num_values; j++)
173 CURVE(i, j) &= mask[i * par->gamma.num_values + j];
174
175
176 write_reg(par, MIPI_DCS_SET_GAMMA_CURVE, 1 << CURVE(1, 14));
177
178 if (CURVE(1, 14))
179 return 0;
180
181 write_reg(par, 0xC2,
182 (CURVE(0, 8) << 4) | CURVE(0, 7),
183 (CURVE(0, 10) << 4) | CURVE(0, 9),
184 (CURVE(0, 12) << 4) | CURVE(0, 11),
185 CURVE(0, 2),
186 (CURVE(0, 4) << 4) | CURVE(0, 3),
187 CURVE(0, 5),
188 CURVE(0, 6),
189 (CURVE(0, 1) << 4) | CURVE(0, 0),
190 (CURVE(0, 14) << 2) | CURVE(0, 13));
191
192 write_reg(par, 0xC3,
193 (CURVE(1, 8) << 4) | CURVE(1, 7),
194 (CURVE(1, 10) << 4) | CURVE(1, 9),
195 (CURVE(1, 12) << 4) | CURVE(1, 11),
196 CURVE(1, 2),
197 (CURVE(1, 4) << 4) | CURVE(1, 3),
198 CURVE(1, 5),
199 CURVE(1, 6),
200 (CURVE(1, 1) << 4) | CURVE(1, 0));
201
202 mdelay(10);
203
204 return 0;
205}
206
207#undef CURVE
208
209static struct fbtft_display display = {
210 .regwidth = 8,
211 .width = WIDTH,
212 .height = HEIGHT,
213 .txbuflen = TXBUFLEN,
214 .gamma_num = 2,
215 .gamma_len = 15,
216 .gamma = DEFAULT_GAMMA,
217 .fbtftops = {
218 .init_display = init_display,
219 .set_addr_win = set_addr_win,
220 .set_var = set_var,
221 .set_gamma = set_gamma,
222 },
223};
224
225FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8340bn", &display);
226
227MODULE_ALIAS("spi:" DRVNAME);
228MODULE_ALIAS("platform:" DRVNAME);
229MODULE_ALIAS("spi:hx8340bn");
230MODULE_ALIAS("platform:hx8340bn");
231
232MODULE_DESCRIPTION("FB driver for the HX8340BN LCD Controller");
233MODULE_AUTHOR("Noralf Tronnes");
234MODULE_LICENSE("GPL");
235