|
40 | 40 | #define AML_UART_TX_RST BIT(22) |
41 | 41 | #define AML_UART_RX_RST BIT(23) |
42 | 42 | #define AML_UART_CLEAR_ERR BIT(24) |
| 43 | +#define AML_UART_RX_INV BIT(25) |
| 44 | +#define AML_UART_TX_INV BIT(26) |
43 | 45 | #define AML_UART_RX_INT_EN BIT(27) |
44 | 46 | #define AML_UART_TX_INT_EN BIT(28) |
| 47 | +#define AML_UART_CTS_INV BIT(29) |
| 48 | +#define AML_UART_ERR_MASK BIT(30) |
| 49 | +#define AML_UART_RTS_INV BIT(31) |
45 | 50 | #define AML_UART_DATA_LEN_MASK (0x03 << 20) |
46 | 51 | #define AML_UART_DATA_LEN_8BIT (0x00 << 20) |
47 | 52 | #define AML_UART_DATA_LEN_7BIT (0x01 << 20) |
@@ -95,6 +100,30 @@ static unsigned int meson_uart_get_mctrl(struct uart_port *port) |
95 | 100 | return TIOCM_CTS; |
96 | 101 | } |
97 | 102 |
|
| 103 | +static void meson_uart_set_rx_invert(struct uart_port *port, bool invert_rx) |
| 104 | +{ |
| 105 | + u32 val; |
| 106 | + |
| 107 | + val = readl(port->membase + AML_UART_CONTROL); |
| 108 | + if (invert_rx) |
| 109 | + val |= AML_UART_RX_INV; |
| 110 | + else |
| 111 | + val &= ~AML_UART_RX_INV; |
| 112 | + writel(val, port->membase + AML_UART_CONTROL); |
| 113 | +} |
| 114 | + |
| 115 | +static void meson_uart_set_tx_invert(struct uart_port *port, bool invert_tx) |
| 116 | +{ |
| 117 | + u32 val; |
| 118 | + |
| 119 | + val = readl(port->membase + AML_UART_CONTROL); |
| 120 | + if (invert_tx) |
| 121 | + val |= AML_UART_TX_INV; |
| 122 | + else |
| 123 | + val &= ~AML_UART_TX_INV; |
| 124 | + writel(val, port->membase + AML_UART_CONTROL); |
| 125 | +} |
| 126 | + |
98 | 127 | static unsigned int meson_uart_tx_empty(struct uart_port *port) |
99 | 128 | { |
100 | 129 | u32 val; |
@@ -710,6 +739,7 @@ static int meson_uart_probe(struct platform_device *pdev) |
710 | 739 | int ret = 0; |
711 | 740 | int irq; |
712 | 741 | bool has_rtscts; |
| 742 | + bool invert_rx, invert_tx, invert_cts, invert_rts; |
713 | 743 |
|
714 | 744 | if (pdev->dev.of_node) |
715 | 745 | pdev->id = of_alias_get_id(pdev->dev.of_node, "serial"); |
@@ -739,6 +769,11 @@ static int meson_uart_probe(struct platform_device *pdev) |
739 | 769 | of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize); |
740 | 770 | has_rtscts = of_property_read_bool(pdev->dev.of_node, "uart-has-rtscts"); |
741 | 771 |
|
| 772 | + invert_rx = of_property_read_bool(pdev->dev.of_node, "uart-invert-rx"); |
| 773 | + invert_tx = of_property_read_bool(pdev->dev.of_node, "uart-invert-tx"); |
| 774 | + invert_cts = of_property_read_bool(pdev->dev.of_node, "uart-invert-cts"); |
| 775 | + invert_rts = of_property_read_bool(pdev->dev.of_node, "uart-invert-rts"); |
| 776 | + |
742 | 777 | if (meson_ports[pdev->id]) { |
743 | 778 | return dev_err_probe(&pdev->dev, -EBUSY, |
744 | 779 | "port %d already allocated\n", pdev->id); |
@@ -792,6 +827,9 @@ static int meson_uart_probe(struct platform_device *pdev) |
792 | 827 | if (ret) |
793 | 828 | meson_ports[pdev->id] = NULL; |
794 | 829 |
|
| 830 | + meson_uart_set_rx_invert(port, invert_rx); |
| 831 | + meson_uart_set_tx_invert(port, invert_tx); |
| 832 | + |
795 | 833 | return ret; |
796 | 834 | } |
797 | 835 |
|
|
0 commit comments