1 RS485 auto mode support ported from 2.4 (diff against 2.6.19-rc6-git10)
3 Signed-off-by: Petr Stetiar <ynezz@true.cz>
5 Index: linux-2.6.24/drivers/serial/amba-pl010.c
6 ===================================================================
7 --- linux-2.6.24.orig/drivers/serial/amba-pl010.c 2008-01-24 23:58:37.000000000 +0100
8 +++ linux-2.6.24/drivers/serial/amba-pl010.c 2010-02-07 18:17:40.000000000 +0100
10 #include <linux/clk.h>
13 +#include <asm/hardware.h>
18 #define UART_DUMMY_RSR_RX 256
19 #define UART_PORT_SIZE 64
21 +#ifdef CONFIG_MACH_TS72XX
22 +static void __iomem *ts_rs485_data9_register;
23 +static void __iomem *ts_rs485_control_register;
26 +#ifdef CONFIG_MACH_TS72XX
27 +static void __iomem *ts_rs485_data9_register;
28 +static void __iomem *ts_rs485_control_register;
32 * We wrap our port structure around the generic uart_port.
38 +#ifdef CONFIG_MACH_TS72XX
39 +static int ts72xx_rs485_init(void)
41 + ts_rs485_data9_register = ioremap(TS72XX_RS485_DATA9_PHYS_BASE, 4096);
42 + if (ts_rs485_data9_register == NULL) {
46 + ts_rs485_control_register = ioremap(TS72XX_RS485_CONTROL_PHYS_BASE, 4096);
47 + if (ts_rs485_control_register == NULL) {
48 + iounmap(ts_rs485_data9_register);
55 +static int ts72xx_auto485(struct uart_port *port, unsigned int cmd, unsigned long *arg)
57 + int baud, cflag, mode;
61 + if (!is_rs485_installed()) {
62 + printk("amba-pl010.c: this board does not support RS485 auto mode\n");
66 + if (port->line != 1) {
67 + printk("amba-pl010.c: auto RS485 mode is only supported on second port (/dev/ttyAM1)\n");
72 + cflag = port->info->tty->termios->c_cflag ;
79 + baud = tty_get_baud_rate(port->info->tty);
83 + if ((mode & TS72XX_RS485_AUTO485FD) || (mode & TS72XX_RS485_AUTO485HD)) {
84 + printk("amba-pl010.c: unsetting auto RS485 mode\n");
85 + __raw_writew(TS72XX_RS485_MODE_RS232, ts_rs485_control_register);
86 + __raw_writew(TS72XX_RS485_MODE_RS232, ts_rs485_data9_register);
90 + if (mode & TS72XX_RS485_AUTO485FD) {
91 + printk ("amba-pl010.c: setting FULL duplex auto RS485 mode\n");
92 + __raw_writew(TS72XX_RS485_MODE_FD, ts_rs485_control_register);
94 + __raw_writew(TS72XX_RS485_MODE_FD, ts_rs485_data9_register);
95 + } else if (mode & TS72XX_RS485_AUTO485HD) {
96 + printk("amba-pl010.c: setting HALF DUPLEX auto RS485 mode\n");
99 + __raw_writew(TS72XX_RS485_MODE_9600_HD, ts_rs485_control_register);
102 + __raw_writew(TS72XX_RS485_MODE_19200_HD, ts_rs485_control_register);
105 + __raw_writew(TS72XX_RS485_MODE_57600_HD, ts_rs485_control_register);
108 + __raw_writew(TS72XX_RS485_MODE_115200_HD, ts_rs485_control_register);
111 + printk("amba-pl010.c: %d baud rate is not supported for auto RS485 mode\n", baud);
114 + if (datalength > 8)
115 + __raw_writew(TS72XX_RS485_MODE_FD, ts_rs485_data9_register);
124 +int pl010_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg)
126 +#ifdef CONFIG_MACH_TS72XX
130 + return ts72xx_auto485(port, cmd, (unsigned long *)arg);
133 + return -ENOIOCTLCMD;
136 + return -ENOIOCTLCMD;
139 static struct uart_ops amba_pl010_pops = {
140 .tx_empty = pl010_tx_empty,
141 .set_mctrl = pl010_set_mctrl,
143 .request_port = pl010_request_port,
144 .config_port = pl010_config_port,
145 .verify_port = pl010_verify_port,
146 + .ioctl = pl010_ioctl,
149 static struct uart_amba_port *amba_ports[UART_NR];
151 ret = uart_register_driver(&amba_reg);
153 ret = amba_driver_register(&pl010_driver);
154 +#ifdef CONFIG_MACH_TS72XX
155 + if (!ret && is_rs485_installed()) {
156 + ret = ts72xx_rs485_init();
158 + printk("amba-pl010.c: ts72xx_rs485_init() failed\n");
160 + printk("amba-pl010.c: auto RS485 mode initialized\n");
164 uart_unregister_driver(&amba_reg);
168 amba_driver_unregister(&pl010_driver);
169 uart_unregister_driver(&amba_reg);
170 +#ifdef CONFIG_MACH_TS72XX
171 + iounmap(ts_rs485_data9_register);
172 + iounmap(ts_rs485_control_register);
176 module_init(pl010_init);
177 Index: linux-2.6.24/include/asm-arm/arch-ep93xx/ts72xx.h
178 ===================================================================
179 --- linux-2.6.24.orig/include/asm-arm/arch-ep93xx/ts72xx.h 2010-02-07 18:03:02.000000000 +0100
180 +++ linux-2.6.24/include/asm-arm/arch-ep93xx/ts72xx.h 2010-02-07 18:03:02.000000000 +0100
182 #define TS72XX_NAND_BUSY_VIRT_BASE 0xfebfa000
183 #define TS72XX_NAND_BUSY_SIZE 0x00001000
185 +#define TS72XX_RS485_CONTROL_PHYS_BASE 0x22C00000
186 +#define TS72XX_RS485_DATA9_PHYS_BASE 0x23000000
187 +#define TS72XX_RS485_AUTO485FD 1
188 +#define TS72XX_RS485_AUTO485HD 2
189 +#define TS72XX_RS485_MODE_RS232 0x00
190 +#define TS72XX_RS485_MODE_FD 0x01
191 +#define TS72XX_RS485_MODE_9600_HD 0x04
192 +#define TS72XX_RS485_MODE_19200_HD 0x05
193 +#define TS72XX_RS485_MODE_57600_HD 0x06
194 +#define TS72XX_RS485_MODE_115200_HD 0x07
196 #define TS72XX_RTC_INDEX_VIRT_BASE 0xfebf9000
197 #define TS72XX_RTC_INDEX_PHYS_BASE 0x10800000
199 #define TS72XX_RTC_DATA_PHYS_BASE 0x11700000
200 #define TS72XX_RTC_DATA_SIZE 0x00001000
202 +#define TS72XX_RS485_CONTROL_PHYS_BASE 0x22C00000
203 +#define TS72XX_RS485_DATA9_PHYS_BASE 0x23000000
204 +#define TS72XX_RS485_AUTO485FD 1
205 +#define TS72XX_RS485_AUTO485HD 2
206 +#define TS72XX_RS485_MODE_RS232 0x00
207 +#define TS72XX_RS485_MODE_FD 0x01
208 +#define TS72XX_RS485_MODE_9600_HD 0x04
209 +#define TS72XX_RS485_MODE_19200_HD 0x05
210 +#define TS72XX_RS485_MODE_57600_HD 0x06
211 +#define TS72XX_RS485_MODE_115200_HD 0x07
213 #define TS72XX_WATCHDOG_CONTROL_PHYS_BASE 0x23800000
214 #define TS72XX_WATCHDOG_FEED_PHYS_BASE 0x23c00000
216 return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7260;
219 +static inline int is_rs485_installed(void)
221 + return !!(__raw_readb(TS72XX_OPTIONS_VIRT_BASE) &
222 + TS72XX_OPTIONS_COM2_RS485);
225 static inline int is_max197_installed(void)
227 return !!(__raw_readb(TS72XX_OPTIONS_VIRT_BASE) &
228 Index: linux-2.6.24/include/asm-arm/ioctls.h
229 ===================================================================
230 --- linux-2.6.24.orig/include/asm-arm/ioctls.h 2008-01-24 23:58:37.000000000 +0100
231 +++ linux-2.6.24/include/asm-arm/ioctls.h 2010-02-07 18:03:02.000000000 +0100
233 #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
234 #define FIOQSIZE 0x545E
236 +#define TIOC_SBCC485 0x545F /* TS72xx RTS/485 mode clear */
237 +#define TIOC_SBCS485 0x5460 /* TS72xx RTS/485 mode set */
239 +#define TIOC_SBCC485 0x545F /* TS72xx RTS/485 mode clear */
240 +#define TIOC_SBCS485 0x5460 /* TS72xx RTS/485 mode set */
242 /* Used for packet mode */
243 #define TIOCPKT_DATA 0
244 #define TIOCPKT_FLUSHREAD 1