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