Commit | Line | Data |
---|---|---|
9cd491e8 HK |
1 | /* |
2 | * FB driver for the HX8357D LCD Controller | |
3 | * Copyright (C) 2015 Adafruit Industries | |
4 | * | |
5 | * Based on the HX8347D FB driver | |
6 | * Copyright (C) 2013 Christian Vogelgsang | |
7 | * | |
8 | * Based on driver code found here: https://github.com/watterott/r61505u-Adapter | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License as published by | |
12 | * the Free Software Foundation; either version 2 of the License, or | |
13 | * (at your option) any later version. | |
14 | * | |
15 | * This program is distributed in the hope that it will be useful, | |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | * GNU General Public License for more details. | |
9cd491e8 HK |
19 | */ |
20 | ||
21 | #include <linux/module.h> | |
22 | #include <linux/kernel.h> | |
23 | #include <linux/init.h> | |
24 | #include <linux/delay.h> | |
95808932 | 25 | #include <video/mipi_display.h> |
9cd491e8 HK |
26 | |
27 | #include "fbtft.h" | |
28 | #include "fb_hx8357d.h" | |
29 | ||
30 | #define DRVNAME "fb_hx8357d" | |
31 | #define WIDTH 320 | |
32 | #define HEIGHT 480 | |
33 | ||
9cd491e8 HK |
34 | static int init_display(struct fbtft_par *par) |
35 | { | |
9cd491e8 HK |
36 | par->fbtftops.reset(par); |
37 | ||
38 | /* Reset things like Gamma */ | |
95808932 | 39 | write_reg(par, MIPI_DCS_SOFT_RESET); |
9cd491e8 HK |
40 | usleep_range(5000, 7000); |
41 | ||
42 | /* setextc */ | |
43 | write_reg(par, HX8357D_SETC, 0xFF, 0x83, 0x57); | |
44 | msleep(150); | |
45 | ||
46 | /* setRGB which also enables SDO */ | |
47 | write_reg(par, HX8357_SETRGB, 0x00, 0x00, 0x06, 0x06); | |
48 | ||
49 | /* -1.52V */ | |
50 | write_reg(par, HX8357D_SETCOM, 0x25); | |
51 | ||
52 | /* Normal mode 70Hz, Idle mode 55 Hz */ | |
53 | write_reg(par, HX8357_SETOSC, 0x68); | |
54 | ||
55 | /* Set Panel - BGR, Gate direction swapped */ | |
56 | write_reg(par, HX8357_SETPANEL, 0x05); | |
57 | ||
58 | write_reg(par, HX8357_SETPWR1, | |
5f10ef7d ERR |
59 | 0x00, /* Not deep standby */ |
60 | 0x15, /* BT */ | |
61 | 0x1C, /* VSPR */ | |
62 | 0x1C, /* VSNR */ | |
63 | 0x83, /* AP */ | |
64 | 0xAA); /* FS */ | |
9cd491e8 HK |
65 | |
66 | write_reg(par, HX8357D_SETSTBA, | |
5f10ef7d ERR |
67 | 0x50, /* OPON normal */ |
68 | 0x50, /* OPON idle */ | |
69 | 0x01, /* STBA */ | |
70 | 0x3C, /* STBA */ | |
71 | 0x1E, /* STBA */ | |
72 | 0x08); /* GEN */ | |
9cd491e8 HK |
73 | |
74 | write_reg(par, HX8357D_SETCYC, | |
5f10ef7d ERR |
75 | 0x02, /* NW 0x02 */ |
76 | 0x40, /* RTN */ | |
77 | 0x00, /* DIV */ | |
78 | 0x2A, /* DUM */ | |
79 | 0x2A, /* DUM */ | |
80 | 0x0D, /* GDON */ | |
81 | 0x78); /* GDOFF */ | |
9cd491e8 HK |
82 | |
83 | write_reg(par, HX8357D_SETGAMMA, | |
5f10ef7d ERR |
84 | 0x02, |
85 | 0x0A, | |
86 | 0x11, | |
87 | 0x1d, | |
88 | 0x23, | |
89 | 0x35, | |
90 | 0x41, | |
91 | 0x4b, | |
92 | 0x4b, | |
93 | 0x42, | |
94 | 0x3A, | |
95 | 0x27, | |
96 | 0x1B, | |
97 | 0x08, | |
98 | 0x09, | |
99 | 0x03, | |
100 | 0x02, | |
101 | 0x0A, | |
102 | 0x11, | |
103 | 0x1d, | |
104 | 0x23, | |
105 | 0x35, | |
106 | 0x41, | |
107 | 0x4b, | |
108 | 0x4b, | |
109 | 0x42, | |
110 | 0x3A, | |
111 | 0x27, | |
112 | 0x1B, | |
113 | 0x08, | |
114 | 0x09, | |
115 | 0x03, | |
116 | 0x00, | |
117 | 0x01); | |
9cd491e8 HK |
118 | |
119 | /* 16 bit */ | |
95808932 | 120 | write_reg(par, MIPI_DCS_SET_PIXEL_FORMAT, 0x55); |
9cd491e8 | 121 | |
95808932 | 122 | write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, 0xC0); |
9cd491e8 HK |
123 | |
124 | /* TE off */ | |
95808932 | 125 | write_reg(par, MIPI_DCS_SET_TEAR_ON, 0x00); |
9cd491e8 HK |
126 | |
127 | /* tear line */ | |
95808932 | 128 | write_reg(par, MIPI_DCS_SET_TEAR_SCANLINE, 0x00, 0x02); |
9cd491e8 HK |
129 | |
130 | /* Exit Sleep */ | |
95808932 | 131 | write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); |
9cd491e8 HK |
132 | msleep(150); |
133 | ||
134 | /* display on */ | |
95808932 | 135 | write_reg(par, MIPI_DCS_SET_DISPLAY_ON); |
9cd491e8 HK |
136 | usleep_range(5000, 7000); |
137 | ||
138 | return 0; | |
139 | } | |
140 | ||
141 | static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye) | |
142 | { | |
95808932 PL |
143 | write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS, |
144 | xs >> 8, xs & 0xff, /* XSTART */ | |
145 | xe >> 8, xe & 0xff); /* XEND */ | |
146 | ||
147 | write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS, | |
148 | ys >> 8, ys & 0xff, /* YSTART */ | |
149 | ye >> 8, ye & 0xff); /* YEND */ | |
150 | ||
151 | write_reg(par, MIPI_DCS_WRITE_MEMORY_START); | |
9cd491e8 HK |
152 | } |
153 | ||
154 | #define HX8357D_MADCTL_MY 0x80 | |
155 | #define HX8357D_MADCTL_MX 0x40 | |
156 | #define HX8357D_MADCTL_MV 0x20 | |
157 | #define HX8357D_MADCTL_ML 0x10 | |
158 | #define HX8357D_MADCTL_RGB 0x00 | |
159 | #define HX8357D_MADCTL_BGR 0x08 | |
160 | #define HX8357D_MADCTL_MH 0x04 | |
161 | static int set_var(struct fbtft_par *par) | |
162 | { | |
163 | u8 val; | |
164 | ||
9cd491e8 HK |
165 | switch (par->info->var.rotate) { |
166 | case 270: | |
167 | val = HX8357D_MADCTL_MV | HX8357D_MADCTL_MX; | |
168 | break; | |
169 | case 180: | |
170 | val = 0; | |
171 | break; | |
172 | case 90: | |
173 | val = HX8357D_MADCTL_MV | HX8357D_MADCTL_MY; | |
174 | break; | |
175 | default: | |
176 | val = HX8357D_MADCTL_MX | HX8357D_MADCTL_MY; | |
177 | break; | |
178 | } | |
179 | ||
180 | val |= (par->bgr ? HX8357D_MADCTL_RGB : HX8357D_MADCTL_BGR); | |
181 | ||
182 | /* Memory Access Control */ | |
95808932 | 183 | write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, val); |
9cd491e8 HK |
184 | |
185 | return 0; | |
186 | } | |
187 | ||
188 | static struct fbtft_display display = { | |
189 | .regwidth = 8, | |
190 | .width = WIDTH, | |
191 | .height = HEIGHT, | |
192 | .gamma_num = 2, | |
193 | .gamma_len = 14, | |
194 | .fbtftops = { | |
195 | .init_display = init_display, | |
196 | .set_addr_win = set_addr_win, | |
197 | .set_var = set_var, | |
198 | }, | |
199 | }; | |
1014c2ce | 200 | |
9cd491e8 HK |
201 | FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8357d", &display); |
202 | ||
203 | MODULE_ALIAS("spi:" DRVNAME); | |
204 | MODULE_ALIAS("platform:" DRVNAME); | |
205 | MODULE_ALIAS("spi:hx8357d"); | |
206 | MODULE_ALIAS("platform:hx8357d"); | |
207 | ||
208 | MODULE_DESCRIPTION("FB driver for the HX8357D LCD Controller"); | |
209 | MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>"); | |
210 | MODULE_LICENSE("GPL"); |