Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[firefly-linux-kernel-4.4.55.git] / drivers / staging / fbtft / fb_hx8357d.c
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.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/init.h>
27 #include <linux/delay.h>
28
29 #include "fbtft.h"
30 #include "fb_hx8357d.h"
31
32 #define DRVNAME         "fb_hx8357d"
33 #define WIDTH           320
34 #define HEIGHT          480
35
36
37 static int init_display(struct fbtft_par *par)
38 {
39         fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
40
41         par->fbtftops.reset(par);
42
43         /* Reset things like Gamma */
44         write_reg(par, HX8357B_SWRESET);
45         usleep_range(5000, 7000);
46
47         /* setextc */
48         write_reg(par, HX8357D_SETC, 0xFF, 0x83, 0x57);
49         msleep(150);
50
51         /* setRGB which also enables SDO */
52         write_reg(par, HX8357_SETRGB, 0x00, 0x00, 0x06, 0x06);
53
54         /* -1.52V */
55         write_reg(par, HX8357D_SETCOM, 0x25);
56
57         /* Normal mode 70Hz, Idle mode 55 Hz */
58         write_reg(par, HX8357_SETOSC, 0x68);
59
60         /* Set Panel - BGR, Gate direction swapped */
61         write_reg(par, HX8357_SETPANEL, 0x05);
62
63         write_reg(par, HX8357_SETPWR1,
64                 0x00,  /* Not deep standby */
65                 0x15,  /* BT */
66                 0x1C,  /* VSPR */
67                 0x1C,  /* VSNR */
68                 0x83,  /* AP */
69                 0xAA);  /* FS */
70
71         write_reg(par, HX8357D_SETSTBA,
72                 0x50,  /* OPON normal */
73                 0x50,  /* OPON idle */
74                 0x01,  /* STBA */
75                 0x3C,  /* STBA */
76                 0x1E,  /* STBA */
77                 0x08);  /* GEN */
78
79         write_reg(par, HX8357D_SETCYC,
80                 0x02,  /* NW 0x02 */
81                 0x40,  /* RTN */
82                 0x00,  /* DIV */
83                 0x2A,  /* DUM */
84                 0x2A,  /* DUM */
85                 0x0D,  /* GDON */
86                 0x78);  /* GDOFF */
87
88         write_reg(par, HX8357D_SETGAMMA,
89                 0x02,
90                 0x0A,
91                 0x11,
92                 0x1d,
93                 0x23,
94                 0x35,
95                 0x41,
96                 0x4b,
97                 0x4b,
98                 0x42,
99                 0x3A,
100                 0x27,
101                 0x1B,
102                 0x08,
103                 0x09,
104                 0x03,
105                 0x02,
106                 0x0A,
107                 0x11,
108                 0x1d,
109                 0x23,
110                 0x35,
111                 0x41,
112                 0x4b,
113                 0x4b,
114                 0x42,
115                 0x3A,
116                 0x27,
117                 0x1B,
118                 0x08,
119                 0x09,
120                 0x03,
121                 0x00,
122                 0x01);
123
124         /* 16 bit */
125         write_reg(par, HX8357_COLMOD, 0x55);
126
127         write_reg(par, HX8357_MADCTL, 0xC0);
128
129         /* TE off */
130         write_reg(par, HX8357_TEON, 0x00);
131
132         /* tear line */
133         write_reg(par, HX8357_TEARLINE, 0x00, 0x02);
134
135         /* Exit Sleep */
136         write_reg(par, HX8357_SLPOUT);
137         msleep(150);
138
139         /* display on */
140         write_reg(par, HX8357_DISPON);
141         usleep_range(5000, 7000);
142
143         return 0;
144 }
145
146 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
147 {
148         fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
149                 "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
150
151         /* Column addr set */
152         write_reg(par, HX8357_CASET,
153                 xs >> 8, xs & 0xff,  /* XSTART */
154                 xe >> 8, xe & 0xff); /* XEND */
155
156         /* Row addr set */
157         write_reg(par, HX8357_PASET,
158                 ys >> 8, ys & 0xff,  /* YSTART */
159                 ye >> 8, ye & 0xff); /* YEND */
160
161         /* write to RAM */
162         write_reg(par, HX8357_RAMWR);
163 }
164
165 #define HX8357D_MADCTL_MY  0x80
166 #define HX8357D_MADCTL_MX  0x40
167 #define HX8357D_MADCTL_MV  0x20
168 #define HX8357D_MADCTL_ML  0x10
169 #define HX8357D_MADCTL_RGB 0x00
170 #define HX8357D_MADCTL_BGR 0x08
171 #define HX8357D_MADCTL_MH  0x04
172 static int set_var(struct fbtft_par *par)
173 {
174         u8 val;
175
176         fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
177
178         switch (par->info->var.rotate) {
179         case 270:
180                 val = HX8357D_MADCTL_MV | HX8357D_MADCTL_MX;
181                 break;
182         case 180:
183                 val = 0;
184                 break;
185         case 90:
186                 val = HX8357D_MADCTL_MV | HX8357D_MADCTL_MY;
187                 break;
188         default:
189                 val = HX8357D_MADCTL_MX | HX8357D_MADCTL_MY;
190                 break;
191         }
192
193         val |= (par->bgr ? HX8357D_MADCTL_RGB : HX8357D_MADCTL_BGR);
194
195         /* Memory Access Control */
196         write_reg(par, HX8357_MADCTL, val);
197
198         return 0;
199 }
200
201 static struct fbtft_display display = {
202         .regwidth = 8,
203         .width = WIDTH,
204         .height = HEIGHT,
205         .gamma_num = 2,
206         .gamma_len = 14,
207         .fbtftops = {
208                 .init_display = init_display,
209                 .set_addr_win = set_addr_win,
210                 .set_var = set_var,
211         },
212 };
213 FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8357d", &display);
214
215 MODULE_ALIAS("spi:" DRVNAME);
216 MODULE_ALIAS("platform:" DRVNAME);
217 MODULE_ALIAS("spi:hx8357d");
218 MODULE_ALIAS("platform:hx8357d");
219
220 MODULE_DESCRIPTION("FB driver for the HX8357D LCD Controller");
221 MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>");
222 MODULE_LICENSE("GPL");