aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/cp210x.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2009-03-11 14:03:49 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-03-24 19:20:44 -0400
commit03ee251546a9360cbb4c27c250d128dcbcfd9931 (patch)
tree50f95cee81b1a4323ae50c6804206704e6771804 /drivers/usb/serial/cp210x.c
parent97324955c62aaa104edea2ef4370dc8882a5ab82 (diff)
USB: serial: rename cp2101 driver to cp210x
Lots of users are getting confused about the cp2101 driver. It really does support more than just the cp2101 device, so rename it to cp210x to try to prevent confusion. Cc: Craig Shelley <craig@microtron.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/cp210x.c')
-rw-r--r--drivers/usb/serial/cp210x.c788
1 files changed, 788 insertions, 0 deletions
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
new file mode 100644
index 000000000000..2f23d0643624
--- /dev/null
+++ b/drivers/usb/serial/cp210x.c
@@ -0,0 +1,788 @@
1/*
2 * Silicon Laboratories CP2101/CP2102 USB to RS232 serial adaptor driver
3 *
4 * Copyright (C) 2005 Craig Shelley (craig@microtron.org.uk)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
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 */
15
16#include <linux/kernel.h>
17#include <linux/errno.h>
18#include <linux/slab.h>
19#include <linux/tty.h>
20#include <linux/tty_flip.h>
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/usb.h>
24#include <linux/uaccess.h>
25#include <linux/usb/serial.h>
26
27/*
28 * Version Information
29 */
30#define DRIVER_VERSION "v0.08"
31#define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver"
32
33/*
34 * Function Prototypes
35 */
36static int cp2101_open(struct tty_struct *, struct usb_serial_port *,
37 struct file *);
38static void cp2101_cleanup(struct usb_serial_port *);
39static void cp2101_close(struct tty_struct *, struct usb_serial_port *,
40 struct file*);
41static void cp2101_get_termios(struct tty_struct *);
42static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *,
43 struct ktermios*);
44static int cp2101_tiocmget(struct tty_struct *, struct file *);
45static int cp2101_tiocmset(struct tty_struct *, struct file *,
46 unsigned int, unsigned int);
47static void cp2101_break_ctl(struct tty_struct *, int);
48static int cp2101_startup(struct usb_serial *);
49static void cp2101_shutdown(struct usb_serial *);
50
51
52static int debug;
53
54static struct usb_device_id id_table [] = {
55 { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */
56 { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
57 { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
58 { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */
59 { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */
60 { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */
61 { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
62 { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
63 { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
64 { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
65 { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
66 { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
67 { USB_DEVICE(0x10C4, 0x8054) }, /* Enfora GSM2228 */
68 { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */
69 { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */
70 { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
71 { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */
72 { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
73 { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */
74 { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
75 { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
76 { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
77 { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
78 { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
79 { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
80 { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
81 { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
82 { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
83 { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
84 { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
85 { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */
86 { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */
87 { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
88 { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
89 { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
90 { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
91 { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
92 { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
93 { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
94 { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */
95 { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */
96 { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
97 { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
98 { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
99 { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
100 { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
101 { } /* Terminating Entry */
102};
103
104MODULE_DEVICE_TABLE(usb, id_table);
105
106static struct usb_driver cp2101_driver = {
107 .name = "cp2101",
108 .probe = usb_serial_probe,
109 .disconnect = usb_serial_disconnect,
110 .id_table = id_table,
111 .no_dynamic_id = 1,
112};
113
114static struct usb_serial_driver cp2101_device = {
115 .driver = {
116 .owner = THIS_MODULE,
117 .name = "cp2101",
118 },
119 .usb_driver = &cp2101_driver,
120 .id_table = id_table,
121 .num_ports = 1,
122 .open = cp2101_open,
123 .close = cp2101_close,
124 .break_ctl = cp2101_break_ctl,
125 .set_termios = cp2101_set_termios,
126 .tiocmget = cp2101_tiocmget,
127 .tiocmset = cp2101_tiocmset,
128 .attach = cp2101_startup,
129 .shutdown = cp2101_shutdown,
130};
131
132/* Config request types */
133#define REQTYPE_HOST_TO_DEVICE 0x41
134#define REQTYPE_DEVICE_TO_HOST 0xc1
135
136/* Config SET requests. To GET, add 1 to the request number */
137#define CP2101_UART 0x00 /* Enable / Disable */
138#define CP2101_BAUDRATE 0x01 /* (BAUD_RATE_GEN_FREQ / baudrate) */
139#define CP2101_BITS 0x03 /* 0x(0)(databits)(parity)(stopbits) */
140#define CP2101_BREAK 0x05 /* On / Off */
141#define CP2101_CONTROL 0x07 /* Flow control line states */
142#define CP2101_MODEMCTL 0x13 /* Modem controls */
143#define CP2101_CONFIG_6 0x19 /* 6 bytes of config data ??? */
144
145/* CP2101_UART */
146#define UART_ENABLE 0x0001
147#define UART_DISABLE 0x0000
148
149/* CP2101_BAUDRATE */
150#define BAUD_RATE_GEN_FREQ 0x384000
151
152/* CP2101_BITS */
153#define BITS_DATA_MASK 0X0f00
154#define BITS_DATA_5 0X0500
155#define BITS_DATA_6 0X0600
156#define BITS_DATA_7 0X0700
157#define BITS_DATA_8 0X0800
158#define BITS_DATA_9 0X0900
159
160#define BITS_PARITY_MASK 0x00f0
161#define BITS_PARITY_NONE 0x0000
162#define BITS_PARITY_ODD 0x0010
163#define BITS_PARITY_EVEN 0x0020
164#define BITS_PARITY_MARK 0x0030
165#define BITS_PARITY_SPACE 0x0040
166
167#define BITS_STOP_MASK 0x000f
168#define BITS_STOP_1 0x0000
169#define BITS_STOP_1_5 0x0001
170#define BITS_STOP_2 0x0002
171
172/* CP2101_BREAK */
173#define BREAK_ON 0x0000
174#define BREAK_OFF 0x0001
175
176/* CP2101_CONTROL */
177#define CONTROL_DTR 0x0001
178#define CONTROL_RTS 0x0002
179#define CONTROL_CTS 0x0010
180#define CONTROL_DSR 0x0020
181#define CONTROL_RING 0x0040
182#define CONTROL_DCD 0x0080
183#define CONTROL_WRITE_DTR 0x0100
184#define CONTROL_WRITE_RTS 0x0200
185
186/*
187 * cp2101_get_config
188 * Reads from the CP2101 configuration registers
189 * 'size' is specified in bytes.
190 * 'data' is a pointer to a pre-allocated array of integers large
191 * enough to hold 'size' bytes (with 4 bytes to each integer)
192 */
193static int cp2101_get_config(struct usb_serial_port *port, u8 request,
194 unsigned int *data, int size)
195{
196 struct usb_serial *serial = port->serial;
197 __le32 *buf;
198 int result, i, length;
199
200 /* Number of integers required to contain the array */
201 length = (((size - 1) | 3) + 1)/4;
202
203 buf = kcalloc(length, sizeof(__le32), GFP_KERNEL);
204 if (!buf) {
205 dev_err(&port->dev, "%s - out of memory.\n", __func__);
206 return -ENOMEM;
207 }
208
209 /* For get requests, the request number must be incremented */
210 request++;
211
212 /* Issue the request, attempting to read 'size' bytes */
213 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
214 request, REQTYPE_DEVICE_TO_HOST, 0x0000,
215 0, buf, size, 300);
216
217 /* Convert data into an array of integers */
218 for (i = 0; i < length; i++)
219 data[i] = le32_to_cpu(buf[i]);
220
221 kfree(buf);
222
223 if (result != size) {
224 dbg("%s - Unable to send config request, "
225 "request=0x%x size=%d result=%d\n",
226 __func__, request, size, result);
227 return -EPROTO;
228 }
229
230 return 0;
231}
232
233/*
234 * cp2101_set_config
235 * Writes to the CP2101 configuration registers
236 * Values less than 16 bits wide are sent directly
237 * 'size' is specified in bytes.
238 */
239static int cp2101_set_config(struct usb_serial_port *port, u8 request,
240 unsigned int *data, int size)
241{
242 struct usb_serial *serial = port->serial;
243 __le32 *buf;
244 int result, i, length;
245
246 /* Number of integers required to contain the array */
247 length = (((size - 1) | 3) + 1)/4;
248
249 buf = kmalloc(length * sizeof(__le32), GFP_KERNEL);
250 if (!buf) {
251 dev_err(&port->dev, "%s - out of memory.\n",
252 __func__);
253 return -ENOMEM;
254 }
255
256 /* Array of integers into bytes */
257 for (i = 0; i < length; i++)
258 buf[i] = cpu_to_le32(data[i]);
259
260 if (size > 2) {
261 result = usb_control_msg(serial->dev,
262 usb_sndctrlpipe(serial->dev, 0),
263 request, REQTYPE_HOST_TO_DEVICE, 0x0000,
264 0, buf, size, 300);
265 } else {
266 result = usb_control_msg(serial->dev,
267 usb_sndctrlpipe(serial->dev, 0),
268 request, REQTYPE_HOST_TO_DEVICE, data[0],
269 0, NULL, 0, 300);
270 }
271
272 kfree(buf);
273
274 if ((size > 2 && result != size) || result < 0) {
275 dbg("%s - Unable to send request, "
276 "request=0x%x size=%d result=%d\n",
277 __func__, request, size, result);
278 return -EPROTO;
279 }
280
281 /* Single data value */
282 result = usb_control_msg(serial->dev,
283 usb_sndctrlpipe(serial->dev, 0),
284 request, REQTYPE_HOST_TO_DEVICE, data[0],
285 0, NULL, 0, 300);
286 return 0;
287}
288
289/*
290 * cp2101_set_config_single
291 * Convenience function for calling cp2101_set_config on single data values
292 * without requiring an integer pointer
293 */
294static inline int cp2101_set_config_single(struct usb_serial_port *port,
295 u8 request, unsigned int data)
296{
297 return cp2101_set_config(port, request, &data, 2);
298}
299
300/*
301 * cp2101_quantise_baudrate
302 * Quantises the baud rate as per AN205 Table 1
303 */
304static unsigned int cp2101_quantise_baudrate(unsigned int baud) {
305 if (baud <= 56) baud = 0;
306 else if (baud <= 300) baud = 300;
307 else if (baud <= 600) baud = 600;
308 else if (baud <= 1200) baud = 1200;
309 else if (baud <= 1800) baud = 1800;
310 else if (baud <= 2400) baud = 2400;
311 else if (baud <= 4000) baud = 4000;
312 else if (baud <= 4803) baud = 4800;
313 else if (baud <= 7207) baud = 7200;
314 else if (baud <= 9612) baud = 9600;
315 else if (baud <= 14428) baud = 14400;
316 else if (baud <= 16062) baud = 16000;
317 else if (baud <= 19250) baud = 19200;
318 else if (baud <= 28912) baud = 28800;
319 else if (baud <= 38601) baud = 38400;
320 else if (baud <= 51558) baud = 51200;
321 else if (baud <= 56280) baud = 56000;
322 else if (baud <= 58053) baud = 57600;
323 else if (baud <= 64111) baud = 64000;
324 else if (baud <= 77608) baud = 76800;
325 else if (baud <= 117028) baud = 115200;
326 else if (baud <= 129347) baud = 128000;
327 else if (baud <= 156868) baud = 153600;
328 else if (baud <= 237832) baud = 230400;
329 else if (baud <= 254234) baud = 250000;
330 else if (baud <= 273066) baud = 256000;
331 else if (baud <= 491520) baud = 460800;
332 else if (baud <= 567138) baud = 500000;
333 else if (baud <= 670254) baud = 576000;
334 else if (baud <= 1053257) baud = 921600;
335 else if (baud <= 1474560) baud = 1228800;
336 else if (baud <= 2457600) baud = 1843200;
337 else baud = 3686400;
338 return baud;
339}
340
341static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port,
342 struct file *filp)
343{
344 struct usb_serial *serial = port->serial;
345 int result;
346
347 dbg("%s - port %d", __func__, port->number);
348
349 if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) {
350 dev_err(&port->dev, "%s - Unable to enable UART\n",
351 __func__);
352 return -EPROTO;
353 }
354
355 /* Start reading from the device */
356 usb_fill_bulk_urb(port->read_urb, serial->dev,
357 usb_rcvbulkpipe(serial->dev,
358 port->bulk_in_endpointAddress),
359 port->read_urb->transfer_buffer,
360 port->read_urb->transfer_buffer_length,
361 serial->type->read_bulk_callback,
362 port);
363 result = usb_submit_urb(port->read_urb, GFP_KERNEL);
364 if (result) {
365 dev_err(&port->dev, "%s - failed resubmitting read urb, "
366 "error %d\n", __func__, result);
367 return result;
368 }
369
370 /* Configure the termios structure */
371 cp2101_get_termios(tty);
372
373 /* Set the DTR and RTS pins low */
374 cp2101_tiocmset(tty, NULL, TIOCM_DTR | TIOCM_RTS, 0);
375
376 return 0;
377}
378
379static void cp2101_cleanup(struct usb_serial_port *port)
380{
381 struct usb_serial *serial = port->serial;
382
383 dbg("%s - port %d", __func__, port->number);
384
385 if (serial->dev) {
386 /* shutdown any bulk reads that might be going on */
387 if (serial->num_bulk_out)
388 usb_kill_urb(port->write_urb);
389 if (serial->num_bulk_in)
390 usb_kill_urb(port->read_urb);
391 }
392}
393
394static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port,
395 struct file *filp)
396{
397 dbg("%s - port %d", __func__, port->number);
398
399 /* shutdown our urbs */
400 dbg("%s - shutting down urbs", __func__);
401 usb_kill_urb(port->write_urb);
402 usb_kill_urb(port->read_urb);
403
404 mutex_lock(&port->serial->disc_mutex);
405 if (!port->serial->disconnected)
406 cp2101_set_config_single(port, CP2101_UART, UART_DISABLE);
407 mutex_unlock(&port->serial->disc_mutex);
408}
409
410/*
411 * cp2101_get_termios
412 * Reads the baud rate, data bits, parity, stop bits and flow control mode
413 * from the device, corrects any unsupported values, and configures the
414 * termios structure to reflect the state of the device
415 */
416static void cp2101_get_termios (struct tty_struct *tty)
417{
418 struct usb_serial_port *port = tty->driver_data;
419 unsigned int cflag, modem_ctl[4];
420 unsigned int baud;
421 unsigned int bits;
422
423 dbg("%s - port %d", __func__, port->number);
424
425 cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
426 /* Convert to baudrate */
427 if (baud)
428 baud = cp2101_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud);
429
430 dbg("%s - baud rate = %d", __func__, baud);
431
432 tty_encode_baud_rate(tty, baud, baud);
433 cflag = tty->termios->c_cflag;
434
435 cp2101_get_config(port, CP2101_BITS, &bits, 2);
436 cflag &= ~CSIZE;
437 switch (bits & BITS_DATA_MASK) {
438 case BITS_DATA_5:
439 dbg("%s - data bits = 5", __func__);
440 cflag |= CS5;
441 break;
442 case BITS_DATA_6:
443 dbg("%s - data bits = 6", __func__);
444 cflag |= CS6;
445 break;
446 case BITS_DATA_7:
447 dbg("%s - data bits = 7", __func__);
448 cflag |= CS7;
449 break;
450 case BITS_DATA_8:
451 dbg("%s - data bits = 8", __func__);
452 cflag |= CS8;
453 break;
454 case BITS_DATA_9:
455 dbg("%s - data bits = 9 (not supported, using 8 data bits)",
456 __func__);
457 cflag |= CS8;
458 bits &= ~BITS_DATA_MASK;
459 bits |= BITS_DATA_8;
460 cp2101_set_config(port, CP2101_BITS, &bits, 2);
461 break;
462 default:
463 dbg("%s - Unknown number of data bits, using 8", __func__);
464 cflag |= CS8;
465 bits &= ~BITS_DATA_MASK;
466 bits |= BITS_DATA_8;
467 cp2101_set_config(port, CP2101_BITS, &bits, 2);
468 break;
469 }
470
471 switch (bits & BITS_PARITY_MASK) {
472 case BITS_PARITY_NONE:
473 dbg("%s - parity = NONE", __func__);
474 cflag &= ~PARENB;
475 break;
476 case BITS_PARITY_ODD:
477 dbg("%s - parity = ODD", __func__);
478 cflag |= (PARENB|PARODD);
479 break;
480 case BITS_PARITY_EVEN:
481 dbg("%s - parity = EVEN", __func__);
482 cflag &= ~PARODD;
483 cflag |= PARENB;
484 break;
485 case BITS_PARITY_MARK:
486 dbg("%s - parity = MARK (not supported, disabling parity)",
487 __func__);
488 cflag &= ~PARENB;
489 bits &= ~BITS_PARITY_MASK;
490 cp2101_set_config(port, CP2101_BITS, &bits, 2);
491 break;
492 case BITS_PARITY_SPACE:
493 dbg("%s - parity = SPACE (not supported, disabling parity)",
494 __func__);
495 cflag &= ~PARENB;
496 bits &= ~BITS_PARITY_MASK;
497 cp2101_set_config(port, CP2101_BITS, &bits, 2);
498 break;
499 default:
500 dbg("%s - Unknown parity mode, disabling parity", __func__);
501 cflag &= ~PARENB;
502 bits &= ~BITS_PARITY_MASK;
503 cp2101_set_config(port, CP2101_BITS, &bits, 2);
504 break;
505 }
506
507 cflag &= ~CSTOPB;
508 switch (bits & BITS_STOP_MASK) {
509 case BITS_STOP_1:
510 dbg("%s - stop bits = 1", __func__);
511 break;
512 case BITS_STOP_1_5:
513 dbg("%s - stop bits = 1.5 (not supported, using 1 stop bit)",
514 __func__);
515 bits &= ~BITS_STOP_MASK;
516 cp2101_set_config(port, CP2101_BITS, &bits, 2);
517 break;
518 case BITS_STOP_2:
519 dbg("%s - stop bits = 2", __func__);
520 cflag |= CSTOPB;
521 break;
522 default:
523 dbg("%s - Unknown number of stop bits, using 1 stop bit",
524 __func__);
525 bits &= ~BITS_STOP_MASK;
526 cp2101_set_config(port, CP2101_BITS, &bits, 2);
527 break;
528 }
529
530 cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16);
531 if (modem_ctl[0] & 0x0008) {
532 dbg("%s - flow control = CRTSCTS", __func__);
533 cflag |= CRTSCTS;
534 } else {
535 dbg("%s - flow control = NONE", __func__);
536 cflag &= ~CRTSCTS;
537 }
538
539 tty->termios->c_cflag = cflag;
540}
541
542static void cp2101_set_termios(struct tty_struct *tty,
543 struct usb_serial_port *port, struct ktermios *old_termios)
544{
545 unsigned int cflag, old_cflag;
546 unsigned int baud = 0, bits;
547 unsigned int modem_ctl[4];
548
549 dbg("%s - port %d", __func__, port->number);
550
551 if (!tty)
552 return;
553
554 tty->termios->c_cflag &= ~CMSPAR;
555 cflag = tty->termios->c_cflag;
556 old_cflag = old_termios->c_cflag;
557 baud = cp2101_quantise_baudrate(tty_get_baud_rate(tty));
558
559 /* If the baud rate is to be updated*/
560 if (baud != tty_termios_baud_rate(old_termios) && baud != 0) {
561 dbg("%s - Setting baud rate to %d baud", __func__,
562 baud);
563 if (cp2101_set_config_single(port, CP2101_BAUDRATE,
564 ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) {
565 dbg("Baud rate requested not supported by device\n");
566 baud = tty_termios_baud_rate(old_termios);
567 }
568 }
569 /* Report back the resulting baud rate */
570 tty_encode_baud_rate(tty, baud, baud);
571
572 /* If the number of data bits is to be updated */
573 if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
574 cp2101_get_config(port, CP2101_BITS, &bits, 2);
575 bits &= ~BITS_DATA_MASK;
576 switch (cflag & CSIZE) {
577 case CS5:
578 bits |= BITS_DATA_5;
579 dbg("%s - data bits = 5", __func__);
580 break;
581 case CS6:
582 bits |= BITS_DATA_6;
583 dbg("%s - data bits = 6", __func__);
584 break;
585 case CS7:
586 bits |= BITS_DATA_7;
587 dbg("%s - data bits = 7", __func__);
588 break;
589 case CS8:
590 bits |= BITS_DATA_8;
591 dbg("%s - data bits = 8", __func__);
592 break;
593 /*case CS9:
594 bits |= BITS_DATA_9;
595 dbg("%s - data bits = 9", __func__);
596 break;*/
597 default:
598 dbg("cp2101 driver does not "
599 "support the number of bits requested,"
600 " using 8 bit mode\n");
601 bits |= BITS_DATA_8;
602 break;
603 }
604 if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
605 dbg("Number of data bits requested "
606 "not supported by device\n");
607 }
608
609 if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) {
610 cp2101_get_config(port, CP2101_BITS, &bits, 2);
611 bits &= ~BITS_PARITY_MASK;
612 if (cflag & PARENB) {
613 if (cflag & PARODD) {
614 bits |= BITS_PARITY_ODD;
615 dbg("%s - parity = ODD", __func__);
616 } else {
617 bits |= BITS_PARITY_EVEN;
618 dbg("%s - parity = EVEN", __func__);
619 }
620 }
621 if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
622 dbg("Parity mode not supported "
623 "by device\n");
624 }
625
626 if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
627 cp2101_get_config(port, CP2101_BITS, &bits, 2);
628 bits &= ~BITS_STOP_MASK;
629 if (cflag & CSTOPB) {
630 bits |= BITS_STOP_2;
631 dbg("%s - stop bits = 2", __func__);
632 } else {
633 bits |= BITS_STOP_1;
634 dbg("%s - stop bits = 1", __func__);
635 }
636 if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
637 dbg("Number of stop bits requested "
638 "not supported by device\n");
639 }
640
641 if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
642 cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16);
643 dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x",
644 __func__, modem_ctl[0], modem_ctl[1],
645 modem_ctl[2], modem_ctl[3]);
646
647 if (cflag & CRTSCTS) {
648 modem_ctl[0] &= ~0x7B;
649 modem_ctl[0] |= 0x09;
650 modem_ctl[1] = 0x80;
651 dbg("%s - flow control = CRTSCTS", __func__);
652 } else {
653 modem_ctl[0] &= ~0x7B;
654 modem_ctl[0] |= 0x01;
655 modem_ctl[1] |= 0x40;
656 dbg("%s - flow control = NONE", __func__);
657 }
658
659 dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x",
660 __func__, modem_ctl[0], modem_ctl[1],
661 modem_ctl[2], modem_ctl[3]);
662 cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16);
663 }
664
665}
666
667static int cp2101_tiocmset (struct tty_struct *tty, struct file *file,
668 unsigned int set, unsigned int clear)
669{
670 struct usb_serial_port *port = tty->driver_data;
671 unsigned int control = 0;
672
673 dbg("%s - port %d", __func__, port->number);
674
675 if (set & TIOCM_RTS) {
676 control |= CONTROL_RTS;
677 control |= CONTROL_WRITE_RTS;
678 }
679 if (set & TIOCM_DTR) {
680 control |= CONTROL_DTR;
681 control |= CONTROL_WRITE_DTR;
682 }
683 if (clear & TIOCM_RTS) {
684 control &= ~CONTROL_RTS;
685 control |= CONTROL_WRITE_RTS;
686 }
687 if (clear & TIOCM_DTR) {
688 control &= ~CONTROL_DTR;
689 control |= CONTROL_WRITE_DTR;
690 }
691
692 dbg("%s - control = 0x%.4x", __func__, control);
693
694 return cp2101_set_config(port, CP2101_CONTROL, &control, 2);
695
696}
697
698static int cp2101_tiocmget (struct tty_struct *tty, struct file *file)
699{
700 struct usb_serial_port *port = tty->driver_data;
701 unsigned int control;
702 int result;
703
704 dbg("%s - port %d", __func__, port->number);
705
706 cp2101_get_config(port, CP2101_CONTROL, &control, 1);
707
708 result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0)
709 |((control & CONTROL_RTS) ? TIOCM_RTS : 0)
710 |((control & CONTROL_CTS) ? TIOCM_CTS : 0)
711 |((control & CONTROL_DSR) ? TIOCM_DSR : 0)
712 |((control & CONTROL_RING)? TIOCM_RI : 0)
713 |((control & CONTROL_DCD) ? TIOCM_CD : 0);
714
715 dbg("%s - control = 0x%.2x", __func__, control);
716
717 return result;
718}
719
720static void cp2101_break_ctl (struct tty_struct *tty, int break_state)
721{
722 struct usb_serial_port *port = tty->driver_data;
723 unsigned int state;
724
725 dbg("%s - port %d", __func__, port->number);
726 if (break_state == 0)
727 state = BREAK_OFF;
728 else
729 state = BREAK_ON;
730 dbg("%s - turning break %s", __func__,
731 state == BREAK_OFF ? "off" : "on");
732 cp2101_set_config(port, CP2101_BREAK, &state, 2);
733}
734
735static int cp2101_startup(struct usb_serial *serial)
736{
737 /* CP2101 buffers behave strangely unless device is reset */
738 usb_reset_device(serial->dev);
739 return 0;
740}
741
742static void cp2101_shutdown(struct usb_serial *serial)
743{
744 int i;
745
746 dbg("%s", __func__);
747
748 /* Stop reads and writes on all ports */
749 for (i = 0; i < serial->num_ports; ++i)
750 cp2101_cleanup(serial->port[i]);
751}
752
753static int __init cp2101_init(void)
754{
755 int retval;
756
757 retval = usb_serial_register(&cp2101_device);
758 if (retval)
759 return retval; /* Failed to register */
760
761 retval = usb_register(&cp2101_driver);
762 if (retval) {
763 /* Failed to register */
764 usb_serial_deregister(&cp2101_device);
765 return retval;
766 }
767
768 /* Success */
769 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
770 DRIVER_DESC "\n");
771 return 0;
772}
773
774static void __exit cp2101_exit(void)
775{
776 usb_deregister(&cp2101_driver);
777 usb_serial_deregister(&cp2101_device);
778}
779
780module_init(cp2101_init);
781module_exit(cp2101_exit);
782
783MODULE_DESCRIPTION(DRIVER_DESC);
784MODULE_VERSION(DRIVER_VERSION);
785MODULE_LICENSE("GPL");
786
787module_param(debug, bool, S_IRUGO | S_IWUSR);
788MODULE_PARM_DESC(debug, "Enable verbose debugging messages");