aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorCraig Shelley <craig@microtron.org.uk>2005-05-26 19:09:56 -0400
committerGreg KH <gregkh@suse.de>2005-06-03 03:04:30 -0400
commit39a66b8d22a36cfa1a48f7f59c6a4639d9c99653 (patch)
tree23cb1c8ea41f28bb5778027e3feb5a0e9c444568 /drivers/usb
parent719df469cb51199316ae2a11c75a8046be34b899 (diff)
[PATCH] USB: CP2101 Add support for flow control
Added support to get/set flow control line levels using TIOCMGET and TIOCMSET. Added support for RTSCTS hardware flow control. cp2101_get_config and cp2101_set_config modified to support long request strings, required for configuring flow control. Signed-off-by: Craig Shelley craig@microtron.org.uk Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/cp2101.c363
1 files changed, 275 insertions, 88 deletions
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index 7e9bb63eb466..4ace9964fc6b 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -7,6 +7,14 @@
7 * modify it under the terms of the GNU General Public License version 7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation. 8 * 2 as published by the Free Software Foundation.
9 * 9 *
10 * Support to set flow control line levels using TIOCMGET and TIOCMSET
11 * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow
12 * control thanks to Munir Nassar nassarmu@real-time.com
13 *
14 * Outstanding Issues:
15 * Buffers are not flushed when the port is opened.
16 * Multiple calls to write() may fail with "Resource temporarily unavailable"
17 *
10 */ 18 */
11 19
12#include <linux/config.h> 20#include <linux/config.h>
@@ -24,7 +32,7 @@
24/* 32/*
25 * Version Information 33 * Version Information
26 */ 34 */
27#define DRIVER_VERSION "v0.03" 35#define DRIVER_VERSION "v0.04"
28#define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" 36#define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver"
29 37
30/* 38/*
@@ -35,6 +43,9 @@ static void cp2101_cleanup(struct usb_serial_port*);
35static void cp2101_close(struct usb_serial_port*, struct file*); 43static void cp2101_close(struct usb_serial_port*, struct file*);
36static void cp2101_get_termios(struct usb_serial_port*); 44static void cp2101_get_termios(struct usb_serial_port*);
37static void cp2101_set_termios(struct usb_serial_port*, struct termios*); 45static void cp2101_set_termios(struct usb_serial_port*, struct termios*);
46static int cp2101_tiocmget (struct usb_serial_port *, struct file *);
47static int cp2101_tiocmset (struct usb_serial_port *, struct file *,
48 unsigned int, unsigned int);
38static void cp2101_break_ctl(struct usb_serial_port*, int); 49static void cp2101_break_ctl(struct usb_serial_port*, int);
39static int cp2101_startup (struct usb_serial *); 50static int cp2101_startup (struct usb_serial *);
40static void cp2101_shutdown(struct usb_serial*); 51static void cp2101_shutdown(struct usb_serial*);
@@ -43,9 +54,10 @@ static void cp2101_shutdown(struct usb_serial*);
43static int debug; 54static int debug;
44 55
45static struct usb_device_id id_table [] = { 56static struct usb_device_id id_table [] = {
46 {USB_DEVICE(0x10c4, 0xea60) }, /*Silicon labs factory default*/ 57 { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
47 {USB_DEVICE(0x10ab, 0x10c5) }, /*Siemens MC60 Cable*/ 58 { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
48 { } /* Terminating Entry*/ 59 { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
60 { } /* Terminating Entry */
49}; 61};
50 62
51MODULE_DEVICE_TABLE (usb, id_table); 63MODULE_DEVICE_TABLE (usb, id_table);
@@ -70,32 +82,35 @@ static struct usb_serial_device_type cp2101_device = {
70 .close = cp2101_close, 82 .close = cp2101_close,
71 .break_ctl = cp2101_break_ctl, 83 .break_ctl = cp2101_break_ctl,
72 .set_termios = cp2101_set_termios, 84 .set_termios = cp2101_set_termios,
85 .tiocmget = cp2101_tiocmget,
86 .tiocmset = cp2101_tiocmset,
73 .attach = cp2101_startup, 87 .attach = cp2101_startup,
74 .shutdown = cp2101_shutdown, 88 .shutdown = cp2101_shutdown,
75}; 89};
76 90
77/*Config request types*/ 91/* Config request types */
78#define REQTYPE_HOST_TO_DEVICE 0x41 92#define REQTYPE_HOST_TO_DEVICE 0x41
79#define REQTYPE_DEVICE_TO_HOST 0xc1 93#define REQTYPE_DEVICE_TO_HOST 0xc1
80 94
81/*Config SET requests. To GET, add 1 to the request number*/ 95/* Config SET requests. To GET, add 1 to the request number */
82#define CP2101_UART 0x00 /*Enable / Disable*/ 96#define CP2101_UART 0x00 /* Enable / Disable */
83#define CP2101_BAUDRATE 0x01 /*(BAUD_RATE_GEN_FREQ / baudrate)*/ 97#define CP2101_BAUDRATE 0x01 /* (BAUD_RATE_GEN_FREQ / baudrate) */
84#define CP2101_BITS 0x03 /*0x(0)(data bits)(parity)(stop bits)*/ 98#define CP2101_BITS 0x03 /* 0x(0)(databits)(parity)(stopbits) */
85#define CP2101_BREAK 0x05 /*On / Off*/ 99#define CP2101_BREAK 0x05 /* On / Off */
86#define CP2101_DTRRTS 0x07 /*101 / 202 ???*/ 100#define CP2101_CONTROL 0x07 /* Flow control line states */
87#define CP2101_CONFIG_16 0x13 /*16 bytes of config data ???*/ 101#define CP2101_MODEMCTL 0x13 /* Modem controls */
88#define CP2101_CONFIG_6 0x19 /*6 bytes of config data ???*/ 102#define CP2101_CONFIG_6 0x19 /* 6 bytes of config data ??? */
89 103
90/*CP2101_UART*/ 104/* CP2101_UART */
91#define UART_ENABLE 0x0001 105#define UART_ENABLE 0x0001
92#define UART_DISABLE 0x0000 106#define UART_DISABLE 0x0000
93 107
94/*CP2101_BAUDRATE*/ 108/* CP2101_BAUDRATE */
95#define BAUD_RATE_GEN_FREQ 0x384000 109#define BAUD_RATE_GEN_FREQ 0x384000
96 110
97/*CP2101_BITS*/ 111/* CP2101_BITS */
98#define BITS_DATA_MASK 0X0f00 112#define BITS_DATA_MASK 0X0f00
113#define BITS_DATA_5 0X0500
99#define BITS_DATA_6 0X0600 114#define BITS_DATA_6 0X0600
100#define BITS_DATA_7 0X0700 115#define BITS_DATA_7 0X0700
101#define BITS_DATA_8 0X0800 116#define BITS_DATA_8 0X0800
@@ -112,64 +127,137 @@ static struct usb_serial_device_type cp2101_device = {
112#define BITS_STOP_1 0x0000 127#define BITS_STOP_1 0x0000
113#define BITS_STOP_1_5 0x0001 128#define BITS_STOP_1_5 0x0001
114#define BITS_STOP_2 0x0002 129#define BITS_STOP_2 0x0002
130
131/* CP2101_BREAK */
115#define BREAK_ON 0x0000 132#define BREAK_ON 0x0000
116#define BREAK_OFF 0x0001 133#define BREAK_OFF 0x0001
117 134
135/* CP2101_CONTROL */
136#define CONTROL_DTR 0x0001
137#define CONTROL_RTS 0x0002
138#define CONTROL_CTS 0x0010
139#define CONTROL_DSR 0x0020
140#define CONTROL_RING 0x0040
141#define CONTROL_DCD 0x0080
142#define CONTROL_WRITE_DTR 0x0100
143#define CONTROL_WRITE_RTS 0x0200
118 144
119static int cp2101_get_config(struct usb_serial_port* port, u8 request) 145/*
146 * cp2101_get_config
147 * Reads from the CP2101 configuration registers
148 * 'size' is specified in bytes.
149 * 'data' is a pointer to a pre-allocated array of integers large
150 * enough to hold 'size' bytes (with 4 bytes to each integer)
151 */
152static int cp2101_get_config(struct usb_serial_port* port, u8 request,
153 unsigned int *data, int size)
120{ 154{
121 struct usb_serial *serial = port->serial; 155 struct usb_serial *serial = port->serial;
122 unsigned char buf[4]; 156 u32 *buf;
123 unsigned int value; 157 int result, i, length;
124 int result, i; 158
159 /* Number of integers required to contain the array */
160 length = (((size - 1) | 3) + 1)/4;
161
162 buf = kmalloc (length * sizeof(u32), GFP_KERNEL);
163 memset(buf, 0, length * sizeof(u32));
164
165 if (!buf) {
166 dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__);
167 return -ENOMEM;
168 }
125 169
126 /*For get requests, the request number must be incremented*/ 170 /* For get requests, the request number must be incremented */
127 request++; 171 request++;
128 172
129 /*Issue the request, attempting to read 4 bytes*/ 173 /* Issue the request, attempting to read 'size' bytes */
130 result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0), 174 result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0),
131 request, REQTYPE_DEVICE_TO_HOST, 0x0000, 175 request, REQTYPE_DEVICE_TO_HOST, 0x0000,
132 0, buf, 4, 300); 176 0, buf, size, 300);
133 177
134 if (result < 0) { 178 /* Convert data into an array of integers */
135 dev_err(&port->dev, "%s - Unable to send config request, " 179 for (i=0; i<length; i++)
136 "request=0x%x result=%d\n", 180 data[i] = le32_to_cpu(buf[i]);
137 __FUNCTION__, request, result);
138 return result;
139 }
140 181
141 /*Assemble each byte read into an integer value*/ 182 kfree(buf);
142 value = 0;
143 for (i=0; i<4 && i<result; i++)
144 value |= (buf[i] << (i * 8));
145 183
146 dbg( " %s - request=0x%x result=%d value=0x%x", 184 if (result != size) {
147 __FUNCTION__, request, result, value); 185 dev_err(&port->dev, "%s - Unable to send config request, "
186 "request=0x%x size=%d result=%d\n",
187 __FUNCTION__, request, size, result);
188 return -EPROTO;
189 }
148 190
149 return value; 191 return 0;
150} 192}
151 193
152static int cp2101_set_config(struct usb_serial_port* port, u8 request, u16 value) 194/*
195 * cp2101_set_config
196 * Writes to the CP2101 configuration registers
197 * Values less than 16 bits wide are sent directly
198 * 'size' is specified in bytes.
199 */
200static int cp2101_set_config(struct usb_serial_port* port, u8 request,
201 unsigned int *data, int size)
153{ 202{
154 struct usb_serial *serial = port->serial; 203 struct usb_serial *serial = port->serial;
155 int result; 204 u32 *buf;
156 result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), 205 int result, i, length;
157 request, REQTYPE_HOST_TO_DEVICE, value,
158 0, NULL, 0, 300);
159 206
160 if (result <0) { 207 /* Number of integers required to contain the array */
161 dev_err(&port->dev, "%s - Unable to send config request, " 208 length = (((size - 1) | 3) + 1)/4;
162 "request=0x%x value=0x%x result=%d\n", 209
163 __FUNCTION__, request, value, result); 210 buf = kmalloc(length * sizeof(u32), GFP_KERNEL);
164 return result; 211 if (!buf) {
212 dev_err(&port->dev, "%s - out of memory.\n",
213 __FUNCTION__);
214 return -ENOMEM;
215 }
216
217 /* Array of integers into bytes */
218 for (i = 0; i < length; i++)
219 buf[i] = cpu_to_le32(data[i]);
220
221 if (size > 2) {
222 result = usb_control_msg (serial->dev,
223 usb_sndctrlpipe(serial->dev, 0),
224 request, REQTYPE_HOST_TO_DEVICE, 0x0000,
225 0, buf, size, 300);
226 } else {
227 result = usb_control_msg (serial->dev,
228 usb_sndctrlpipe(serial->dev, 0),
229 request, REQTYPE_HOST_TO_DEVICE, data[0],
230 0, NULL, 0, 300);
165 } 231 }
166 232
167 dbg(" %s - request=0x%x value=0x%x result=%d", 233 kfree(buf);
168 __FUNCTION__, request, value, result); 234
235 if ((size > 2 && result != size) || result < 0) {
236 dev_err(&port->dev, "%s - Unable to send request, "
237 "request=0x%x size=%d result=%d\n",
238 __FUNCTION__, request, size, result);
239 return -EPROTO;
240 }
169 241
242 /* Single data value */
243 result = usb_control_msg (serial->dev,
244 usb_sndctrlpipe(serial->dev, 0),
245 request, REQTYPE_HOST_TO_DEVICE, data[0],
246 0, NULL, 0, 300);
170 return 0; 247 return 0;
171} 248}
172 249
250/*
251 * cp2101_set_config_single
252 * Convenience function for calling cp2101_set_config on single data values
253 * without requiring an integer pointer
254 */
255static inline int cp2101_set_config_single(struct usb_serial_port* port,
256 u8 request, unsigned int data)
257{
258 return cp2101_set_config(port, request, &data, 2);
259}
260
173static int cp2101_open (struct usb_serial_port *port, struct file *filp) 261static int cp2101_open (struct usb_serial_port *port, struct file *filp)
174{ 262{
175 struct usb_serial *serial = port->serial; 263 struct usb_serial *serial = port->serial;
@@ -177,7 +265,7 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp)
177 265
178 dbg("%s - port %d", __FUNCTION__, port->number); 266 dbg("%s - port %d", __FUNCTION__, port->number);
179 267
180 if (cp2101_set_config(port, CP2101_UART, UART_ENABLE)) { 268 if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) {
181 dev_err(&port->dev, "%s - Unable to enable UART\n", 269 dev_err(&port->dev, "%s - Unable to enable UART\n",
182 __FUNCTION__); 270 __FUNCTION__);
183 return -EPROTO; 271 return -EPROTO;
@@ -198,9 +286,12 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp)
198 return result; 286 return result;
199 } 287 }
200 288
201 /*Configure the termios structure*/ 289 /* Configure the termios structure */
202 cp2101_get_termios(port); 290 cp2101_get_termios(port);
203 291
292 /* Set the DTR and RTS pins low */
293 cp2101_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0);
294
204 return 0; 295 return 0;
205} 296}
206 297
@@ -228,16 +319,18 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp)
228 usb_kill_urb(port->write_urb); 319 usb_kill_urb(port->write_urb);
229 usb_kill_urb(port->read_urb); 320 usb_kill_urb(port->read_urb);
230 321
231 cp2101_set_config(port, CP2101_UART, UART_DISABLE); 322 cp2101_set_config_single(port, CP2101_UART, UART_DISABLE);
232} 323}
233 324
234/* cp2101_get_termios*/ 325/*
235/* Reads the baud rate, data bits, parity and stop bits from the device*/ 326 * cp2101_get_termios
236/* Corrects any unsupported values*/ 327 * Reads the baud rate, data bits, parity, stop bits and flow control mode
237/* Configures the termios structure to reflect the state of the device*/ 328 * from the device, corrects any unsupported values, and configures the
329 * termios structure to reflect the state of the device
330 */
238static void cp2101_get_termios (struct usb_serial_port *port) 331static void cp2101_get_termios (struct usb_serial_port *port)
239{ 332{
240 unsigned int cflag; 333 unsigned int cflag, modem_ctl[4];
241 int baud; 334 int baud;
242 int bits; 335 int bits;
243 336
@@ -249,15 +342,16 @@ static void cp2101_get_termios (struct usb_serial_port *port)
249 } 342 }
250 cflag = port->tty->termios->c_cflag; 343 cflag = port->tty->termios->c_cflag;
251 344
252 baud = cp2101_get_config(port, CP2101_BAUDRATE); 345 cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
253 /*Convert to baudrate*/ 346 /* Convert to baudrate */
254 if (baud) 347 if (baud)
255 baud = BAUD_RATE_GEN_FREQ / baud; 348 baud = BAUD_RATE_GEN_FREQ / baud;
256 349
257 dbg("%s - baud rate = %d", __FUNCTION__, baud); 350 dbg("%s - baud rate = %d", __FUNCTION__, baud);
258 cflag &= ~CBAUD; 351 cflag &= ~CBAUD;
259 switch (baud) { 352 switch (baud) {
260 /* The baud rates which are commented out below 353 /*
354 * The baud rates which are commented out below
261 * appear to be supported by the device 355 * appear to be supported by the device
262 * but are non-standard 356 * but are non-standard
263 */ 357 */
@@ -284,14 +378,18 @@ static void cp2101_get_termios (struct usb_serial_port *port)
284 dbg("%s - Baud rate is not supported, " 378 dbg("%s - Baud rate is not supported, "
285 "using 9600 baud", __FUNCTION__); 379 "using 9600 baud", __FUNCTION__);
286 cflag |= B9600; 380 cflag |= B9600;
287 cp2101_set_config(port, CP2101_BAUDRATE, 381 cp2101_set_config_single(port, CP2101_BAUDRATE,
288 (BAUD_RATE_GEN_FREQ/9600)); 382 (BAUD_RATE_GEN_FREQ/9600));
289 break; 383 break;
290 } 384 }
291 385
292 bits = cp2101_get_config(port, CP2101_BITS); 386 cp2101_get_config(port, CP2101_BITS, &bits, 2);
293 cflag &= ~CSIZE; 387 cflag &= ~CSIZE;
294 switch(bits & BITS_DATA_MASK) { 388 switch(bits & BITS_DATA_MASK) {
389 case BITS_DATA_5:
390 dbg("%s - data bits = 5", __FUNCTION__);
391 cflag |= CS5;
392 break;
295 case BITS_DATA_6: 393 case BITS_DATA_6:
296 dbg("%s - data bits = 6", __FUNCTION__); 394 dbg("%s - data bits = 6", __FUNCTION__);
297 cflag |= CS6; 395 cflag |= CS6;
@@ -310,7 +408,7 @@ static void cp2101_get_termios (struct usb_serial_port *port)
310 cflag |= CS8; 408 cflag |= CS8;
311 bits &= ~BITS_DATA_MASK; 409 bits &= ~BITS_DATA_MASK;
312 bits |= BITS_DATA_8; 410 bits |= BITS_DATA_8;
313 cp2101_set_config(port, CP2101_BITS, bits); 411 cp2101_set_config(port, CP2101_BITS, &bits, 2);
314 break; 412 break;
315 default: 413 default:
316 dbg("%s - Unknown number of data bits, " 414 dbg("%s - Unknown number of data bits, "
@@ -318,7 +416,7 @@ static void cp2101_get_termios (struct usb_serial_port *port)
318 cflag |= CS8; 416 cflag |= CS8;
319 bits &= ~BITS_DATA_MASK; 417 bits &= ~BITS_DATA_MASK;
320 bits |= BITS_DATA_8; 418 bits |= BITS_DATA_8;
321 cp2101_set_config(port, CP2101_BITS, bits); 419 cp2101_set_config(port, CP2101_BITS, &bits, 2);
322 break; 420 break;
323 } 421 }
324 422
@@ -341,21 +439,21 @@ static void cp2101_get_termios (struct usb_serial_port *port)
341 "disabling parity)", __FUNCTION__); 439 "disabling parity)", __FUNCTION__);
342 cflag &= ~PARENB; 440 cflag &= ~PARENB;
343 bits &= ~BITS_PARITY_MASK; 441 bits &= ~BITS_PARITY_MASK;
344 cp2101_set_config(port, CP2101_BITS, bits); 442 cp2101_set_config(port, CP2101_BITS, &bits, 2);
345 break; 443 break;
346 case BITS_PARITY_SPACE: 444 case BITS_PARITY_SPACE:
347 dbg("%s - parity = SPACE (not supported, " 445 dbg("%s - parity = SPACE (not supported, "
348 "disabling parity)", __FUNCTION__); 446 "disabling parity)", __FUNCTION__);
349 cflag &= ~PARENB; 447 cflag &= ~PARENB;
350 bits &= ~BITS_PARITY_MASK; 448 bits &= ~BITS_PARITY_MASK;
351 cp2101_set_config(port, CP2101_BITS, bits); 449 cp2101_set_config(port, CP2101_BITS, &bits, 2);
352 break; 450 break;
353 default: 451 default:
354 dbg("%s - Unknown parity mode, " 452 dbg("%s - Unknown parity mode, "
355 "disabling parity", __FUNCTION__); 453 "disabling parity", __FUNCTION__);
356 cflag &= ~PARENB; 454 cflag &= ~PARENB;
357 bits &= ~BITS_PARITY_MASK; 455 bits &= ~BITS_PARITY_MASK;
358 cp2101_set_config(port, CP2101_BITS, bits); 456 cp2101_set_config(port, CP2101_BITS, &bits, 2);
359 break; 457 break;
360 } 458 }
361 459
@@ -366,9 +464,9 @@ static void cp2101_get_termios (struct usb_serial_port *port)
366 break; 464 break;
367 case BITS_STOP_1_5: 465 case BITS_STOP_1_5:
368 dbg("%s - stop bits = 1.5 (not supported, " 466 dbg("%s - stop bits = 1.5 (not supported, "
369 "using 1 stop bit", __FUNCTION__); 467 "using 1 stop bit)", __FUNCTION__);
370 bits &= ~BITS_STOP_MASK; 468 bits &= ~BITS_STOP_MASK;
371 cp2101_set_config(port, CP2101_BITS, bits); 469 cp2101_set_config(port, CP2101_BITS, &bits, 2);
372 break; 470 break;
373 case BITS_STOP_2: 471 case BITS_STOP_2:
374 dbg("%s - stop bits = 2", __FUNCTION__); 472 dbg("%s - stop bits = 2", __FUNCTION__);
@@ -378,10 +476,19 @@ static void cp2101_get_termios (struct usb_serial_port *port)
378 dbg("%s - Unknown number of stop bits, " 476 dbg("%s - Unknown number of stop bits, "
379 "using 1 stop bit", __FUNCTION__); 477 "using 1 stop bit", __FUNCTION__);
380 bits &= ~BITS_STOP_MASK; 478 bits &= ~BITS_STOP_MASK;
381 cp2101_set_config(port, CP2101_BITS, bits); 479 cp2101_set_config(port, CP2101_BITS, &bits, 2);
382 break; 480 break;
383 } 481 }
384 482
483 cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16);
484 if (modem_ctl[0] & 0x0008) {
485 dbg("%s - flow control = CRTSCTS", __FUNCTION__);
486 cflag |= CRTSCTS;
487 } else {
488 dbg("%s - flow control = NONE", __FUNCTION__);
489 cflag &= ~CRTSCTS;
490 }
491
385 port->tty->termios->c_cflag = cflag; 492 port->tty->termios->c_cflag = cflag;
386} 493}
387 494
@@ -389,8 +496,8 @@ static void cp2101_set_termios (struct usb_serial_port *port,
389 struct termios *old_termios) 496 struct termios *old_termios)
390{ 497{
391 unsigned int cflag, old_cflag=0; 498 unsigned int cflag, old_cflag=0;
392 int baud=0; 499 int baud=0, bits;
393 int bits; 500 unsigned int modem_ctl[4];
394 501
395 dbg("%s - port %d", __FUNCTION__, port->number); 502 dbg("%s - port %d", __FUNCTION__, port->number);
396 503
@@ -400,7 +507,7 @@ static void cp2101_set_termios (struct usb_serial_port *port,
400 } 507 }
401 cflag = port->tty->termios->c_cflag; 508 cflag = port->tty->termios->c_cflag;
402 509
403 /* check that they really want us to change something */ 510 /* Check that they really want us to change something */
404 if (old_termios) { 511 if (old_termios) {
405 if ((cflag == old_termios->c_cflag) && 512 if ((cflag == old_termios->c_cflag) &&
406 (RELEVANT_IFLAG(port->tty->termios->c_iflag) 513 (RELEVANT_IFLAG(port->tty->termios->c_iflag)
@@ -415,7 +522,8 @@ static void cp2101_set_termios (struct usb_serial_port *port,
415 /* If the baud rate is to be updated*/ 522 /* If the baud rate is to be updated*/
416 if ((cflag & CBAUD) != (old_cflag & CBAUD)) { 523 if ((cflag & CBAUD) != (old_cflag & CBAUD)) {
417 switch (cflag & CBAUD) { 524 switch (cflag & CBAUD) {
418 /* The baud rates which are commented out below 525 /*
526 * The baud rates which are commented out below
419 * appear to be supported by the device 527 * appear to be supported by the device
420 * but are non-standard 528 * but are non-standard
421 */ 529 */
@@ -448,18 +556,22 @@ static void cp2101_set_termios (struct usb_serial_port *port,
448 if (baud) { 556 if (baud) {
449 dbg("%s - Setting baud rate to %d baud", __FUNCTION__, 557 dbg("%s - Setting baud rate to %d baud", __FUNCTION__,
450 baud); 558 baud);
451 if (cp2101_set_config(port, CP2101_BAUDRATE, 559 if (cp2101_set_config_single(port, CP2101_BAUDRATE,
452 (BAUD_RATE_GEN_FREQ / baud))) 560 (BAUD_RATE_GEN_FREQ / baud)))
453 dev_err(&port->dev, "Baud rate requested not " 561 dev_err(&port->dev, "Baud rate requested not "
454 "supported by device\n"); 562 "supported by device\n");
455 } 563 }
456 } 564 }
457 565
458 /*If the number of data bits is to be updated*/ 566 /* If the number of data bits is to be updated */
459 if ((cflag & CSIZE) != (old_cflag & CSIZE)) { 567 if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
460 bits = cp2101_get_config(port, CP2101_BITS); 568 cp2101_get_config(port, CP2101_BITS, &bits, 2);
461 bits &= ~BITS_DATA_MASK; 569 bits &= ~BITS_DATA_MASK;
462 switch (cflag & CSIZE) { 570 switch (cflag & CSIZE) {
571 case CS5:
572 bits |= BITS_DATA_5;
573 dbg("%s - data bits = 5", __FUNCTION__);
574 break;
463 case CS6: 575 case CS6:
464 bits |= BITS_DATA_6; 576 bits |= BITS_DATA_6;
465 dbg("%s - data bits = 6", __FUNCTION__); 577 dbg("%s - data bits = 6", __FUNCTION__);
@@ -483,13 +595,13 @@ static void cp2101_set_termios (struct usb_serial_port *port,
483 bits |= BITS_DATA_8; 595 bits |= BITS_DATA_8;
484 break; 596 break;
485 } 597 }
486 if (cp2101_set_config(port, CP2101_BITS, bits)) 598 if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
487 dev_err(&port->dev, "Number of data bits requested " 599 dev_err(&port->dev, "Number of data bits requested "
488 "not supported by device\n"); 600 "not supported by device\n");
489 } 601 }
490 602
491 if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { 603 if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) {
492 bits = cp2101_get_config(port, CP2101_BITS); 604 cp2101_get_config(port, CP2101_BITS, &bits, 2);
493 bits &= ~BITS_PARITY_MASK; 605 bits &= ~BITS_PARITY_MASK;
494 if (cflag & PARENB) { 606 if (cflag & PARENB) {
495 if (cflag & PARODD) { 607 if (cflag & PARODD) {
@@ -500,13 +612,13 @@ static void cp2101_set_termios (struct usb_serial_port *port,
500 dbg("%s - parity = EVEN", __FUNCTION__); 612 dbg("%s - parity = EVEN", __FUNCTION__);
501 } 613 }
502 } 614 }
503 if (cp2101_set_config(port, CP2101_BITS, bits)) 615 if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
504 dev_err(&port->dev, "Parity mode not supported " 616 dev_err(&port->dev, "Parity mode not supported "
505 "by device\n"); 617 "by device\n");
506 } 618 }
507 619
508 if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { 620 if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
509 bits = cp2101_get_config(port, CP2101_BITS); 621 cp2101_get_config(port, CP2101_BITS, &bits, 2);
510 bits &= ~BITS_STOP_MASK; 622 bits &= ~BITS_STOP_MASK;
511 if (cflag & CSTOPB) { 623 if (cflag & CSTOPB) {
512 bits |= BITS_STOP_2; 624 bits |= BITS_STOP_2;
@@ -515,15 +627,90 @@ static void cp2101_set_termios (struct usb_serial_port *port,
515 bits |= BITS_STOP_1; 627 bits |= BITS_STOP_1;
516 dbg("%s - stop bits = 1", __FUNCTION__); 628 dbg("%s - stop bits = 1", __FUNCTION__);
517 } 629 }
518 if (cp2101_set_config(port, CP2101_BITS, bits)) 630 if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
519 dev_err(&port->dev, "Number of stop bits requested " 631 dev_err(&port->dev, "Number of stop bits requested "
520 "not supported by device\n"); 632 "not supported by device\n");
521 } 633 }
634
635 if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
636 cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16);
637 dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x",
638 __FUNCTION__, modem_ctl[0], modem_ctl[1],
639 modem_ctl[2], modem_ctl[3]);
640
641 if (cflag & CRTSCTS) {
642 modem_ctl[0] &= ~0x7B;
643 modem_ctl[0] |= 0x09;
644 modem_ctl[1] = 0x80;
645 dbg("%s - flow control = CRTSCTS", __FUNCTION__);
646 } else {
647 modem_ctl[0] &= ~0x7B;
648 modem_ctl[0] |= 0x01;
649 modem_ctl[1] |= 0x40;
650 dbg("%s - flow control = NONE", __FUNCTION__);
651 }
652
653 dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x",
654 __FUNCTION__, modem_ctl[0], modem_ctl[1],
655 modem_ctl[2], modem_ctl[3]);
656 cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16);
657 }
658
659}
660
661static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file,
662 unsigned int set, unsigned int clear)
663{
664 int control = 0;
665
666 dbg("%s - port %d", __FUNCTION__, port->number);
667
668 if (set & TIOCM_RTS) {
669 control |= CONTROL_RTS;
670 control |= CONTROL_WRITE_RTS;
671 }
672 if (set & TIOCM_DTR) {
673 control |= CONTROL_DTR;
674 control |= CONTROL_WRITE_DTR;
675 }
676 if (clear & TIOCM_RTS) {
677 control &= ~CONTROL_RTS;
678 control |= CONTROL_WRITE_RTS;
679 }
680 if (clear & TIOCM_DTR) {
681 control &= ~CONTROL_DTR;
682 control |= CONTROL_WRITE_DTR;
683 }
684
685 dbg("%s - control = 0x%.4x", __FUNCTION__, control);
686
687 return cp2101_set_config(port, CP2101_CONTROL, &control, 2);
688
689}
690
691static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file)
692{
693 int control, result;
694
695 dbg("%s - port %d", __FUNCTION__, port->number);
696
697 cp2101_get_config(port, CP2101_CONTROL, &control, 1);
698
699 result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0)
700 |((control & CONTROL_RTS) ? TIOCM_RTS : 0)
701 |((control & CONTROL_CTS) ? TIOCM_CTS : 0)
702 |((control & CONTROL_DSR) ? TIOCM_DSR : 0)
703 |((control & CONTROL_RING)? TIOCM_RI : 0)
704 |((control & CONTROL_DCD) ? TIOCM_CD : 0);
705
706 dbg("%s - control = 0x%.2x", __FUNCTION__, control);
707
708 return result;
522} 709}
523 710
524static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) 711static void cp2101_break_ctl (struct usb_serial_port *port, int break_state)
525{ 712{
526 u16 state; 713 int state;
527 714
528 dbg("%s - port %d", __FUNCTION__, port->number); 715 dbg("%s - port %d", __FUNCTION__, port->number);
529 if (break_state == 0) 716 if (break_state == 0)
@@ -532,12 +719,12 @@ static void cp2101_break_ctl (struct usb_serial_port *port, int break_state)
532 state = BREAK_ON; 719 state = BREAK_ON;
533 dbg("%s - turning break %s", __FUNCTION__, 720 dbg("%s - turning break %s", __FUNCTION__,
534 state==BREAK_OFF ? "off" : "on"); 721 state==BREAK_OFF ? "off" : "on");
535 cp2101_set_config(port, CP2101_BREAK, state); 722 cp2101_set_config(port, CP2101_BREAK, &state, 2);
536} 723}
537 724
538static int cp2101_startup (struct usb_serial *serial) 725static int cp2101_startup (struct usb_serial *serial)
539{ 726{
540 /*CP2101 buffers behave strangely unless device is reset*/ 727 /* CP2101 buffers behave strangely unless device is reset */
541 usb_reset_device(serial->dev); 728 usb_reset_device(serial->dev);
542 return 0; 729 return 0;
543} 730}
@@ -548,7 +735,7 @@ static void cp2101_shutdown (struct usb_serial *serial)
548 735
549 dbg("%s", __FUNCTION__); 736 dbg("%s", __FUNCTION__);
550 737
551 /* stop reads and writes on all ports */ 738 /* Stop reads and writes on all ports */
552 for (i=0; i < serial->num_ports; ++i) { 739 for (i=0; i < serial->num_ports; ++i) {
553 cp2101_cleanup(serial->port[i]); 740 cp2101_cleanup(serial->port[i]);
554 } 741 }
@@ -560,16 +747,16 @@ static int __init cp2101_init (void)
560 747
561 retval = usb_serial_register(&cp2101_device); 748 retval = usb_serial_register(&cp2101_device);
562 if (retval) 749 if (retval)
563 return retval; /*Failed to register*/ 750 return retval; /* Failed to register */
564 751
565 retval = usb_register(&cp2101_driver); 752 retval = usb_register(&cp2101_driver);
566 if (retval) { 753 if (retval) {
567 /*Failed to register*/ 754 /* Failed to register */
568 usb_serial_deregister(&cp2101_device); 755 usb_serial_deregister(&cp2101_device);
569 return retval; 756 return retval;
570 } 757 }
571 758
572 /*Success*/ 759 /* Success */
573 info(DRIVER_DESC " " DRIVER_VERSION); 760 info(DRIVER_DESC " " DRIVER_VERSION);
574 return 0; 761 return 0;
575} 762}