Merge branch 'org.openembedded.dev' of new.openembedded.org:openembedded into org...
[openembedded.git] / recipes / linux / linux-2.6.24 / ts72xx / ts72xx-rs485.patch
1 RS485 auto mode support ported from 2.4 (diff against 2.6.19-rc6-git10)
2
3 Signed-off-by: Petr Stetiar <ynezz@true.cz>
4
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
9 @@ -51,6 +51,7 @@
10  #include <linux/clk.h>
11  
12  #include <asm/io.h>
13 +#include <asm/hardware.h>
14  
15  #define UART_NR                8
16  
17 @@ -66,6 +67,16 @@
18  #define UART_DUMMY_RSR_RX      256
19  #define UART_PORT_SIZE         64
20  
21 +#ifdef CONFIG_MACH_TS72XX
22 +static void __iomem *ts_rs485_data9_register;
23 +static void __iomem *ts_rs485_control_register;
24 +#endif
25 +
26 +#ifdef CONFIG_MACH_TS72XX
27 +static void __iomem *ts_rs485_data9_register;
28 +static void __iomem *ts_rs485_control_register;
29 +#endif
30 +
31  /*
32   * We wrap our port structure around the generic uart_port.
33   */
34 @@ -521,6 +532,107 @@
35         return ret;
36  }
37  
38 +#ifdef CONFIG_MACH_TS72XX
39 +static int ts72xx_rs485_init(void)
40 +{
41 +       ts_rs485_data9_register = ioremap(TS72XX_RS485_DATA9_PHYS_BASE, 4096);
42 +       if (ts_rs485_data9_register == NULL) {
43 +               return -1;
44 +       }
45 +
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);
49 +               return -1;
50 +       }
51 +
52 +       return 0;
53 +}
54 +
55 +static int ts72xx_auto485(struct uart_port *port, unsigned int cmd, unsigned long *arg)
56 +{
57 +       int baud, cflag, mode;
58 +       int datalength;
59 +
60 +       mode = (int)*arg;
61 +       if (!is_rs485_installed()) {
62 +               printk("amba-pl010.c: this board does not support RS485 auto mode\n");
63 +               return -EINVAL;
64 +       }
65 +
66 +       if (port->line != 1) {
67 +               printk("amba-pl010.c: auto RS485 mode is only supported on second port (/dev/ttyAM1)\n");
68 +               return -EINVAL;
69 +       }
70 +
71 +       datalength = 8;
72 +       cflag = port->info->tty->termios->c_cflag ;
73 +       if (cflag & PARENB)
74 +               datalength++;
75 +
76 +       if (cflag & CSTOPB)
77 +               datalength++;
78 +
79 +       baud = tty_get_baud_rate(port->info->tty);
80 +
81 +       switch (cmd) {
82 +               case TIOC_SBCC485:
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);
87 +                       }
88 +                       break;
89 +               case TIOC_SBCS485:
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);
93 +                               if (datalength > 8)
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");
97 +                               switch (baud) {
98 +                                       case 9600:
99 +                                               __raw_writew(TS72XX_RS485_MODE_9600_HD, ts_rs485_control_register);
100 +                                               break;
101 +                                       case 19200:
102 +                                               __raw_writew(TS72XX_RS485_MODE_19200_HD, ts_rs485_control_register);
103 +                                               break;
104 +                                       case 57600:
105 +                                               __raw_writew(TS72XX_RS485_MODE_57600_HD, ts_rs485_control_register);
106 +                                               break;
107 +                                       case 115200:
108 +                                               __raw_writew(TS72XX_RS485_MODE_115200_HD, ts_rs485_control_register);
109 +                                               break;
110 +                                       default:
111 +                                       printk("amba-pl010.c: %d baud rate is not supported for auto RS485 mode\n", baud);
112 +                                       return -1;
113 +                               }
114 +                               if (datalength > 8)
115 +                                       __raw_writew(TS72XX_RS485_MODE_FD, ts_rs485_data9_register);
116 +                       }
117 +                       break;
118 +       }
119 +
120 +       return 0;
121 +}
122 +#endif
123 +
124 +int pl010_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg)
125 +{
126 +#ifdef CONFIG_MACH_TS72XX
127 +       switch (cmd) {
128 +               case TIOC_SBCC485:
129 +               case TIOC_SBCS485:
130 +                       return ts72xx_auto485(port, cmd, (unsigned long *)arg);
131 +                       break;
132 +               default:
133 +                       return -ENOIOCTLCMD;
134 +       }
135 +#endif
136 +       return -ENOIOCTLCMD;
137 +}
138 +
139  static struct uart_ops amba_pl010_pops = {
140         .tx_empty       = pl010_tx_empty,
141         .set_mctrl      = pl010_set_mctrl,
142 @@ -538,6 +650,7 @@
143         .request_port   = pl010_request_port,
144         .config_port    = pl010_config_port,
145         .verify_port    = pl010_verify_port,
146 +       .ioctl          = pl010_ioctl,
147  };
148  
149  static struct uart_amba_port *amba_ports[UART_NR];
150 @@ -796,6 +909,15 @@
151         ret = uart_register_driver(&amba_reg);
152         if (ret == 0) {
153                 ret = amba_driver_register(&pl010_driver);
154 +#ifdef CONFIG_MACH_TS72XX
155 +               if (!ret && is_rs485_installed()) {
156 +                       ret = ts72xx_rs485_init();
157 +                       if (ret)
158 +                               printk("amba-pl010.c: ts72xx_rs485_init() failed\n");
159 +                       else
160 +                               printk("amba-pl010.c: auto RS485 mode initialized\n");
161 +               }
162 +#endif
163                 if (ret)
164                         uart_unregister_driver(&amba_reg);
165         }
166 @@ -806,6 +928,10 @@
167  {
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);
173 +#endif
174  }
175  
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
181 @@ -59,6 +59,16 @@
182  #define TS72XX_NAND_BUSY_VIRT_BASE     0xfebfa000
183  #define TS72XX_NAND_BUSY_SIZE          0x00001000
184  
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
195  
196  #define TS72XX_RTC_INDEX_VIRT_BASE     0xfebf9000
197  #define TS72XX_RTC_INDEX_PHYS_BASE     0x10800000
198 @@ -68,6 +78,16 @@
199  #define TS72XX_RTC_DATA_PHYS_BASE      0x11700000
200  #define TS72XX_RTC_DATA_SIZE           0x00001000
201  
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
212  
213  #define TS72XX_WATCHDOG_CONTROL_PHYS_BASE      0x23800000
214  #define TS72XX_WATCHDOG_FEED_PHYS_BASE         0x23c00000
215 @@ -90,6 +110,12 @@
216         return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7260;
217  }
218  
219 +static inline int is_rs485_installed(void)
220 +{
221 +       return !!(__raw_readb(TS72XX_OPTIONS_VIRT_BASE) &
222 +                                       TS72XX_OPTIONS_COM2_RS485);
223 +}
224 +
225  static inline int is_max197_installed(void)
226  {
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
232 @@ -70,6 +70,12 @@
233  #define TIOCGICOUNT    0x545D  /* read serial port inline interrupt counts */
234  #define FIOQSIZE       0x545E
235  
236 +#define TIOC_SBCC485   0x545F /* TS72xx RTS/485 mode clear */
237 +#define TIOC_SBCS485   0x5460 /* TS72xx RTS/485 mode set */
238 +
239 +#define TIOC_SBCC485   0x545F /* TS72xx RTS/485 mode clear */
240 +#define TIOC_SBCS485   0x5460 /* TS72xx RTS/485 mode set */
241 +
242  /* Used for packet mode */
243  #define TIOCPKT_DATA            0
244  #define TIOCPKT_FLUSHREAD       1