1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Probe for F81216A LPC to 4 UART |
4 | * |
5 | * Copyright (C) 2014-2016 Ricardo Ribalda, Qtechnology A/S |
6 | */ |
7 | #include <linux/module.h> |
8 | #include <linux/pci.h> |
9 | #include <linux/pnp.h> |
10 | #include <linux/kernel.h> |
11 | #include <linux/serial_core.h> |
12 | #include <linux/irq.h> |
13 | #include "8250.h" |
14 | |
15 | #define ADDR_PORT 0 |
16 | #define DATA_PORT 1 |
17 | #define EXIT_KEY 0xAA |
18 | #define CHIP_ID1 0x20 |
19 | #define CHIP_ID2 0x21 |
20 | #define CHIP_ID_F81865 0x0407 |
21 | #define CHIP_ID_F81866 0x1010 |
22 | #define CHIP_ID_F81966 0x0215 |
23 | #define CHIP_ID_F81216AD 0x1602 |
24 | #define CHIP_ID_F81216H 0x0501 |
25 | #define CHIP_ID_F81216 0x0802 |
26 | #define VENDOR_ID1 0x23 |
27 | #define VENDOR_ID1_VAL 0x19 |
28 | #define VENDOR_ID2 0x24 |
29 | #define VENDOR_ID2_VAL 0x34 |
30 | #define IO_ADDR1 0x61 |
31 | #define IO_ADDR2 0x60 |
32 | #define LDN 0x7 |
33 | |
34 | #define FINTEK_IRQ_MODE 0x70 |
35 | #define IRQ_SHARE BIT(4) |
36 | #define IRQ_MODE_MASK (BIT(6) | BIT(5)) |
37 | #define IRQ_LEVEL_LOW 0 |
38 | #define IRQ_EDGE_HIGH BIT(5) |
39 | |
40 | /* |
41 | * F81216H clock source register, the value and mask is the same with F81866, |
42 | * but it's on F0h. |
43 | * |
44 | * Clock speeds for UART (register F0h) |
45 | * 00: 1.8432MHz. |
46 | * 01: 18.432MHz. |
47 | * 10: 24MHz. |
48 | * 11: 14.769MHz. |
49 | */ |
50 | #define RS485 0xF0 |
51 | #define RTS_INVERT BIT(5) |
52 | #define RS485_URA BIT(4) |
53 | #define RXW4C_IRA BIT(3) |
54 | #define TXW4C_IRA BIT(2) |
55 | |
56 | #define FIFO_CTRL 0xF6 |
57 | #define FIFO_MODE_MASK (BIT(1) | BIT(0)) |
58 | #define FIFO_MODE_128 (BIT(1) | BIT(0)) |
59 | #define RXFTHR_MODE_MASK (BIT(5) | BIT(4)) |
60 | #define RXFTHR_MODE_4X BIT(5) |
61 | |
62 | #define F81216_LDN_LOW 0x0 |
63 | #define F81216_LDN_HIGH 0x4 |
64 | |
65 | /* |
66 | * F81866/966 registers |
67 | * |
68 | * The IRQ setting mode of F81866/966 is not the same with F81216 series. |
69 | * Level/Low: IRQ_MODE0:0, IRQ_MODE1:0 |
70 | * Edge/High: IRQ_MODE0:1, IRQ_MODE1:0 |
71 | * |
72 | * Clock speeds for UART (register F2h) |
73 | * 00: 1.8432MHz. |
74 | * 01: 18.432MHz. |
75 | * 10: 24MHz. |
76 | * 11: 14.769MHz. |
77 | */ |
78 | #define F81866_IRQ_MODE 0xf0 |
79 | #define F81866_IRQ_SHARE BIT(0) |
80 | #define F81866_IRQ_MODE0 BIT(1) |
81 | |
82 | #define F81866_FIFO_CTRL FIFO_CTRL |
83 | #define F81866_IRQ_MODE1 BIT(3) |
84 | |
85 | #define F81866_LDN_LOW 0x10 |
86 | #define F81866_LDN_HIGH 0x16 |
87 | |
88 | #define F81866_UART_CLK 0xF2 |
89 | #define F81866_UART_CLK_MASK (BIT(1) | BIT(0)) |
90 | #define F81866_UART_CLK_1_8432MHZ 0 |
91 | #define F81866_UART_CLK_14_769MHZ (BIT(1) | BIT(0)) |
92 | #define F81866_UART_CLK_18_432MHZ BIT(0) |
93 | #define F81866_UART_CLK_24MHZ BIT(1) |
94 | |
95 | struct fintek_8250 { |
96 | u16 pid; |
97 | u16 base_port; |
98 | u8 index; |
99 | u8 key; |
100 | }; |
101 | |
102 | static u8 sio_read_reg(struct fintek_8250 *pdata, u8 reg) |
103 | { |
104 | outb(value: reg, port: pdata->base_port + ADDR_PORT); |
105 | return inb(port: pdata->base_port + DATA_PORT); |
106 | } |
107 | |
108 | static void sio_write_reg(struct fintek_8250 *pdata, u8 reg, u8 data) |
109 | { |
110 | outb(value: reg, port: pdata->base_port + ADDR_PORT); |
111 | outb(value: data, port: pdata->base_port + DATA_PORT); |
112 | } |
113 | |
114 | static void sio_write_mask_reg(struct fintek_8250 *pdata, u8 reg, u8 mask, |
115 | u8 data) |
116 | { |
117 | u8 tmp; |
118 | |
119 | tmp = (sio_read_reg(pdata, reg) & ~mask) | (mask & data); |
120 | sio_write_reg(pdata, reg, data: tmp); |
121 | } |
122 | |
123 | static int fintek_8250_enter_key(u16 base_port, u8 key) |
124 | { |
125 | if (!request_muxed_region(base_port, 2, "8250_fintek" )) |
126 | return -EBUSY; |
127 | |
128 | /* Force to deactive all SuperIO in this base_port */ |
129 | outb(EXIT_KEY, port: base_port + ADDR_PORT); |
130 | |
131 | outb(value: key, port: base_port + ADDR_PORT); |
132 | outb(value: key, port: base_port + ADDR_PORT); |
133 | return 0; |
134 | } |
135 | |
136 | static void fintek_8250_exit_key(u16 base_port) |
137 | { |
138 | |
139 | outb(EXIT_KEY, port: base_port + ADDR_PORT); |
140 | release_region(base_port + ADDR_PORT, 2); |
141 | } |
142 | |
143 | static int fintek_8250_check_id(struct fintek_8250 *pdata) |
144 | { |
145 | u16 chip; |
146 | |
147 | if (sio_read_reg(pdata, VENDOR_ID1) != VENDOR_ID1_VAL) |
148 | return -ENODEV; |
149 | |
150 | if (sio_read_reg(pdata, VENDOR_ID2) != VENDOR_ID2_VAL) |
151 | return -ENODEV; |
152 | |
153 | chip = sio_read_reg(pdata, CHIP_ID1); |
154 | chip |= sio_read_reg(pdata, CHIP_ID2) << 8; |
155 | |
156 | switch (chip) { |
157 | case CHIP_ID_F81865: |
158 | case CHIP_ID_F81866: |
159 | case CHIP_ID_F81966: |
160 | case CHIP_ID_F81216AD: |
161 | case CHIP_ID_F81216H: |
162 | case CHIP_ID_F81216: |
163 | break; |
164 | default: |
165 | return -ENODEV; |
166 | } |
167 | |
168 | pdata->pid = chip; |
169 | return 0; |
170 | } |
171 | |
172 | static int fintek_8250_get_ldn_range(struct fintek_8250 *pdata, int *min, |
173 | int *max) |
174 | { |
175 | switch (pdata->pid) { |
176 | case CHIP_ID_F81966: |
177 | case CHIP_ID_F81865: |
178 | case CHIP_ID_F81866: |
179 | *min = F81866_LDN_LOW; |
180 | *max = F81866_LDN_HIGH; |
181 | return 0; |
182 | |
183 | case CHIP_ID_F81216AD: |
184 | case CHIP_ID_F81216H: |
185 | case CHIP_ID_F81216: |
186 | *min = F81216_LDN_LOW; |
187 | *max = F81216_LDN_HIGH; |
188 | return 0; |
189 | } |
190 | |
191 | return -ENODEV; |
192 | } |
193 | |
194 | static int fintek_8250_rs485_config(struct uart_port *port, struct ktermios *termios, |
195 | struct serial_rs485 *rs485) |
196 | { |
197 | uint8_t config = 0; |
198 | struct fintek_8250 *pdata = port->private_data; |
199 | |
200 | if (!pdata) |
201 | return -EINVAL; |
202 | |
203 | |
204 | if (rs485->flags & SER_RS485_ENABLED) { |
205 | /* Hardware do not support same RTS level on send and receive */ |
206 | if (!(rs485->flags & SER_RS485_RTS_ON_SEND) == |
207 | !(rs485->flags & SER_RS485_RTS_AFTER_SEND)) |
208 | return -EINVAL; |
209 | config |= RS485_URA; |
210 | } |
211 | |
212 | if (rs485->delay_rts_before_send) { |
213 | rs485->delay_rts_before_send = 1; |
214 | config |= TXW4C_IRA; |
215 | } |
216 | |
217 | if (rs485->delay_rts_after_send) { |
218 | rs485->delay_rts_after_send = 1; |
219 | config |= RXW4C_IRA; |
220 | } |
221 | |
222 | if (rs485->flags & SER_RS485_RTS_ON_SEND) |
223 | config |= RTS_INVERT; |
224 | |
225 | if (fintek_8250_enter_key(base_port: pdata->base_port, key: pdata->key)) |
226 | return -EBUSY; |
227 | |
228 | sio_write_reg(pdata, LDN, data: pdata->index); |
229 | sio_write_reg(pdata, RS485, data: config); |
230 | fintek_8250_exit_key(base_port: pdata->base_port); |
231 | |
232 | return 0; |
233 | } |
234 | |
235 | static void fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool is_level) |
236 | { |
237 | sio_write_reg(pdata, LDN, data: pdata->index); |
238 | |
239 | switch (pdata->pid) { |
240 | case CHIP_ID_F81966: |
241 | case CHIP_ID_F81866: |
242 | sio_write_mask_reg(pdata, F81866_FIFO_CTRL, F81866_IRQ_MODE1, |
243 | data: 0); |
244 | fallthrough; |
245 | case CHIP_ID_F81865: |
246 | sio_write_mask_reg(pdata, F81866_IRQ_MODE, F81866_IRQ_SHARE, |
247 | F81866_IRQ_SHARE); |
248 | sio_write_mask_reg(pdata, F81866_IRQ_MODE, F81866_IRQ_MODE0, |
249 | data: is_level ? 0 : F81866_IRQ_MODE0); |
250 | break; |
251 | |
252 | case CHIP_ID_F81216AD: |
253 | case CHIP_ID_F81216H: |
254 | case CHIP_ID_F81216: |
255 | sio_write_mask_reg(pdata, FINTEK_IRQ_MODE, IRQ_SHARE, |
256 | IRQ_SHARE); |
257 | sio_write_mask_reg(pdata, FINTEK_IRQ_MODE, IRQ_MODE_MASK, |
258 | data: is_level ? IRQ_LEVEL_LOW : IRQ_EDGE_HIGH); |
259 | break; |
260 | } |
261 | } |
262 | |
263 | static void fintek_8250_set_max_fifo(struct fintek_8250 *pdata) |
264 | { |
265 | switch (pdata->pid) { |
266 | case CHIP_ID_F81216H: /* 128Bytes FIFO */ |
267 | case CHIP_ID_F81966: |
268 | case CHIP_ID_F81866: |
269 | sio_write_mask_reg(pdata, FIFO_CTRL, |
270 | FIFO_MODE_MASK | RXFTHR_MODE_MASK, |
271 | FIFO_MODE_128 | RXFTHR_MODE_4X); |
272 | break; |
273 | |
274 | default: /* Default 16Bytes FIFO */ |
275 | break; |
276 | } |
277 | } |
278 | |
279 | static void fintek_8250_set_termios(struct uart_port *port, |
280 | struct ktermios *termios, |
281 | const struct ktermios *old) |
282 | { |
283 | struct fintek_8250 *pdata = port->private_data; |
284 | unsigned int baud = tty_termios_baud_rate(termios); |
285 | int i; |
286 | u8 reg; |
287 | static u32 baudrate_table[] = {115200, 921600, 1152000, 1500000}; |
288 | static u8 clock_table[] = { F81866_UART_CLK_1_8432MHZ, |
289 | F81866_UART_CLK_14_769MHZ, F81866_UART_CLK_18_432MHZ, |
290 | F81866_UART_CLK_24MHZ }; |
291 | |
292 | /* |
293 | * We'll use serial8250_do_set_termios() for baud = 0, otherwise It'll |
294 | * crash on baudrate_table[i] % baud with "division by zero". |
295 | */ |
296 | if (!baud) |
297 | goto exit; |
298 | |
299 | switch (pdata->pid) { |
300 | case CHIP_ID_F81216H: |
301 | reg = RS485; |
302 | break; |
303 | case CHIP_ID_F81966: |
304 | case CHIP_ID_F81866: |
305 | reg = F81866_UART_CLK; |
306 | break; |
307 | default: |
308 | /* Don't change clocksource with unknown PID */ |
309 | dev_warn(port->dev, |
310 | "%s: pid: %x Not support. use default set_termios.\n" , |
311 | __func__, pdata->pid); |
312 | goto exit; |
313 | } |
314 | |
315 | for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) { |
316 | if (baud > baudrate_table[i] || baudrate_table[i] % baud != 0) |
317 | continue; |
318 | |
319 | if (port->uartclk == baudrate_table[i] * 16) |
320 | break; |
321 | |
322 | if (fintek_8250_enter_key(base_port: pdata->base_port, key: pdata->key)) |
323 | continue; |
324 | |
325 | port->uartclk = baudrate_table[i] * 16; |
326 | |
327 | sio_write_reg(pdata, LDN, data: pdata->index); |
328 | sio_write_mask_reg(pdata, reg, F81866_UART_CLK_MASK, |
329 | data: clock_table[i]); |
330 | |
331 | fintek_8250_exit_key(base_port: pdata->base_port); |
332 | break; |
333 | } |
334 | |
335 | if (i == ARRAY_SIZE(baudrate_table)) { |
336 | baud = tty_termios_baud_rate(termios: old); |
337 | tty_termios_encode_baud_rate(termios, ibaud: baud, obaud: baud); |
338 | } |
339 | |
340 | exit: |
341 | serial8250_do_set_termios(port, termios, old); |
342 | } |
343 | |
344 | static void fintek_8250_set_termios_handler(struct uart_8250_port *uart) |
345 | { |
346 | struct fintek_8250 *pdata = uart->port.private_data; |
347 | |
348 | switch (pdata->pid) { |
349 | case CHIP_ID_F81216H: |
350 | case CHIP_ID_F81966: |
351 | case CHIP_ID_F81866: |
352 | uart->port.set_termios = fintek_8250_set_termios; |
353 | break; |
354 | |
355 | default: |
356 | break; |
357 | } |
358 | } |
359 | |
360 | static int probe_setup_port(struct fintek_8250 *pdata, |
361 | struct uart_8250_port *uart) |
362 | { |
363 | static const u16 addr[] = {0x4e, 0x2e}; |
364 | static const u8 keys[] = {0x77, 0xa0, 0x87, 0x67}; |
365 | struct irq_data *irq_data; |
366 | bool level_mode = false; |
367 | int i, j, k, min, max; |
368 | |
369 | for (i = 0; i < ARRAY_SIZE(addr); i++) { |
370 | for (j = 0; j < ARRAY_SIZE(keys); j++) { |
371 | pdata->base_port = addr[i]; |
372 | pdata->key = keys[j]; |
373 | |
374 | if (fintek_8250_enter_key(base_port: addr[i], key: keys[j])) |
375 | continue; |
376 | if (fintek_8250_check_id(pdata) || |
377 | fintek_8250_get_ldn_range(pdata, min: &min, max: &max)) { |
378 | fintek_8250_exit_key(base_port: addr[i]); |
379 | continue; |
380 | } |
381 | |
382 | for (k = min; k < max; k++) { |
383 | u16 aux; |
384 | |
385 | sio_write_reg(pdata, LDN, data: k); |
386 | aux = sio_read_reg(pdata, IO_ADDR1); |
387 | aux |= sio_read_reg(pdata, IO_ADDR2) << 8; |
388 | if (aux != uart->port.iobase) |
389 | continue; |
390 | |
391 | pdata->index = k; |
392 | |
393 | irq_data = irq_get_irq_data(irq: uart->port.irq); |
394 | if (irq_data) |
395 | level_mode = |
396 | irqd_is_level_type(d: irq_data); |
397 | |
398 | fintek_8250_set_irq_mode(pdata, is_level: level_mode); |
399 | fintek_8250_set_max_fifo(pdata); |
400 | |
401 | fintek_8250_exit_key(base_port: addr[i]); |
402 | |
403 | return 0; |
404 | } |
405 | |
406 | fintek_8250_exit_key(base_port: addr[i]); |
407 | } |
408 | } |
409 | |
410 | return -ENODEV; |
411 | } |
412 | |
413 | /* Only the first port supports delays */ |
414 | static const struct serial_rs485 fintek_8250_rs485_supported_port0 = { |
415 | .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND, |
416 | .delay_rts_before_send = 1, |
417 | .delay_rts_after_send = 1, |
418 | }; |
419 | |
420 | static const struct serial_rs485 fintek_8250_rs485_supported = { |
421 | .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND, |
422 | }; |
423 | |
424 | static void fintek_8250_set_rs485_handler(struct uart_8250_port *uart) |
425 | { |
426 | struct fintek_8250 *pdata = uart->port.private_data; |
427 | |
428 | switch (pdata->pid) { |
429 | case CHIP_ID_F81216AD: |
430 | case CHIP_ID_F81216H: |
431 | case CHIP_ID_F81966: |
432 | case CHIP_ID_F81866: |
433 | case CHIP_ID_F81865: |
434 | uart->port.rs485_config = fintek_8250_rs485_config; |
435 | if (!pdata->index) |
436 | uart->port.rs485_supported = fintek_8250_rs485_supported_port0; |
437 | else |
438 | uart->port.rs485_supported = fintek_8250_rs485_supported; |
439 | break; |
440 | |
441 | default: /* No RS485 Auto direction functional */ |
442 | break; |
443 | } |
444 | } |
445 | |
446 | int fintek_8250_probe(struct uart_8250_port *uart) |
447 | { |
448 | struct fintek_8250 *pdata; |
449 | struct fintek_8250 probe_data; |
450 | |
451 | if (probe_setup_port(pdata: &probe_data, uart)) |
452 | return -ENODEV; |
453 | |
454 | pdata = devm_kzalloc(dev: uart->port.dev, size: sizeof(*pdata), GFP_KERNEL); |
455 | if (!pdata) |
456 | return -ENOMEM; |
457 | |
458 | memcpy(pdata, &probe_data, sizeof(probe_data)); |
459 | uart->port.private_data = pdata; |
460 | fintek_8250_set_rs485_handler(uart); |
461 | fintek_8250_set_termios_handler(uart); |
462 | |
463 | return 0; |
464 | } |
465 | |