Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
[linux-2.6-microblaze.git] / drivers / staging / fbtft / fb_ra8875.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * FBTFT driver for the RA8875 LCD Controller
4  * Copyright by Pf@nne & NOTRO
5  */
6
7 #include <linux/module.h>
8 #include <linux/kernel.h>
9 #include <linux/init.h>
10 #include <linux/delay.h>
11
12 #include <linux/gpio/consumer.h>
13 #include "fbtft.h"
14
15 #define DRVNAME "fb_ra8875"
16
17 static int write_spi(struct fbtft_par *par, void *buf, size_t len)
18 {
19         struct spi_transfer t = {
20                 .tx_buf = buf,
21                 .len = len,
22                 .speed_hz = 1000000,
23         };
24         struct spi_message m;
25
26         fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
27                           "%s(len=%zu): ", __func__, len);
28
29         if (!par->spi) {
30                 dev_err(par->info->device,
31                         "%s: par->spi is unexpectedly NULL\n", __func__);
32                 return -1;
33         }
34
35         spi_message_init(&m);
36         spi_message_add_tail(&t, &m);
37         return spi_sync(par->spi, &m);
38 }
39
40 static int init_display(struct fbtft_par *par)
41 {
42         gpiod_set_value(par->gpio.dc, 1);
43
44         fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
45                       "%s()\n", __func__);
46         fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
47                       "display size %dx%d\n",
48                 par->info->var.xres,
49                 par->info->var.yres);
50
51         par->fbtftops.reset(par);
52
53         if ((par->info->var.xres == 320) && (par->info->var.yres == 240)) {
54                 /* PLL clock frequency */
55                 write_reg(par, 0x88, 0x0A);
56                 write_reg(par, 0x89, 0x02);
57                 mdelay(10);
58                 /* color deep / MCU Interface */
59                 write_reg(par, 0x10, 0x0C);
60                 /* pixel clock period  */
61                 write_reg(par, 0x04, 0x03);
62                 mdelay(1);
63                 /* horizontal settings */
64                 write_reg(par, 0x14, 0x27);
65                 write_reg(par, 0x15, 0x00);
66                 write_reg(par, 0x16, 0x05);
67                 write_reg(par, 0x17, 0x04);
68                 write_reg(par, 0x18, 0x03);
69                 /* vertical settings */
70                 write_reg(par, 0x19, 0xEF);
71                 write_reg(par, 0x1A, 0x00);
72                 write_reg(par, 0x1B, 0x05);
73                 write_reg(par, 0x1C, 0x00);
74                 write_reg(par, 0x1D, 0x0E);
75                 write_reg(par, 0x1E, 0x00);
76                 write_reg(par, 0x1F, 0x02);
77         } else if ((par->info->var.xres == 480) &&
78                    (par->info->var.yres == 272)) {
79                 /* PLL clock frequency  */
80                 write_reg(par, 0x88, 0x0A);
81                 write_reg(par, 0x89, 0x02);
82                 mdelay(10);
83                 /* color deep / MCU Interface */
84                 write_reg(par, 0x10, 0x0C);
85                 /* pixel clock period  */
86                 write_reg(par, 0x04, 0x82);
87                 mdelay(1);
88                 /* horizontal settings */
89                 write_reg(par, 0x14, 0x3B);
90                 write_reg(par, 0x15, 0x00);
91                 write_reg(par, 0x16, 0x01);
92                 write_reg(par, 0x17, 0x00);
93                 write_reg(par, 0x18, 0x05);
94                 /* vertical settings */
95                 write_reg(par, 0x19, 0x0F);
96                 write_reg(par, 0x1A, 0x01);
97                 write_reg(par, 0x1B, 0x02);
98                 write_reg(par, 0x1C, 0x00);
99                 write_reg(par, 0x1D, 0x07);
100                 write_reg(par, 0x1E, 0x00);
101                 write_reg(par, 0x1F, 0x09);
102         } else if ((par->info->var.xres == 640) &&
103                    (par->info->var.yres == 480)) {
104                 /* PLL clock frequency */
105                 write_reg(par, 0x88, 0x0B);
106                 write_reg(par, 0x89, 0x02);
107                 mdelay(10);
108                 /* color deep / MCU Interface */
109                 write_reg(par, 0x10, 0x0C);
110                 /* pixel clock period */
111                 write_reg(par, 0x04, 0x01);
112                 mdelay(1);
113                 /* horizontal settings */
114                 write_reg(par, 0x14, 0x4F);
115                 write_reg(par, 0x15, 0x05);
116                 write_reg(par, 0x16, 0x0F);
117                 write_reg(par, 0x17, 0x01);
118                 write_reg(par, 0x18, 0x00);
119                 /* vertical settings */
120                 write_reg(par, 0x19, 0xDF);
121                 write_reg(par, 0x1A, 0x01);
122                 write_reg(par, 0x1B, 0x0A);
123                 write_reg(par, 0x1C, 0x00);
124                 write_reg(par, 0x1D, 0x0E);
125                 write_reg(par, 0x1E, 0x00);
126                 write_reg(par, 0x1F, 0x01);
127         } else if ((par->info->var.xres == 800) &&
128                    (par->info->var.yres == 480)) {
129                 /* PLL clock frequency */
130                 write_reg(par, 0x88, 0x0B);
131                 write_reg(par, 0x89, 0x02);
132                 mdelay(10);
133                 /* color deep / MCU Interface */
134                 write_reg(par, 0x10, 0x0C);
135                 /* pixel clock period */
136                 write_reg(par, 0x04, 0x81);
137                 mdelay(1);
138                 /* horizontal settings */
139                 write_reg(par, 0x14, 0x63);
140                 write_reg(par, 0x15, 0x03);
141                 write_reg(par, 0x16, 0x03);
142                 write_reg(par, 0x17, 0x02);
143                 write_reg(par, 0x18, 0x00);
144                 /* vertical settings */
145                 write_reg(par, 0x19, 0xDF);
146                 write_reg(par, 0x1A, 0x01);
147                 write_reg(par, 0x1B, 0x14);
148                 write_reg(par, 0x1C, 0x00);
149                 write_reg(par, 0x1D, 0x06);
150                 write_reg(par, 0x1E, 0x00);
151                 write_reg(par, 0x1F, 0x01);
152         } else {
153                 dev_err(par->info->device, "display size is not supported!!");
154                 return -1;
155         }
156
157         /* PWM clock */
158         write_reg(par, 0x8a, 0x81);
159         write_reg(par, 0x8b, 0xFF);
160         mdelay(10);
161
162         /* Display ON */
163         write_reg(par, 0x01, 0x80);
164         mdelay(10);
165
166         return 0;
167 }
168
169 static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
170 {
171         /* Set_Active_Window */
172         write_reg(par, 0x30, xs & 0x00FF);
173         write_reg(par, 0x31, (xs & 0xFF00) >> 8);
174         write_reg(par, 0x32, ys & 0x00FF);
175         write_reg(par, 0x33, (ys & 0xFF00) >> 8);
176         write_reg(par, 0x34, (xs + xe) & 0x00FF);
177         write_reg(par, 0x35, ((xs + xe) & 0xFF00) >> 8);
178         write_reg(par, 0x36, (ys + ye) & 0x00FF);
179         write_reg(par, 0x37, ((ys + ye) & 0xFF00) >> 8);
180
181         /* Set_Memory_Write_Cursor */
182         write_reg(par, 0x46,  xs & 0xff);
183         write_reg(par, 0x47, (xs >> 8) & 0x03);
184         write_reg(par, 0x48,  ys & 0xff);
185         write_reg(par, 0x49, (ys >> 8) & 0x01);
186
187         write_reg(par, 0x02);
188 }
189
190 static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
191 {
192         va_list args;
193         int i, ret;
194         u8 *buf = par->buf;
195
196         /* slow down spi-speed for writing registers */
197         par->fbtftops.write = write_spi;
198
199         if (unlikely(par->debug & DEBUG_WRITE_REGISTER)) {
200                 va_start(args, len);
201                 for (i = 0; i < len; i++)
202                         buf[i] = (u8)va_arg(args, unsigned int);
203                 va_end(args);
204                 fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par, par->info->device,
205                                   u8, buf, len, "%s: ", __func__);
206         }
207
208         va_start(args, len);
209         *buf++ = 0x80;
210         *buf = (u8)va_arg(args, unsigned int);
211         ret = par->fbtftops.write(par, par->buf, 2);
212         if (ret < 0) {
213                 va_end(args);
214                 dev_err(par->info->device, "write() failed and returned %dn",
215                         ret);
216                 return;
217         }
218         len--;
219
220         udelay(100);
221
222         if (len) {
223                 buf = (u8 *)par->buf;
224                 *buf++ = 0x00;
225                 i = len;
226                 while (i--)
227                         *buf++ = (u8)va_arg(args, unsigned int);
228
229                 ret = par->fbtftops.write(par, par->buf, len + 1);
230                 if (ret < 0) {
231                         va_end(args);
232                         dev_err(par->info->device,
233                                 "write() failed and returned %dn", ret);
234                         return;
235                 }
236         }
237         va_end(args);
238
239         /* restore user spi-speed */
240         par->fbtftops.write = fbtft_write_spi;
241         udelay(100);
242 }
243
244 static int write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
245 {
246         u16 *vmem16;
247         __be16 *txbuf16;
248         size_t remain;
249         size_t to_copy;
250         size_t tx_array_size;
251         int i;
252         int ret = 0;
253         size_t startbyte_size = 0;
254
255         fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s(offset=%zu, len=%zu)\n",
256                       __func__, offset, len);
257
258         remain = len / 2;
259         vmem16 = (u16 *)(par->info->screen_buffer + offset);
260         tx_array_size = par->txbuf.len / 2;
261         txbuf16 = par->txbuf.buf + 1;
262         tx_array_size -= 2;
263         *(u8 *)(par->txbuf.buf) = 0x00;
264         startbyte_size = 1;
265
266         while (remain) {
267                 to_copy = min(tx_array_size, remain);
268                 dev_dbg(par->info->device, "    to_copy=%zu, remain=%zu\n",
269                         to_copy, remain - to_copy);
270
271                 for (i = 0; i < to_copy; i++)
272                         txbuf16[i] = cpu_to_be16(vmem16[i]);
273
274                 vmem16 = vmem16 + to_copy;
275                 ret = par->fbtftops.write(par, par->txbuf.buf,
276                         startbyte_size + to_copy * 2);
277                 if (ret < 0)
278                         return ret;
279                 remain -= to_copy;
280         }
281
282         return ret;
283 }
284
285 static struct fbtft_display display = {
286         .regwidth = 8,
287         .fbtftops = {
288                 .init_display = init_display,
289                 .set_addr_win = set_addr_win,
290                 .write_register = write_reg8_bus8,
291                 .write_vmem = write_vmem16_bus8,
292                 .write = write_spi,
293         },
294 };
295
296 FBTFT_REGISTER_DRIVER(DRVNAME, "raio,ra8875", &display);
297
298 MODULE_ALIAS("spi:" DRVNAME);
299 MODULE_ALIAS("platform:" DRVNAME);
300 MODULE_ALIAS("spi:ra8875");
301 MODULE_ALIAS("platform:ra8875");
302
303 MODULE_DESCRIPTION("FB driver for the RA8875 LCD Controller");
304 MODULE_AUTHOR("Pf@nne");
305 MODULE_LICENSE("GPL");