2 * Driver for Conexant Digicolor serial ports (USART)
4 * Author: Baruch Siach <baruch@tkos.co.il>
6 * Copyright (C) 2014 Paradox Innovation Ltd.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
14 #include <linux/module.h>
15 #include <linux/console.h>
16 #include <linux/serial_core.h>
17 #include <linux/serial.h>
18 #include <linux/clk.h>
20 #include <linux/tty.h>
21 #include <linux/tty_flip.h>
23 #include <linux/platform_device.h>
24 #include <linux/workqueue.h>
26 #define UA_ENABLE 0x00
27 #define UA_ENABLE_ENABLE BIT(0)
29 #define UA_CONTROL 0x01
30 #define UA_CONTROL_RX_ENABLE BIT(0)
31 #define UA_CONTROL_TX_ENABLE BIT(1)
32 #define UA_CONTROL_SOFT_RESET BIT(2)
34 #define UA_STATUS 0x02
35 #define UA_STATUS_PARITY_ERR BIT(0)
36 #define UA_STATUS_FRAME_ERR BIT(1)
37 #define UA_STATUS_OVERRUN_ERR BIT(2)
38 #define UA_STATUS_TX_READY BIT(6)
40 #define UA_CONFIG 0x03
41 #define UA_CONFIG_CHAR_LEN BIT(0)
42 #define UA_CONFIG_STOP_BITS BIT(1)
43 #define UA_CONFIG_PARITY BIT(2)
44 #define UA_CONFIG_ODD_PARITY BIT(4)
46 #define UA_EMI_REC 0x04
48 #define UA_HBAUD_LO 0x08
49 #define UA_HBAUD_HI 0x09
51 #define UA_STATUS_FIFO 0x0a
52 #define UA_STATUS_FIFO_RX_EMPTY BIT(2)
53 #define UA_STATUS_FIFO_RX_INT_ALMOST BIT(3)
54 #define UA_STATUS_FIFO_TX_FULL BIT(4)
55 #define UA_STATUS_FIFO_TX_INT_ALMOST BIT(7)
57 #define UA_CONFIG_FIFO 0x0b
58 #define UA_CONFIG_FIFO_RX_THRESH 7
59 #define UA_CONFIG_FIFO_RX_FIFO_MODE BIT(3)
60 #define UA_CONFIG_FIFO_TX_FIFO_MODE BIT(7)
62 #define UA_INTFLAG_CLEAR 0x1c
63 #define UA_INTFLAG_SET 0x1d
64 #define UA_INT_ENABLE 0x1e
65 #define UA_INT_STATUS 0x1f
67 #define UA_INT_TX BIT(0)
68 #define UA_INT_RX BIT(1)
70 #define DIGICOLOR_USART_NR 3
73 * We use the 16 bytes hardware FIFO to buffer Rx traffic. Rx interrupt is
74 * only produced when the FIFO is filled more than a certain configurable
75 * threshold. Unfortunately, there is no way to set this threshold below half
76 * FIFO. This means that we must periodically poll the FIFO status register to
77 * see whether there are waiting Rx bytes.
80 struct digicolor_port
{
81 struct uart_port port
;
82 struct delayed_work rx_poll_work
;
85 static struct uart_port
*digicolor_ports
[DIGICOLOR_USART_NR
];
87 static bool digicolor_uart_tx_full(struct uart_port
*port
)
89 return !!(readb_relaxed(port
->membase
+ UA_STATUS_FIFO
) &
90 UA_STATUS_FIFO_TX_FULL
);
93 static bool digicolor_uart_rx_empty(struct uart_port
*port
)
95 return !!(readb_relaxed(port
->membase
+ UA_STATUS_FIFO
) &
96 UA_STATUS_FIFO_RX_EMPTY
);
99 static void digicolor_uart_stop_tx(struct uart_port
*port
)
101 u8 int_enable
= readb_relaxed(port
->membase
+ UA_INT_ENABLE
);
103 int_enable
&= ~UA_INT_TX
;
104 writeb_relaxed(int_enable
, port
->membase
+ UA_INT_ENABLE
);
107 static void digicolor_uart_start_tx(struct uart_port
*port
)
109 u8 int_enable
= readb_relaxed(port
->membase
+ UA_INT_ENABLE
);
111 int_enable
|= UA_INT_TX
;
112 writeb_relaxed(int_enable
, port
->membase
+ UA_INT_ENABLE
);
115 static void digicolor_uart_stop_rx(struct uart_port
*port
)
117 u8 int_enable
= readb_relaxed(port
->membase
+ UA_INT_ENABLE
);
119 int_enable
&= ~UA_INT_RX
;
120 writeb_relaxed(int_enable
, port
->membase
+ UA_INT_ENABLE
);
123 static void digicolor_rx_poll(struct work_struct
*work
)
125 struct digicolor_port
*dp
=
126 container_of(to_delayed_work(work
),
127 struct digicolor_port
, rx_poll_work
);
129 if (!digicolor_uart_rx_empty(&dp
->port
))
130 /* force RX interrupt */
131 writeb_relaxed(UA_INT_RX
, dp
->port
.membase
+ UA_INTFLAG_SET
);
133 schedule_delayed_work(&dp
->rx_poll_work
, msecs_to_jiffies(100));
136 static void digicolor_uart_rx(struct uart_port
*port
)
140 spin_lock_irqsave(&port
->lock
, flags
);
144 unsigned int ch_flag
;
146 if (digicolor_uart_rx_empty(port
))
149 ch
= readb_relaxed(port
->membase
+ UA_EMI_REC
);
150 status
= readb_relaxed(port
->membase
+ UA_STATUS
);
153 ch_flag
= TTY_NORMAL
;
156 if (status
& UA_STATUS_PARITY_ERR
)
157 port
->icount
.parity
++;
158 else if (status
& UA_STATUS_FRAME_ERR
)
159 port
->icount
.frame
++;
160 else if (status
& UA_STATUS_OVERRUN_ERR
)
161 port
->icount
.overrun
++;
163 status
&= port
->read_status_mask
;
165 if (status
& UA_STATUS_PARITY_ERR
)
166 ch_flag
= TTY_PARITY
;
167 else if (status
& UA_STATUS_FRAME_ERR
)
169 else if (status
& UA_STATUS_OVERRUN_ERR
)
170 ch_flag
= TTY_OVERRUN
;
173 if (status
& port
->ignore_status_mask
)
176 uart_insert_char(port
, status
, UA_STATUS_OVERRUN_ERR
, ch
,
180 spin_unlock_irqrestore(&port
->lock
, flags
);
182 tty_flip_buffer_push(&port
->state
->port
);
185 static void digicolor_uart_tx(struct uart_port
*port
)
187 struct circ_buf
*xmit
= &port
->state
->xmit
;
190 if (digicolor_uart_tx_full(port
))
193 spin_lock_irqsave(&port
->lock
, flags
);
196 writeb_relaxed(port
->x_char
, port
->membase
+ UA_EMI_REC
);
202 if (uart_circ_empty(xmit
) || uart_tx_stopped(port
)) {
203 digicolor_uart_stop_tx(port
);
207 while (!uart_circ_empty(xmit
)) {
208 writeb(xmit
->buf
[xmit
->tail
], port
->membase
+ UA_EMI_REC
);
209 xmit
->tail
= (xmit
->tail
+ 1) & (UART_XMIT_SIZE
- 1);
212 if (digicolor_uart_tx_full(port
))
216 if (uart_circ_chars_pending(xmit
) < WAKEUP_CHARS
)
217 uart_write_wakeup(port
);
220 spin_unlock_irqrestore(&port
->lock
, flags
);
223 static irqreturn_t
digicolor_uart_int(int irq
, void *dev_id
)
225 struct uart_port
*port
= dev_id
;
226 u8 int_status
= readb_relaxed(port
->membase
+ UA_INT_STATUS
);
228 writeb_relaxed(UA_INT_RX
| UA_INT_TX
,
229 port
->membase
+ UA_INTFLAG_CLEAR
);
231 if (int_status
& UA_INT_RX
)
232 digicolor_uart_rx(port
);
233 if (int_status
& UA_INT_TX
)
234 digicolor_uart_tx(port
);
239 static unsigned int digicolor_uart_tx_empty(struct uart_port
*port
)
241 u8 status
= readb_relaxed(port
->membase
+ UA_STATUS
);
243 return (status
& UA_STATUS_TX_READY
) ? TIOCSER_TEMT
: 0;
246 static unsigned int digicolor_uart_get_mctrl(struct uart_port
*port
)
251 static void digicolor_uart_set_mctrl(struct uart_port
*port
, unsigned int mctrl
)
255 static void digicolor_uart_break_ctl(struct uart_port
*port
, int state
)
259 static int digicolor_uart_startup(struct uart_port
*port
)
261 struct digicolor_port
*dp
=
262 container_of(port
, struct digicolor_port
, port
);
264 writeb_relaxed(UA_ENABLE_ENABLE
, port
->membase
+ UA_ENABLE
);
265 writeb_relaxed(UA_CONTROL_SOFT_RESET
, port
->membase
+ UA_CONTROL
);
266 writeb_relaxed(0, port
->membase
+ UA_CONTROL
);
268 writeb_relaxed(UA_CONFIG_FIFO_RX_FIFO_MODE
269 | UA_CONFIG_FIFO_TX_FIFO_MODE
| UA_CONFIG_FIFO_RX_THRESH
,
270 port
->membase
+ UA_CONFIG_FIFO
);
271 writeb_relaxed(UA_STATUS_FIFO_RX_INT_ALMOST
,
272 port
->membase
+ UA_STATUS_FIFO
);
273 writeb_relaxed(UA_CONTROL_RX_ENABLE
| UA_CONTROL_TX_ENABLE
,
274 port
->membase
+ UA_CONTROL
);
275 writeb_relaxed(UA_INT_TX
| UA_INT_RX
,
276 port
->membase
+ UA_INT_ENABLE
);
278 schedule_delayed_work(&dp
->rx_poll_work
, msecs_to_jiffies(100));
283 static void digicolor_uart_shutdown(struct uart_port
*port
)
285 struct digicolor_port
*dp
=
286 container_of(port
, struct digicolor_port
, port
);
288 writeb_relaxed(0, port
->membase
+ UA_ENABLE
);
289 cancel_delayed_work_sync(&dp
->rx_poll_work
);
292 static void digicolor_uart_set_termios(struct uart_port
*port
,
293 struct ktermios
*termios
,
294 struct ktermios
*old
)
296 unsigned int baud
, divisor
;
300 /* Mask termios capabilities we don't support */
301 termios
->c_cflag
&= ~CMSPAR
;
302 termios
->c_iflag
&= ~(BRKINT
| IGNBRK
);
304 /* Limit baud rates so that we don't need the fractional divider */
305 baud
= uart_get_baud_rate(port
, termios
, old
,
306 port
->uartclk
/ (0x10000*16),
307 port
->uartclk
/ 256);
308 divisor
= uart_get_divisor(port
, baud
) - 1;
310 switch (termios
->c_cflag
& CSIZE
) {
315 config
|= UA_CONFIG_CHAR_LEN
;
319 if (termios
->c_cflag
& CSTOPB
)
320 config
|= UA_CONFIG_STOP_BITS
;
322 if (termios
->c_cflag
& PARENB
) {
323 config
|= UA_CONFIG_PARITY
;
324 if (termios
->c_cflag
& PARODD
)
325 config
|= UA_CONFIG_ODD_PARITY
;
328 /* Set read status mask */
329 port
->read_status_mask
= UA_STATUS_OVERRUN_ERR
;
330 if (termios
->c_iflag
& INPCK
)
331 port
->read_status_mask
|= UA_STATUS_PARITY_ERR
332 | UA_STATUS_FRAME_ERR
;
334 /* Set status ignore mask */
335 port
->ignore_status_mask
= 0;
336 if (!(termios
->c_cflag
& CREAD
))
337 port
->ignore_status_mask
|= UA_STATUS_OVERRUN_ERR
338 | UA_STATUS_PARITY_ERR
| UA_STATUS_FRAME_ERR
;
340 spin_lock_irqsave(&port
->lock
, flags
);
342 uart_update_timeout(port
, termios
->c_cflag
, baud
);
344 writeb_relaxed(config
, port
->membase
+ UA_CONFIG
);
345 writeb_relaxed(divisor
& 0xff, port
->membase
+ UA_HBAUD_LO
);
346 writeb_relaxed(divisor
>> 8, port
->membase
+ UA_HBAUD_HI
);
348 spin_unlock_irqrestore(&port
->lock
, flags
);
351 static const char *digicolor_uart_type(struct uart_port
*port
)
353 return (port
->type
== PORT_DIGICOLOR
) ? "DIGICOLOR USART" : NULL
;
356 static void digicolor_uart_config_port(struct uart_port
*port
, int flags
)
358 if (flags
& UART_CONFIG_TYPE
)
359 port
->type
= PORT_DIGICOLOR
;
362 static void digicolor_uart_release_port(struct uart_port
*port
)
366 static int digicolor_uart_request_port(struct uart_port
*port
)
371 static const struct uart_ops digicolor_uart_ops
= {
372 .tx_empty
= digicolor_uart_tx_empty
,
373 .set_mctrl
= digicolor_uart_set_mctrl
,
374 .get_mctrl
= digicolor_uart_get_mctrl
,
375 .stop_tx
= digicolor_uart_stop_tx
,
376 .start_tx
= digicolor_uart_start_tx
,
377 .stop_rx
= digicolor_uart_stop_rx
,
378 .break_ctl
= digicolor_uart_break_ctl
,
379 .startup
= digicolor_uart_startup
,
380 .shutdown
= digicolor_uart_shutdown
,
381 .set_termios
= digicolor_uart_set_termios
,
382 .type
= digicolor_uart_type
,
383 .config_port
= digicolor_uart_config_port
,
384 .release_port
= digicolor_uart_release_port
,
385 .request_port
= digicolor_uart_request_port
,
388 static void digicolor_uart_console_putchar(struct uart_port
*port
, int ch
)
390 while (digicolor_uart_tx_full(port
))
393 writeb_relaxed(ch
, port
->membase
+ UA_EMI_REC
);
396 static void digicolor_uart_console_write(struct console
*co
, const char *c
,
399 struct uart_port
*port
= digicolor_ports
[co
->index
];
404 if (oops_in_progress
)
405 locked
= spin_trylock_irqsave(&port
->lock
, flags
);
407 spin_lock_irqsave(&port
->lock
, flags
);
409 uart_console_write(port
, c
, n
, digicolor_uart_console_putchar
);
412 spin_unlock_irqrestore(&port
->lock
, flags
);
414 /* Wait for transmitter to become empty */
416 status
= readb_relaxed(port
->membase
+ UA_STATUS
);
417 } while ((status
& UA_STATUS_TX_READY
) == 0);
420 static int digicolor_uart_console_setup(struct console
*co
, char *options
)
422 int baud
= 115200, bits
= 8, parity
= 'n', flow
= 'n';
423 struct uart_port
*port
;
425 if (co
->index
< 0 || co
->index
>= DIGICOLOR_USART_NR
)
428 port
= digicolor_ports
[co
->index
];
433 uart_parse_options(options
, &baud
, &parity
, &bits
, &flow
);
435 return uart_set_options(port
, co
, baud
, parity
, bits
, flow
);
438 static struct console digicolor_console
= {
440 .device
= uart_console_device
,
441 .write
= digicolor_uart_console_write
,
442 .setup
= digicolor_uart_console_setup
,
443 .flags
= CON_PRINTBUFFER
,
447 static struct uart_driver digicolor_uart
= {
448 .driver_name
= "digicolor-usart",
450 .nr
= DIGICOLOR_USART_NR
,
453 static int digicolor_uart_probe(struct platform_device
*pdev
)
455 struct device_node
*np
= pdev
->dev
.of_node
;
457 struct digicolor_port
*dp
;
458 struct resource
*res
;
459 struct clk
*uart_clk
;
462 dev_err(&pdev
->dev
, "Missing device tree node\n");
466 index
= of_alias_get_id(np
, "serial");
467 if (index
< 0 || index
>= DIGICOLOR_USART_NR
)
470 dp
= devm_kzalloc(&pdev
->dev
, sizeof(*dp
), GFP_KERNEL
);
474 uart_clk
= devm_clk_get(&pdev
->dev
, NULL
);
475 if (IS_ERR(uart_clk
))
476 return PTR_ERR(uart_clk
);
478 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
479 dp
->port
.mapbase
= res
->start
;
480 dp
->port
.membase
= devm_ioremap_resource(&pdev
->dev
, res
);
481 if (IS_ERR(dp
->port
.membase
))
482 return PTR_ERR(dp
->port
.membase
);
484 irq
= platform_get_irq(pdev
, 0);
489 dp
->port
.iotype
= UPIO_MEM
;
490 dp
->port
.uartclk
= clk_get_rate(uart_clk
);
491 dp
->port
.fifosize
= 16;
492 dp
->port
.dev
= &pdev
->dev
;
493 dp
->port
.ops
= &digicolor_uart_ops
;
494 dp
->port
.line
= index
;
495 dp
->port
.type
= PORT_DIGICOLOR
;
496 spin_lock_init(&dp
->port
.lock
);
498 digicolor_ports
[index
] = &dp
->port
;
499 platform_set_drvdata(pdev
, &dp
->port
);
501 INIT_DELAYED_WORK(&dp
->rx_poll_work
, digicolor_rx_poll
);
503 ret
= devm_request_irq(&pdev
->dev
, dp
->port
.irq
, digicolor_uart_int
, 0,
504 dev_name(&pdev
->dev
), &dp
->port
);
508 return uart_add_one_port(&digicolor_uart
, &dp
->port
);
511 static int digicolor_uart_remove(struct platform_device
*pdev
)
513 struct uart_port
*port
= platform_get_drvdata(pdev
);
515 uart_remove_one_port(&digicolor_uart
, port
);
520 static const struct of_device_id digicolor_uart_dt_ids
[] = {
521 { .compatible
= "cnxt,cx92755-usart", },
524 MODULE_DEVICE_TABLE(of
, digicolor_uart_dt_ids
);
526 static struct platform_driver digicolor_uart_platform
= {
528 .name
= "digicolor-usart",
529 .of_match_table
= of_match_ptr(digicolor_uart_dt_ids
),
531 .probe
= digicolor_uart_probe
,
532 .remove
= digicolor_uart_remove
,
535 static int __init
digicolor_uart_init(void)
539 if (IS_ENABLED(CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE
)) {
540 digicolor_uart
.cons
= &digicolor_console
;
541 digicolor_console
.data
= &digicolor_uart
;
544 ret
= uart_register_driver(&digicolor_uart
);
548 return platform_driver_register(&digicolor_uart_platform
);
550 module_init(digicolor_uart_init
);
552 static void __exit
digicolor_uart_exit(void)
554 platform_driver_unregister(&digicolor_uart_platform
);
555 uart_unregister_driver(&digicolor_uart
);
557 module_exit(digicolor_uart_exit
);
559 MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
560 MODULE_DESCRIPTION("Conexant Digicolor USART serial driver");
561 MODULE_LICENSE("GPL");