diff options
author | Laurent Pinchart <laurentp@cse-semaphore.com> | 2008-07-24 12:36:37 -0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2008-07-28 08:48:04 -0400 |
commit | 7485d26b7e13ee8ff82adb271ac90a996c1fe830 (patch) | |
tree | 13bc7e6f30aa6cfb039e780b597f264eccf9d3df /drivers/serial | |
parent | dc2380ec8572fcd7f7e9579afc9fb223300d922f (diff) |
cpm_uart: Modem control lines support
This patch replaces the get_mctrl/set_mctrl stubs with modem control line
read/write access through the GPIO lib.
Available modem control lines are described in the device tree using GPIO
bindings. The driver expect a GPIO pin for each of the CTS, RTS, DCD, DSR,
DTR and RI signals. Unused control lines can be left out.
Signed-off-by: Laurent Pinchart <laurentp@cse-semaphore.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart.h | 10 | ||||
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart_core.c | 40 |
2 files changed, 47 insertions, 3 deletions
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index 5c76e0ae0582..5999ef5ac78e 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h | |||
@@ -50,6 +50,15 @@ | |||
50 | 50 | ||
51 | #define SCC_WAIT_CLOSING 100 | 51 | #define SCC_WAIT_CLOSING 100 |
52 | 52 | ||
53 | #define GPIO_CTS 0 | ||
54 | #define GPIO_RTS 1 | ||
55 | #define GPIO_DCD 2 | ||
56 | #define GPIO_DSR 3 | ||
57 | #define GPIO_DTR 4 | ||
58 | #define GPIO_RI 5 | ||
59 | |||
60 | #define NUM_GPIOS (GPIO_RI+1) | ||
61 | |||
53 | struct uart_cpm_port { | 62 | struct uart_cpm_port { |
54 | struct uart_port port; | 63 | struct uart_port port; |
55 | u16 rx_nrfifos; | 64 | u16 rx_nrfifos; |
@@ -82,6 +91,7 @@ struct uart_cpm_port { | |||
82 | int wait_closing; | 91 | int wait_closing; |
83 | /* value to combine with opcode to form cpm command */ | 92 | /* value to combine with opcode to form cpm command */ |
84 | u32 command; | 93 | u32 command; |
94 | int gpios[NUM_GPIOS]; | ||
85 | }; | 95 | }; |
86 | 96 | ||
87 | extern int cpm_uart_nr; | 97 | extern int cpm_uart_nr; |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index a4f86927a74b..5e0c17f71653 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -43,6 +43,8 @@ | |||
43 | #include <linux/dma-mapping.h> | 43 | #include <linux/dma-mapping.h> |
44 | #include <linux/fs_uart_pd.h> | 44 | #include <linux/fs_uart_pd.h> |
45 | #include <linux/of_platform.h> | 45 | #include <linux/of_platform.h> |
46 | #include <linux/gpio.h> | ||
47 | #include <linux/of_gpio.h> | ||
46 | 48 | ||
47 | #include <asm/io.h> | 49 | #include <asm/io.h> |
48 | #include <asm/irq.h> | 50 | #include <asm/irq.h> |
@@ -96,13 +98,41 @@ static unsigned int cpm_uart_tx_empty(struct uart_port *port) | |||
96 | 98 | ||
97 | static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | 99 | static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) |
98 | { | 100 | { |
99 | /* Whee. Do nothing. */ | 101 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
102 | |||
103 | if (pinfo->gpios[GPIO_RTS] >= 0) | ||
104 | gpio_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS)); | ||
105 | |||
106 | if (pinfo->gpios[GPIO_DTR] >= 0) | ||
107 | gpio_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR)); | ||
100 | } | 108 | } |
101 | 109 | ||
102 | static unsigned int cpm_uart_get_mctrl(struct uart_port *port) | 110 | static unsigned int cpm_uart_get_mctrl(struct uart_port *port) |
103 | { | 111 | { |
104 | /* Whee. Do nothing. */ | 112 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
105 | return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; | 113 | unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; |
114 | |||
115 | if (pinfo->gpios[GPIO_CTS] >= 0) { | ||
116 | if (gpio_get_value(pinfo->gpios[GPIO_CTS])) | ||
117 | mctrl &= ~TIOCM_CTS; | ||
118 | } | ||
119 | |||
120 | if (pinfo->gpios[GPIO_DSR] >= 0) { | ||
121 | if (gpio_get_value(pinfo->gpios[GPIO_DSR])) | ||
122 | mctrl &= ~TIOCM_DSR; | ||
123 | } | ||
124 | |||
125 | if (pinfo->gpios[GPIO_DCD] >= 0) { | ||
126 | if (gpio_get_value(pinfo->gpios[GPIO_DCD])) | ||
127 | mctrl &= ~TIOCM_CAR; | ||
128 | } | ||
129 | |||
130 | if (pinfo->gpios[GPIO_RI] >= 0) { | ||
131 | if (!gpio_get_value(pinfo->gpios[GPIO_RI])) | ||
132 | mctrl |= TIOCM_RNG; | ||
133 | } | ||
134 | |||
135 | return mctrl; | ||
106 | } | 136 | } |
107 | 137 | ||
108 | /* | 138 | /* |
@@ -991,6 +1021,7 @@ static int cpm_uart_init_port(struct device_node *np, | |||
991 | void __iomem *mem, *pram; | 1021 | void __iomem *mem, *pram; |
992 | int len; | 1022 | int len; |
993 | int ret; | 1023 | int ret; |
1024 | int i; | ||
994 | 1025 | ||
995 | data = of_get_property(np, "fsl,cpm-brg", &len); | 1026 | data = of_get_property(np, "fsl,cpm-brg", &len); |
996 | if (!data || len != 4) { | 1027 | if (!data || len != 4) { |
@@ -1050,6 +1081,9 @@ static int cpm_uart_init_port(struct device_node *np, | |||
1050 | goto out_pram; | 1081 | goto out_pram; |
1051 | } | 1082 | } |
1052 | 1083 | ||
1084 | for (i = 0; i < NUM_GPIOS; i++) | ||
1085 | pinfo->gpios[i] = of_get_gpio(np, i); | ||
1086 | |||
1053 | return cpm_uart_request_port(&pinfo->port); | 1087 | return cpm_uart_request_port(&pinfo->port); |
1054 | 1088 | ||
1055 | out_pram: | 1089 | out_pram: |