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.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=%d): ", __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 	gpio_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");
306