Adding support for MOXA ART SoC. Testing port of linux-2.6.32.60-moxart.
[linux-3.6.7-moxart.git] / drivers / usb / serial / mct_u232.c
blobc088250555ba0a798e8d4c737ef69e6525fe1508
1 /*
2 * MCT (Magic Control Technology Corp.) USB RS232 Converter Driver
4 * Copyright (C) 2000 Wolfgang Grandegger (wolfgang@ces.ch)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is largely derived from the Belkin USB Serial Adapter Driver
12 * (see belkin_sa.[ch]). All of the information about the device was acquired
13 * by using SniffUSB on Windows98. For technical details see mct_u232.h.
15 * William G. Greathouse and Greg Kroah-Hartman provided great help on how to
16 * do the reverse engineering and how to write a USB serial device driver.
18 * TO BE DONE, TO BE CHECKED:
19 * DTR/RTS signal handling may be incomplete or incorrect. I have mainly
20 * implemented what I have seen with SniffUSB or found in belkin_sa.c.
21 * For further TODOs check also belkin_sa.c.
24 #include <linux/kernel.h>
25 #include <linux/errno.h>
26 #include <linux/init.h>
27 #include <linux/slab.h>
28 #include <linux/tty.h>
29 #include <linux/tty_driver.h>
30 #include <linux/tty_flip.h>
31 #include <linux/module.h>
32 #include <linux/spinlock.h>
33 #include <linux/uaccess.h>
34 #include <asm/unaligned.h>
35 #include <linux/usb.h>
36 #include <linux/usb/serial.h>
37 #include <linux/serial.h>
38 #include <linux/ioctl.h>
39 #include "mct_u232.h"
42 * Version Information
44 #define DRIVER_VERSION "z2.1" /* Linux in-kernel version */
45 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
46 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
48 static bool debug;
51 * Function prototypes
53 static int mct_u232_startup(struct usb_serial *serial);
54 static int mct_u232_port_probe(struct usb_serial_port *port);
55 static int mct_u232_port_remove(struct usb_serial_port *remove);
56 static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
57 static void mct_u232_close(struct usb_serial_port *port);
58 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
59 static void mct_u232_read_int_callback(struct urb *urb);
60 static void mct_u232_set_termios(struct tty_struct *tty,
61 struct usb_serial_port *port, struct ktermios *old);
62 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
63 static int mct_u232_tiocmget(struct tty_struct *tty);
64 static int mct_u232_tiocmset(struct tty_struct *tty,
65 unsigned int set, unsigned int clear);
66 static int mct_u232_ioctl(struct tty_struct *tty,
67 unsigned int cmd, unsigned long arg);
68 static int mct_u232_get_icount(struct tty_struct *tty,
69 struct serial_icounter_struct *icount);
70 static void mct_u232_throttle(struct tty_struct *tty);
71 static void mct_u232_unthrottle(struct tty_struct *tty);
75 * All of the device info needed for the MCT USB-RS232 converter.
77 static const struct usb_device_id id_table[] = {
78 { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
79 { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
80 { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
81 { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
82 { } /* Terminating entry */
84 MODULE_DEVICE_TABLE(usb, id_table);
86 static struct usb_serial_driver mct_u232_device = {
87 .driver = {
88 .owner = THIS_MODULE,
89 .name = "mct_u232",
91 .description = "MCT U232",
92 .id_table = id_table,
93 .num_ports = 1,
94 .open = mct_u232_open,
95 .close = mct_u232_close,
96 .dtr_rts = mct_u232_dtr_rts,
97 .throttle = mct_u232_throttle,
98 .unthrottle = mct_u232_unthrottle,
99 .read_int_callback = mct_u232_read_int_callback,
100 .set_termios = mct_u232_set_termios,
101 .break_ctl = mct_u232_break_ctl,
102 .tiocmget = mct_u232_tiocmget,
103 .tiocmset = mct_u232_tiocmset,
104 .attach = mct_u232_startup,
105 .port_probe = mct_u232_port_probe,
106 .port_remove = mct_u232_port_remove,
107 .ioctl = mct_u232_ioctl,
108 .get_icount = mct_u232_get_icount,
111 static struct usb_serial_driver * const serial_drivers[] = {
112 &mct_u232_device, NULL
115 struct mct_u232_private {
116 spinlock_t lock;
117 unsigned int control_state; /* Modem Line Setting (TIOCM) */
118 unsigned char last_lcr; /* Line Control Register */
119 unsigned char last_lsr; /* Line Status Register */
120 unsigned char last_msr; /* Modem Status Register */
121 unsigned int rx_flags; /* Throttling flags */
122 struct async_icount icount;
123 wait_queue_head_t msr_wait; /* for handling sleeping while waiting
124 for msr change to happen */
127 #define THROTTLED 0x01
130 * Handle vendor specific USB requests
133 #define WDR_TIMEOUT 5000 /* default urb timeout */
136 * Later day 2.6.0-test kernels have new baud rates like B230400 which
137 * we do not know how to support. We ignore them for the moment.
139 static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
140 speed_t value, speed_t *result)
142 *result = value;
144 if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
145 || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
146 switch (value) {
147 case 300:
148 return 0x01;
149 case 600:
150 return 0x02; /* this one not tested */
151 case 1200:
152 return 0x03;
153 case 2400:
154 return 0x04;
155 case 4800:
156 return 0x06;
157 case 9600:
158 return 0x08;
159 case 19200:
160 return 0x09;
161 case 38400:
162 return 0x0a;
163 case 57600:
164 return 0x0b;
165 case 115200:
166 return 0x0c;
167 default:
168 *result = 9600;
169 return 0x08;
171 } else {
172 /* FIXME: Can we use any divider - should we do
173 divider = 115200/value;
174 real baud = 115200/divider */
175 switch (value) {
176 case 300: break;
177 case 600: break;
178 case 1200: break;
179 case 2400: break;
180 case 4800: break;
181 case 9600: break;
182 case 19200: break;
183 case 38400: break;
184 case 57600: break;
185 case 115200: break;
186 default:
187 value = 9600;
188 *result = 9600;
190 return 115200/value;
194 static int mct_u232_set_baud_rate(struct tty_struct *tty,
195 struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
197 unsigned int divisor;
198 int rc;
199 unsigned char *buf;
200 unsigned char cts_enable_byte = 0;
201 speed_t speed;
203 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
204 if (buf == NULL)
205 return -ENOMEM;
207 divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
208 put_unaligned_le32(cpu_to_le32(divisor), buf);
209 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
210 MCT_U232_SET_BAUD_RATE_REQUEST,
211 MCT_U232_SET_REQUEST_TYPE,
212 0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE,
213 WDR_TIMEOUT);
214 if (rc < 0) /*FIXME: What value speed results */
215 dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
216 value, rc);
217 else
218 tty_encode_baud_rate(tty, speed, speed);
219 dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor);
221 /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
222 always sends two extra USB 'device request' messages after the
223 'baud rate change' message. The actual functionality of the
224 request codes in these messages is not fully understood but these
225 particular codes are never seen in any operation besides a baud
226 rate change. Both of these messages send a single byte of data.
227 In the first message, the value of this byte is always zero.
229 The second message has been determined experimentally to control
230 whether data will be transmitted to a device which is not asserting
231 the 'CTS' signal. If the second message's data byte is zero, data
232 will be transmitted even if 'CTS' is not asserted (i.e. no hardware
233 flow control). if the second message's data byte is nonzero (a
234 value of 1 is used by this driver), data will not be transmitted to
235 a device which is not asserting 'CTS'.
238 buf[0] = 0;
239 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
240 MCT_U232_SET_UNKNOWN1_REQUEST,
241 MCT_U232_SET_REQUEST_TYPE,
242 0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE,
243 WDR_TIMEOUT);
244 if (rc < 0)
245 dev_err(&port->dev, "Sending USB device request code %d "
246 "failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST,
247 rc);
249 if (port && C_CRTSCTS(tty))
250 cts_enable_byte = 1;
252 dbg("set_baud_rate: send second control message, data = %02X",
253 cts_enable_byte);
254 buf[0] = cts_enable_byte;
255 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
256 MCT_U232_SET_CTS_REQUEST,
257 MCT_U232_SET_REQUEST_TYPE,
258 0, 0, buf, MCT_U232_SET_CTS_SIZE,
259 WDR_TIMEOUT);
260 if (rc < 0)
261 dev_err(&port->dev, "Sending USB device request code %d "
262 "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
264 kfree(buf);
265 return rc;
266 } /* mct_u232_set_baud_rate */
268 static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)
270 int rc;
271 unsigned char *buf;
273 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
274 if (buf == NULL)
275 return -ENOMEM;
277 buf[0] = lcr;
278 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
279 MCT_U232_SET_LINE_CTRL_REQUEST,
280 MCT_U232_SET_REQUEST_TYPE,
281 0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE,
282 WDR_TIMEOUT);
283 if (rc < 0)
284 dev_err(&serial->dev->dev,
285 "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc);
286 dbg("set_line_ctrl: 0x%x", lcr);
287 kfree(buf);
288 return rc;
289 } /* mct_u232_set_line_ctrl */
291 static int mct_u232_set_modem_ctrl(struct usb_serial *serial,
292 unsigned int control_state)
294 int rc;
295 unsigned char mcr;
296 unsigned char *buf;
298 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
299 if (buf == NULL)
300 return -ENOMEM;
302 mcr = MCT_U232_MCR_NONE;
303 if (control_state & TIOCM_DTR)
304 mcr |= MCT_U232_MCR_DTR;
305 if (control_state & TIOCM_RTS)
306 mcr |= MCT_U232_MCR_RTS;
308 buf[0] = mcr;
309 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
310 MCT_U232_SET_MODEM_CTRL_REQUEST,
311 MCT_U232_SET_REQUEST_TYPE,
312 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE,
313 WDR_TIMEOUT);
314 kfree(buf);
316 dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr);
318 if (rc < 0) {
319 dev_err(&serial->dev->dev,
320 "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
321 return rc;
323 return 0;
324 } /* mct_u232_set_modem_ctrl */
326 static int mct_u232_get_modem_stat(struct usb_serial *serial,
327 unsigned char *msr)
329 int rc;
330 unsigned char *buf;
332 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
333 if (buf == NULL) {
334 *msr = 0;
335 return -ENOMEM;
337 rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
338 MCT_U232_GET_MODEM_STAT_REQUEST,
339 MCT_U232_GET_REQUEST_TYPE,
340 0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
341 WDR_TIMEOUT);
342 if (rc < 0) {
343 dev_err(&serial->dev->dev,
344 "Get MODEM STATus failed (error = %d)\n", rc);
345 *msr = 0;
346 } else {
347 *msr = buf[0];
349 dbg("get_modem_stat: 0x%x", *msr);
350 kfree(buf);
351 return rc;
352 } /* mct_u232_get_modem_stat */
354 static void mct_u232_msr_to_icount(struct async_icount *icount,
355 unsigned char msr)
357 /* Translate Control Line states */
358 if (msr & MCT_U232_MSR_DDSR)
359 icount->dsr++;
360 if (msr & MCT_U232_MSR_DCTS)
361 icount->cts++;
362 if (msr & MCT_U232_MSR_DRI)
363 icount->rng++;
364 if (msr & MCT_U232_MSR_DCD)
365 icount->dcd++;
366 } /* mct_u232_msr_to_icount */
368 static void mct_u232_msr_to_state(unsigned int *control_state,
369 unsigned char msr)
371 /* Translate Control Line states */
372 if (msr & MCT_U232_MSR_DSR)
373 *control_state |= TIOCM_DSR;
374 else
375 *control_state &= ~TIOCM_DSR;
376 if (msr & MCT_U232_MSR_CTS)
377 *control_state |= TIOCM_CTS;
378 else
379 *control_state &= ~TIOCM_CTS;
380 if (msr & MCT_U232_MSR_RI)
381 *control_state |= TIOCM_RI;
382 else
383 *control_state &= ~TIOCM_RI;
384 if (msr & MCT_U232_MSR_CD)
385 *control_state |= TIOCM_CD;
386 else
387 *control_state &= ~TIOCM_CD;
388 dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state);
389 } /* mct_u232_msr_to_state */
392 * Driver's tty interface functions
395 static int mct_u232_startup(struct usb_serial *serial)
397 struct usb_serial_port *port, *rport;
399 /* Puh, that's dirty */
400 port = serial->port[0];
401 rport = serial->port[1];
402 /* No unlinking, it wasn't submitted yet. */
403 usb_free_urb(port->read_urb);
404 port->read_urb = rport->interrupt_in_urb;
405 rport->interrupt_in_urb = NULL;
406 port->read_urb->context = port;
408 return 0;
409 } /* mct_u232_startup */
411 static int mct_u232_port_probe(struct usb_serial_port *port)
413 struct mct_u232_private *priv;
415 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
416 if (!priv)
417 return -ENOMEM;
419 spin_lock_init(&priv->lock);
420 init_waitqueue_head(&priv->msr_wait);
422 usb_set_serial_port_data(port, priv);
424 return 0;
427 static int mct_u232_port_remove(struct usb_serial_port *port)
429 struct mct_u232_private *priv;
431 priv = usb_get_serial_port_data(port);
432 kfree(priv);
434 return 0;
437 static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
439 struct usb_serial *serial = port->serial;
440 struct mct_u232_private *priv = usb_get_serial_port_data(port);
441 int retval = 0;
442 unsigned int control_state;
443 unsigned long flags;
444 unsigned char last_lcr;
445 unsigned char last_msr;
447 /* Compensate for a hardware bug: although the Sitecom U232-P25
448 * device reports a maximum output packet size of 32 bytes,
449 * it seems to be able to accept only 16 bytes (and that's what
450 * SniffUSB says too...)
452 if (le16_to_cpu(serial->dev->descriptor.idProduct)
453 == MCT_U232_SITECOM_PID)
454 port->bulk_out_size = 16;
456 /* Do a defined restart: the normal serial device seems to
457 * always turn on DTR and RTS here, so do the same. I'm not
458 * sure if this is really necessary. But it should not harm
459 * either.
461 spin_lock_irqsave(&priv->lock, flags);
462 if (tty && (tty->termios->c_cflag & CBAUD))
463 priv->control_state = TIOCM_DTR | TIOCM_RTS;
464 else
465 priv->control_state = 0;
467 priv->last_lcr = (MCT_U232_DATA_BITS_8 |
468 MCT_U232_PARITY_NONE |
469 MCT_U232_STOP_BITS_1);
470 control_state = priv->control_state;
471 last_lcr = priv->last_lcr;
472 spin_unlock_irqrestore(&priv->lock, flags);
473 mct_u232_set_modem_ctrl(serial, control_state);
474 mct_u232_set_line_ctrl(serial, last_lcr);
476 /* Read modem status and update control state */
477 mct_u232_get_modem_stat(serial, &last_msr);
478 spin_lock_irqsave(&priv->lock, flags);
479 priv->last_msr = last_msr;
480 mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
481 spin_unlock_irqrestore(&priv->lock, flags);
483 retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
484 if (retval) {
485 dev_err(&port->dev,
486 "usb_submit_urb(read bulk) failed pipe 0x%x err %d\n",
487 port->read_urb->pipe, retval);
488 goto error;
491 retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
492 if (retval) {
493 usb_kill_urb(port->read_urb);
494 dev_err(&port->dev,
495 "usb_submit_urb(read int) failed pipe 0x%x err %d",
496 port->interrupt_in_urb->pipe, retval);
497 goto error;
499 return 0;
501 error:
502 return retval;
503 } /* mct_u232_open */
505 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
507 unsigned int control_state;
508 struct mct_u232_private *priv = usb_get_serial_port_data(port);
510 mutex_lock(&port->serial->disc_mutex);
511 if (!port->serial->disconnected) {
512 /* drop DTR and RTS */
513 spin_lock_irq(&priv->lock);
514 if (on)
515 priv->control_state |= TIOCM_DTR | TIOCM_RTS;
516 else
517 priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
518 control_state = priv->control_state;
519 spin_unlock_irq(&priv->lock);
520 mct_u232_set_modem_ctrl(port->serial, control_state);
522 mutex_unlock(&port->serial->disc_mutex);
525 static void mct_u232_close(struct usb_serial_port *port)
528 * Must kill the read urb as it is actually an interrupt urb, which
529 * generic close thus fails to kill.
531 usb_kill_urb(port->read_urb);
532 usb_kill_urb(port->interrupt_in_urb);
534 usb_serial_generic_close(port);
535 } /* mct_u232_close */
538 static void mct_u232_read_int_callback(struct urb *urb)
540 struct usb_serial_port *port = urb->context;
541 struct mct_u232_private *priv = usb_get_serial_port_data(port);
542 struct usb_serial *serial = port->serial;
543 struct tty_struct *tty;
544 unsigned char *data = urb->transfer_buffer;
545 int retval;
546 int status = urb->status;
547 unsigned long flags;
549 switch (status) {
550 case 0:
551 /* success */
552 break;
553 case -ECONNRESET:
554 case -ENOENT:
555 case -ESHUTDOWN:
556 /* this urb is terminated, clean up */
557 dbg("%s - urb shutting down with status: %d",
558 __func__, status);
559 return;
560 default:
561 dbg("%s - nonzero urb status received: %d",
562 __func__, status);
563 goto exit;
566 if (!serial) {
567 dbg("%s - bad serial pointer, exiting", __func__);
568 return;
571 usb_serial_debug_data(debug, &port->dev, __func__,
572 urb->actual_length, data);
575 * Work-a-round: handle the 'usual' bulk-in pipe here
577 if (urb->transfer_buffer_length > 2) {
578 if (urb->actual_length) {
579 tty = tty_port_tty_get(&port->port);
580 if (tty) {
581 tty_insert_flip_string(tty, data,
582 urb->actual_length);
583 tty_flip_buffer_push(tty);
585 tty_kref_put(tty);
587 goto exit;
591 * The interrupt-in pipe signals exceptional conditions (modem line
592 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
594 spin_lock_irqsave(&priv->lock, flags);
595 priv->last_msr = data[MCT_U232_MSR_INDEX];
597 /* Record Control Line states */
598 mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
600 mct_u232_msr_to_icount(&priv->icount, priv->last_msr);
602 #if 0
603 /* Not yet handled. See belkin_sa.c for further information */
604 /* Now to report any errors */
605 priv->last_lsr = data[MCT_U232_LSR_INDEX];
607 * fill in the flip buffer here, but I do not know the relation
608 * to the current/next receive buffer or characters. I need
609 * to look in to this before committing any code.
611 if (priv->last_lsr & MCT_U232_LSR_ERR) {
612 tty = tty_port_tty_get(&port->port);
613 /* Overrun Error */
614 if (priv->last_lsr & MCT_U232_LSR_OE) {
616 /* Parity Error */
617 if (priv->last_lsr & MCT_U232_LSR_PE) {
619 /* Framing Error */
620 if (priv->last_lsr & MCT_U232_LSR_FE) {
622 /* Break Indicator */
623 if (priv->last_lsr & MCT_U232_LSR_BI) {
625 tty_kref_put(tty);
627 #endif
628 wake_up_interruptible(&priv->msr_wait);
629 spin_unlock_irqrestore(&priv->lock, flags);
630 exit:
631 retval = usb_submit_urb(urb, GFP_ATOMIC);
632 if (retval)
633 dev_err(&port->dev,
634 "%s - usb_submit_urb failed with result %d\n",
635 __func__, retval);
636 } /* mct_u232_read_int_callback */
638 static void mct_u232_set_termios(struct tty_struct *tty,
639 struct usb_serial_port *port,
640 struct ktermios *old_termios)
642 struct usb_serial *serial = port->serial;
643 struct mct_u232_private *priv = usb_get_serial_port_data(port);
644 struct ktermios *termios = tty->termios;
645 unsigned int cflag = termios->c_cflag;
646 unsigned int old_cflag = old_termios->c_cflag;
647 unsigned long flags;
648 unsigned int control_state;
649 unsigned char last_lcr;
651 /* get a local copy of the current port settings */
652 spin_lock_irqsave(&priv->lock, flags);
653 control_state = priv->control_state;
654 spin_unlock_irqrestore(&priv->lock, flags);
655 last_lcr = 0;
658 * Update baud rate.
659 * Do not attempt to cache old rates and skip settings,
660 * disconnects screw such tricks up completely.
661 * Premature optimization is the root of all evil.
664 /* reassert DTR and RTS on transition from B0 */
665 if ((old_cflag & CBAUD) == B0) {
666 dbg("%s: baud was B0", __func__);
667 control_state |= TIOCM_DTR | TIOCM_RTS;
668 mct_u232_set_modem_ctrl(serial, control_state);
671 mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
673 if ((cflag & CBAUD) == B0) {
674 dbg("%s: baud is B0", __func__);
675 /* Drop RTS and DTR */
676 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
677 mct_u232_set_modem_ctrl(serial, control_state);
681 * Update line control register (LCR)
684 /* set the parity */
685 if (cflag & PARENB)
686 last_lcr |= (cflag & PARODD) ?
687 MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
688 else
689 last_lcr |= MCT_U232_PARITY_NONE;
691 /* set the number of data bits */
692 switch (cflag & CSIZE) {
693 case CS5:
694 last_lcr |= MCT_U232_DATA_BITS_5; break;
695 case CS6:
696 last_lcr |= MCT_U232_DATA_BITS_6; break;
697 case CS7:
698 last_lcr |= MCT_U232_DATA_BITS_7; break;
699 case CS8:
700 last_lcr |= MCT_U232_DATA_BITS_8; break;
701 default:
702 dev_err(&port->dev,
703 "CSIZE was not CS5-CS8, using default of 8\n");
704 last_lcr |= MCT_U232_DATA_BITS_8;
705 break;
708 termios->c_cflag &= ~CMSPAR;
710 /* set the number of stop bits */
711 last_lcr |= (cflag & CSTOPB) ?
712 MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
714 mct_u232_set_line_ctrl(serial, last_lcr);
716 /* save off the modified port settings */
717 spin_lock_irqsave(&priv->lock, flags);
718 priv->control_state = control_state;
719 priv->last_lcr = last_lcr;
720 spin_unlock_irqrestore(&priv->lock, flags);
721 } /* mct_u232_set_termios */
723 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
725 struct usb_serial_port *port = tty->driver_data;
726 struct usb_serial *serial = port->serial;
727 struct mct_u232_private *priv = usb_get_serial_port_data(port);
728 unsigned char lcr;
729 unsigned long flags;
731 spin_lock_irqsave(&priv->lock, flags);
732 lcr = priv->last_lcr;
734 if (break_state)
735 lcr |= MCT_U232_SET_BREAK;
736 spin_unlock_irqrestore(&priv->lock, flags);
738 mct_u232_set_line_ctrl(serial, lcr);
739 } /* mct_u232_break_ctl */
742 static int mct_u232_tiocmget(struct tty_struct *tty)
744 struct usb_serial_port *port = tty->driver_data;
745 struct mct_u232_private *priv = usb_get_serial_port_data(port);
746 unsigned int control_state;
747 unsigned long flags;
749 spin_lock_irqsave(&priv->lock, flags);
750 control_state = priv->control_state;
751 spin_unlock_irqrestore(&priv->lock, flags);
753 return control_state;
756 static int mct_u232_tiocmset(struct tty_struct *tty,
757 unsigned int set, unsigned int clear)
759 struct usb_serial_port *port = tty->driver_data;
760 struct usb_serial *serial = port->serial;
761 struct mct_u232_private *priv = usb_get_serial_port_data(port);
762 unsigned int control_state;
763 unsigned long flags;
765 spin_lock_irqsave(&priv->lock, flags);
766 control_state = priv->control_state;
768 if (set & TIOCM_RTS)
769 control_state |= TIOCM_RTS;
770 if (set & TIOCM_DTR)
771 control_state |= TIOCM_DTR;
772 if (clear & TIOCM_RTS)
773 control_state &= ~TIOCM_RTS;
774 if (clear & TIOCM_DTR)
775 control_state &= ~TIOCM_DTR;
777 priv->control_state = control_state;
778 spin_unlock_irqrestore(&priv->lock, flags);
779 return mct_u232_set_modem_ctrl(serial, control_state);
782 static void mct_u232_throttle(struct tty_struct *tty)
784 struct usb_serial_port *port = tty->driver_data;
785 struct mct_u232_private *priv = usb_get_serial_port_data(port);
786 unsigned int control_state;
788 spin_lock_irq(&priv->lock);
789 priv->rx_flags |= THROTTLED;
790 if (C_CRTSCTS(tty)) {
791 priv->control_state &= ~TIOCM_RTS;
792 control_state = priv->control_state;
793 spin_unlock_irq(&priv->lock);
794 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
795 } else {
796 spin_unlock_irq(&priv->lock);
800 static void mct_u232_unthrottle(struct tty_struct *tty)
802 struct usb_serial_port *port = tty->driver_data;
803 struct mct_u232_private *priv = usb_get_serial_port_data(port);
804 unsigned int control_state;
806 spin_lock_irq(&priv->lock);
807 if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
808 priv->rx_flags &= ~THROTTLED;
809 priv->control_state |= TIOCM_RTS;
810 control_state = priv->control_state;
811 spin_unlock_irq(&priv->lock);
812 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
813 } else {
814 spin_unlock_irq(&priv->lock);
818 static int mct_u232_ioctl(struct tty_struct *tty,
819 unsigned int cmd, unsigned long arg)
821 DEFINE_WAIT(wait);
822 struct usb_serial_port *port = tty->driver_data;
823 struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port);
824 struct async_icount cnow, cprev;
825 unsigned long flags;
827 dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
829 switch (cmd) {
831 case TIOCMIWAIT:
833 dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
835 spin_lock_irqsave(&mct_u232_port->lock, flags);
836 cprev = mct_u232_port->icount;
837 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
838 for ( ; ; ) {
839 prepare_to_wait(&mct_u232_port->msr_wait,
840 &wait, TASK_INTERRUPTIBLE);
841 schedule();
842 finish_wait(&mct_u232_port->msr_wait, &wait);
843 /* see if a signal did it */
844 if (signal_pending(current))
845 return -ERESTARTSYS;
846 spin_lock_irqsave(&mct_u232_port->lock, flags);
847 cnow = mct_u232_port->icount;
848 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
849 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
850 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
851 return -EIO; /* no change => error */
852 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
853 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
854 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
855 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
856 return 0;
858 cprev = cnow;
862 return -ENOIOCTLCMD;
865 static int mct_u232_get_icount(struct tty_struct *tty,
866 struct serial_icounter_struct *icount)
868 struct usb_serial_port *port = tty->driver_data;
869 struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port);
870 struct async_icount *ic = &mct_u232_port->icount;
871 unsigned long flags;
873 spin_lock_irqsave(&mct_u232_port->lock, flags);
875 icount->cts = ic->cts;
876 icount->dsr = ic->dsr;
877 icount->rng = ic->rng;
878 icount->dcd = ic->dcd;
879 icount->rx = ic->rx;
880 icount->tx = ic->tx;
881 icount->frame = ic->frame;
882 icount->overrun = ic->overrun;
883 icount->parity = ic->parity;
884 icount->brk = ic->brk;
885 icount->buf_overrun = ic->buf_overrun;
887 spin_unlock_irqrestore(&mct_u232_port->lock, flags);
889 dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d",
890 __func__, port->number, icount->rx, icount->tx);
891 return 0;
894 module_usb_serial_driver(serial_drivers, id_table);
896 MODULE_AUTHOR(DRIVER_AUTHOR);
897 MODULE_DESCRIPTION(DRIVER_DESC);
898 MODULE_LICENSE("GPL");
900 module_param(debug, bool, S_IRUGO | S_IWUSR);
901 MODULE_PARM_DESC(debug, "Debug enabled or not");