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