aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/serial/cypress_m8.c185
1 files changed, 88 insertions, 97 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 9db23decc5bd..f34a9bb6a219 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -16,6 +16,14 @@
16 * See http://geocities.com/i0xox0i for information on this driver and the 16 * See http://geocities.com/i0xox0i for information on this driver and the
17 * earthmate usb device. 17 * earthmate usb device.
18 * 18 *
19 * Lonnie Mendez <dignome@gmail.com>
20 * 4-29-2005
21 * Fixed problem where setting or retreiving the serial config would fail with
22 * EPIPE. Removed CRTS toggling so the driver behaves more like other usbserial
23 * adapters. Issued new interval of 1ms instead of the default 10ms. As a
24 * result, transfer speed has been substantially increased. From avg. 850bps to
25 * avg. 3300bps. initial termios has also been modified. Cleaned up code and
26 * formatting issues so it is more readable. Replaced the C++ style comments.
19 * 27 *
20 * Lonnie Mendez <dignome@gmail.com> 28 * Lonnie Mendez <dignome@gmail.com>
21 * 12-15-2004 29 * 12-15-2004
@@ -32,12 +40,6 @@
32 * 10-2003 40 * 10-2003
33 * Driver first released. 41 * Driver first released.
34 * 42 *
35 *
36 * Long Term TODO:
37 * Improve transfer speeds - both read/write are somewhat slow
38 * at this point.
39 * Improve debugging. Show modem line status with debug output and
40 * implement filtering for certain data as a module parameter.
41 */ 43 */
42 44
43/* Thanks to Neil Whelchel for writing the first cypress m8 implementation for linux. */ 45/* Thanks to Neil Whelchel for writing the first cypress m8 implementation for linux. */
@@ -72,11 +74,12 @@
72 static int debug; 74 static int debug;
73#endif 75#endif
74static int stats; 76static int stats;
77static int interval;
75 78
76/* 79/*
77 * Version Information 80 * Version Information
78 */ 81 */
79#define DRIVER_VERSION "v1.08" 82#define DRIVER_VERSION "v1.09"
80#define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>" 83#define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>"
81#define DRIVER_DESC "Cypress USB to Serial Driver" 84#define DRIVER_DESC "Cypress USB to Serial Driver"
82 85
@@ -130,7 +133,6 @@ struct cypress_private {
130 char prev_status, diff_status; /* used for TIOCMIWAIT */ 133 char prev_status, diff_status; /* used for TIOCMIWAIT */
131 /* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */ 134 /* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
132 struct termios tmp_termios; /* stores the old termios settings */ 135 struct termios tmp_termios; /* stores the old termios settings */
133 char calledfromopen; /* used when issuing lines on open - fixes rts drop bug */
134}; 136};
135 137
136/* write buffer structure */ 138/* write buffer structure */
@@ -168,10 +170,8 @@ static void cypress_buf_free(struct cypress_buf *cb);
168static void cypress_buf_clear(struct cypress_buf *cb); 170static void cypress_buf_clear(struct cypress_buf *cb);
169static unsigned int cypress_buf_data_avail(struct cypress_buf *cb); 171static unsigned int cypress_buf_data_avail(struct cypress_buf *cb);
170static unsigned int cypress_buf_space_avail(struct cypress_buf *cb); 172static unsigned int cypress_buf_space_avail(struct cypress_buf *cb);
171static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, 173static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, unsigned int count);
172 unsigned int count); 174static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count);
173static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf,
174 unsigned int count);
175 175
176 176
177static struct usb_serial_device_type cypress_earthmate_device = { 177static struct usb_serial_device_type cypress_earthmate_device = {
@@ -238,10 +238,9 @@ static struct usb_serial_device_type cypress_hidcom_device = {
238static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_mask, int data_bits, int stop_bits, 238static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_mask, int data_bits, int stop_bits,
239 int parity_enable, int parity_type, int reset, int cypress_request_type) 239 int parity_enable, int parity_type, int reset, int cypress_request_type)
240{ 240{
241 int i, n_baud_rate = 0, retval = 0; 241 int new_baudrate = 0, retval = 0, tries = 0;
242 struct cypress_private *priv; 242 struct cypress_private *priv;
243 __u8 feature_buffer[5]; 243 __u8 feature_buffer[8];
244 __u8 config;
245 unsigned long flags; 244 unsigned long flags;
246 245
247 dbg("%s", __FUNCTION__); 246 dbg("%s", __FUNCTION__);
@@ -256,7 +255,8 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m
256 * of 57600bps (I have no idea whether DeLorme chose to use the general purpose 255 * of 57600bps (I have no idea whether DeLorme chose to use the general purpose
257 * firmware or not), if you need to modify this speed setting for your own 256 * firmware or not), if you need to modify this speed setting for your own
258 * project please add your own chiptype and modify the code likewise. The 257 * project please add your own chiptype and modify the code likewise. The
259 * Cypress HID->COM device will work successfully up to 115200bps. 258 * Cypress HID->COM device will work successfully up to 115200bps (but the
259 * actual throughput is around 3kBps).
260 */ 260 */
261 if (baud_mask != priv->cbr_mask) { 261 if (baud_mask != priv->cbr_mask) {
262 dbg("%s - baud rate is changing", __FUNCTION__); 262 dbg("%s - baud rate is changing", __FUNCTION__);
@@ -265,109 +265,114 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m
265 * but are not used with NMEA and SiRF protocols */ 265 * but are not used with NMEA and SiRF protocols */
266 266
267 if ( (baud_mask == B300) || (baud_mask == B600) ) { 267 if ( (baud_mask == B300) || (baud_mask == B600) ) {
268 err("%s - failed setting baud rate, unsupported speed (default to 4800)", 268 err("%s - failed setting baud rate, unsupported speed",
269 __FUNCTION__); 269 __FUNCTION__);
270 n_baud_rate = 4800; 270 new_baudrate = priv->baud_rate;
271 } else if ( (n_baud_rate = mask_to_rate(baud_mask)) == -1) { 271 } else if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
272 err("%s - failed setting baud rate, unsupported speed (default to 4800)", 272 err("%s - failed setting baud rate, unsupported speed",
273 __FUNCTION__); 273 __FUNCTION__);
274 n_baud_rate = 4800; 274 new_baudrate = priv->baud_rate;
275 } 275 }
276 } else if (priv->chiptype == CT_CYPHIDCOM) { 276 } else if (priv->chiptype == CT_CYPHIDCOM) {
277 if ( (n_baud_rate = mask_to_rate(baud_mask)) == -1) { 277 if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
278 err("%s - failed setting baud rate, unsupported speed (default to 4800)", 278 err("%s - failed setting baud rate, unsupported speed",
279 __FUNCTION__); 279 __FUNCTION__);
280 n_baud_rate = 4800; 280 new_baudrate = priv->baud_rate;
281 } 281 }
282 } else if (priv->chiptype == CT_GENERIC) { 282 } else if (priv->chiptype == CT_GENERIC) {
283 if ( (n_baud_rate = mask_to_rate(baud_mask)) == -1) { 283 if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
284 err("%s - failed setting baud rate, unsupported speed (default to 4800)", 284 err("%s - failed setting baud rate, unsupported speed",
285 __FUNCTION__); 285 __FUNCTION__);
286 n_baud_rate = 4800; 286 new_baudrate = priv->baud_rate;
287 } 287 }
288 } else { 288 } else {
289 info("%s - please define your chiptype, using 4800bps default", __FUNCTION__); 289 info("%s - please define your chiptype", __FUNCTION__);
290 n_baud_rate = 4800; 290 new_baudrate = priv->baud_rate;
291 } 291 }
292 } else { /* baud rate not changing, keep the old */ 292 } else { /* baud rate not changing, keep the old */
293 n_baud_rate = priv->baud_rate; 293 new_baudrate = priv->baud_rate;
294 } 294 }
295 dbg("%s - baud rate is being sent as %d", __FUNCTION__, n_baud_rate); 295 dbg("%s - baud rate is being sent as %d", __FUNCTION__, new_baudrate);
296
297 296
298 /* 297 memset(feature_buffer, 0, 8);
299 * This algorithm accredited to Jiang Jay Zhang... thanks for all the help! 298 /* fill the feature_buffer with new configuration */
300 */ 299 *((u_int32_t *)feature_buffer) = new_baudrate;
301 for (i = 0; i < 4; ++i) {
302 feature_buffer[i] = ( n_baud_rate >> (i*8) & 0xFF );
303 }
304 300
305 config = 0; // reset config byte 301 feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */
306 config |= data_bits; // assign data bits in 2 bit space ( max 3 )
307 /* 1 bit gap */ 302 /* 1 bit gap */
308 config |= (stop_bits << 3); // assign stop bits in 1 bit space 303 feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */
309 config |= (parity_enable << 4); // assign parity flag in 1 bit space 304 feature_buffer[4] |= (parity_enable << 4); /* assign parity flag in 1 bit space */
310 config |= (parity_type << 5); // assign parity type in 1 bit space 305 feature_buffer[4] |= (parity_type << 5); /* assign parity type in 1 bit space */
311 /* 1 bit gap */ 306 /* 1 bit gap */
312 config |= (reset << 7); // assign reset at end of byte, 1 bit space 307 feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */
313
314 feature_buffer[4] = config;
315 308
316 dbg("%s - device is being sent this feature report:", __FUNCTION__); 309 dbg("%s - device is being sent this feature report:", __FUNCTION__);
317 dbg("%s - %02X - %02X - %02X - %02X - %02X", __FUNCTION__, feature_buffer[0], feature_buffer[1], 310 dbg("%s - %02X - %02X - %02X - %02X - %02X", __FUNCTION__, feature_buffer[0], feature_buffer[1],
318 feature_buffer[2], feature_buffer[3], feature_buffer[4]); 311 feature_buffer[2], feature_buffer[3], feature_buffer[4]);
319 312
313 do {
320 retval = usb_control_msg (port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), 314 retval = usb_control_msg (port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
321 HID_REQ_SET_REPORT, USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS, 315 HID_REQ_SET_REPORT, USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
322 0x0300, 0, feature_buffer, 5, 500); 316 0x0300, 0, feature_buffer, 8, 500);
317
318 if (tries++ >= 3)
319 break;
323 320
324 if (retval != 5) 321 if (retval == EPIPE)
322 usb_clear_halt(port->serial->dev, 0x00);
323 } while (retval != 8 && retval != ENODEV);
324
325 if (retval != 8)
325 err("%s - failed sending serial line settings - %d", __FUNCTION__, retval); 326 err("%s - failed sending serial line settings - %d", __FUNCTION__, retval);
326 else { 327 else {
327 spin_lock_irqsave(&priv->lock, flags); 328 spin_lock_irqsave(&priv->lock, flags);
328 priv->baud_rate = n_baud_rate; 329 priv->baud_rate = new_baudrate;
329 priv->cbr_mask = baud_mask; 330 priv->cbr_mask = baud_mask;
330 priv->current_config = config; 331 priv->current_config = feature_buffer[4];
331 ++priv->cmd_count;
332 spin_unlock_irqrestore(&priv->lock, flags); 332 spin_unlock_irqrestore(&priv->lock, flags);
333 } 333 }
334 break; 334 break;
335 case CYPRESS_GET_CONFIG: 335 case CYPRESS_GET_CONFIG:
336 dbg("%s - retreiving serial line settings", __FUNCTION__); 336 dbg("%s - retreiving serial line settings", __FUNCTION__);
337 /* reset values in feature buffer */ 337 /* set initial values in feature buffer */
338 memset(feature_buffer, 0, 5); 338 memset(feature_buffer, 0, 8);
339 339
340 do {
340 retval = usb_control_msg (port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), 341 retval = usb_control_msg (port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0),
341 HID_REQ_GET_REPORT, USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS, 342 HID_REQ_GET_REPORT, USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
342 0x0300, 0, feature_buffer, 5, 500); 343 0x0300, 0, feature_buffer, 8, 500);
344
345 if (tries++ >= 3)
346 break;
347
348 if (retval == EPIPE)
349 usb_clear_halt(port->serial->dev, 0x00);
350 } while (retval != 5 && retval != ENODEV);
351
343 if (retval != 5) { 352 if (retval != 5) {
344 err("%s - failed to retreive serial line settings - %d", __FUNCTION__, retval); 353 err("%s - failed to retreive serial line settings - %d", __FUNCTION__, retval);
345 return retval; 354 return retval;
346 } else { 355 } else {
347 spin_lock_irqsave(&priv->lock, flags); 356 spin_lock_irqsave(&priv->lock, flags);
357
348 /* store the config in one byte, and later use bit masks to check values */ 358 /* store the config in one byte, and later use bit masks to check values */
349 priv->current_config = feature_buffer[4]; 359 priv->current_config = feature_buffer[4];
350 /* reverse the process above to get the baud_mask value */ 360 priv->baud_rate = *((u_int32_t *)feature_buffer);
351 n_baud_rate = 0; // reset bits
352 for (i = 0; i < 4; ++i) {
353 n_baud_rate |= ( feature_buffer[i] << (i*8) );
354 }
355 361
356 priv->baud_rate = n_baud_rate; 362 if ( (priv->cbr_mask = rate_to_mask(priv->baud_rate)) == 0x40)
357 if ( (priv->cbr_mask = rate_to_mask(n_baud_rate)) == 0x40)
358 dbg("%s - failed setting the baud mask (not defined)", __FUNCTION__); 363 dbg("%s - failed setting the baud mask (not defined)", __FUNCTION__);
359 ++priv->cmd_count;
360 spin_unlock_irqrestore(&priv->lock, flags); 364 spin_unlock_irqrestore(&priv->lock, flags);
361 } 365 }
362 break;
363 default:
364 err("%s - unsupported serial control command issued", __FUNCTION__);
365 } 366 }
367 spin_lock_irqsave(&priv->lock, flags);
368 ++priv->cmd_count;
369 spin_unlock_irqrestore(&priv->lock, flags);
370
366 return retval; 371 return retval;
367} /* cypress_serial_control */ 372} /* cypress_serial_control */
368 373
369 374
370/* given a baud mask, it will return speed on success */ 375/* given a baud mask, it will return integer baud on success */
371static int mask_to_rate (unsigned mask) 376static int mask_to_rate (unsigned mask)
372{ 377{
373 int rate; 378 int rate;
@@ -438,11 +443,12 @@ static int generic_startup (struct usb_serial *serial)
438 443
439 usb_reset_configuration (serial->dev); 444 usb_reset_configuration (serial->dev);
440 445
446 interval = 1;
441 priv->cmd_ctrl = 0; 447 priv->cmd_ctrl = 0;
442 priv->line_control = 0; 448 priv->line_control = 0;
443 priv->termios_initialized = 0; 449 priv->termios_initialized = 0;
444 priv->calledfromopen = 0;
445 priv->rx_flags = 0; 450 priv->rx_flags = 0;
451 priv->cbr_mask = B300;
446 usb_set_serial_port_data(serial->port[0], priv); 452 usb_set_serial_port_data(serial->port[0], priv);
447 453
448 return (0); 454 return (0);
@@ -513,7 +519,6 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
513 dbg("%s - port %d", __FUNCTION__, port->number); 519 dbg("%s - port %d", __FUNCTION__, port->number);
514 520
515 /* clear halts before open */ 521 /* clear halts before open */
516 usb_clear_halt(serial->dev, 0x00);
517 usb_clear_halt(serial->dev, 0x81); 522 usb_clear_halt(serial->dev, 0x81);
518 usb_clear_halt(serial->dev, 0x02); 523 usb_clear_halt(serial->dev, 0x02);
519 524
@@ -531,7 +536,6 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
531 /* raise both lines and set termios */ 536 /* raise both lines and set termios */
532 spin_lock_irqsave(&priv->lock, flags); 537 spin_lock_irqsave(&priv->lock, flags);
533 priv->line_control = CONTROL_DTR | CONTROL_RTS; 538 priv->line_control = CONTROL_DTR | CONTROL_RTS;
534 priv->calledfromopen = 1;
535 priv->cmd_ctrl = 1; 539 priv->cmd_ctrl = 1;
536 spin_unlock_irqrestore(&priv->lock, flags); 540 spin_unlock_irqrestore(&priv->lock, flags);
537 result = cypress_write(port, NULL, 0); 541 result = cypress_write(port, NULL, 0);
@@ -553,7 +557,7 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
553 usb_fill_int_urb(port->interrupt_in_urb, serial->dev, 557 usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
554 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress), 558 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
555 port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length, 559 port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length,
556 cypress_read_int_callback, port, port->interrupt_in_urb->interval); 560 cypress_read_int_callback, port, interval);
557 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 561 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
558 562
559 if (result){ 563 if (result){
@@ -680,12 +684,12 @@ static void cypress_send(struct usb_serial_port *port)
680 spin_lock_irqsave(&priv->lock, flags); 684 spin_lock_irqsave(&priv->lock, flags);
681 switch (port->interrupt_out_size) { 685 switch (port->interrupt_out_size) {
682 case 32: 686 case 32:
683 // this is for the CY7C64013... 687 /* this is for the CY7C64013... */
684 offset = 2; 688 offset = 2;
685 port->interrupt_out_buffer[0] = priv->line_control; 689 port->interrupt_out_buffer[0] = priv->line_control;
686 break; 690 break;
687 case 8: 691 case 8:
688 // this is for the CY7C63743... 692 /* this is for the CY7C63743... */
689 offset = 1; 693 offset = 1;
690 port->interrupt_out_buffer[0] = priv->line_control; 694 port->interrupt_out_buffer[0] = priv->line_control;
691 break; 695 break;
@@ -738,6 +742,7 @@ send:
738 742
739 port->interrupt_out_urb->transfer_buffer_length = actual_size; 743 port->interrupt_out_urb->transfer_buffer_length = actual_size;
740 port->interrupt_out_urb->dev = port->serial->dev; 744 port->interrupt_out_urb->dev = port->serial->dev;
745 port->interrupt_out_urb->interval = interval;
741 result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC); 746 result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC);
742 if (result) { 747 if (result) {
743 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, 748 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__,
@@ -910,7 +915,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
910 unsigned cflag, iflag, baud_mask; 915 unsigned cflag, iflag, baud_mask;
911 unsigned long flags; 916 unsigned long flags;
912 __u8 oldlines; 917 __u8 oldlines;
913 int linechange; 918 int linechange = 0;
914 919
915 dbg("%s - port %d", __FUNCTION__, port->number); 920 dbg("%s - port %d", __FUNCTION__, port->number);
916 921
@@ -996,15 +1001,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
996 case B115200: dbg("%s - setting baud 115200bps", __FUNCTION__); break; 1001 case B115200: dbg("%s - setting baud 115200bps", __FUNCTION__); break;
997 default: dbg("%s - unknown masked baud rate", __FUNCTION__); 1002 default: dbg("%s - unknown masked baud rate", __FUNCTION__);
998 } 1003 }
999 priv->line_control |= CONTROL_DTR; 1004 priv->line_control = (CONTROL_DTR | CONTROL_RTS);
1000
1001 /* toggle CRTSCTS? - don't do this if being called from cypress_open */
1002 if (!priv->calledfromopen) {
1003 if (cflag & CRTSCTS)
1004 priv->line_control |= CONTROL_RTS;
1005 else
1006 priv->line_control &= ~CONTROL_RTS;
1007 }
1008 } 1005 }
1009 spin_unlock_irqrestore(&priv->lock, flags); 1006 spin_unlock_irqrestore(&priv->lock, flags);
1010 1007
@@ -1014,8 +1011,6 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
1014 cypress_serial_control(port, baud_mask, data_bits, stop_bits, parity_enable, 1011 cypress_serial_control(port, baud_mask, data_bits, stop_bits, parity_enable,
1015 parity_type, 0, CYPRESS_SET_CONFIG); 1012 parity_type, 0, CYPRESS_SET_CONFIG);
1016 1013
1017 msleep(50); /* give some time between change and read (50ms) */
1018
1019 /* we perform a CYPRESS_GET_CONFIG so that the current settings are filled into the private structure 1014 /* we perform a CYPRESS_GET_CONFIG so that the current settings are filled into the private structure
1020 * this should confirm that all is working if it returns what we just set */ 1015 * this should confirm that all is working if it returns what we just set */
1021 cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG); 1016 cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
@@ -1031,7 +1026,6 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
1031 dbg("Using custom termios settings for a baud rate of 4800bps."); 1026 dbg("Using custom termios settings for a baud rate of 4800bps.");
1032 /* define custom termios settings for NMEA protocol */ 1027 /* define custom termios settings for NMEA protocol */
1033 1028
1034
1035 tty->termios->c_iflag /* input modes - */ 1029 tty->termios->c_iflag /* input modes - */
1036 &= ~(IGNBRK /* disable ignore break */ 1030 &= ~(IGNBRK /* disable ignore break */
1037 | BRKINT /* disable break causes interrupt */ 1031 | BRKINT /* disable break causes interrupt */
@@ -1052,23 +1046,16 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
1052 | ISIG /* disable interrupt, quit, and suspend special characters */ 1046 | ISIG /* disable interrupt, quit, and suspend special characters */
1053 | IEXTEN); /* disable non-POSIX special characters */ 1047 | IEXTEN); /* disable non-POSIX special characters */
1054 1048
1055 } else if (priv->chiptype == CT_CYPHIDCOM) { 1049 } /* CT_CYPHIDCOM: Application should handle this for device */
1056
1057 // Software app handling it for device...
1058 1050
1059 }
1060 linechange = (priv->line_control != oldlines); 1051 linechange = (priv->line_control != oldlines);
1061 spin_unlock_irqrestore(&priv->lock, flags); 1052 spin_unlock_irqrestore(&priv->lock, flags);
1062 1053
1063 /* if necessary, set lines */ 1054 /* if necessary, set lines */
1064 if (!priv->calledfromopen && linechange) { 1055 if (linechange) {
1065 priv->cmd_ctrl = 1; 1056 priv->cmd_ctrl = 1;
1066 cypress_write(port, NULL, 0); 1057 cypress_write(port, NULL, 0);
1067 } 1058 }
1068
1069 if (priv->calledfromopen)
1070 priv->calledfromopen = 0;
1071
1072} /* cypress_set_termios */ 1059} /* cypress_set_termios */
1073 1060
1074 1061
@@ -1164,7 +1151,7 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
1164 spin_lock_irqsave(&priv->lock, flags); 1151 spin_lock_irqsave(&priv->lock, flags);
1165 switch(urb->actual_length) { 1152 switch(urb->actual_length) {
1166 case 32: 1153 case 32:
1167 // This is for the CY7C64013... 1154 /* This is for the CY7C64013... */
1168 priv->current_status = data[0] & 0xF8; 1155 priv->current_status = data[0] & 0xF8;
1169 bytes = data[1]+2; 1156 bytes = data[1]+2;
1170 i=2; 1157 i=2;
@@ -1172,7 +1159,7 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
1172 havedata = 1; 1159 havedata = 1;
1173 break; 1160 break;
1174 case 8: 1161 case 8:
1175 // This is for the CY7C63743... 1162 /* This is for the CY7C63743... */
1176 priv->current_status = data[0] & 0xF8; 1163 priv->current_status = data[0] & 0xF8;
1177 bytes = (data[0] & 0x07)+1; 1164 bytes = (data[0] & 0x07)+1;
1178 i=1; 1165 i=1;
@@ -1245,7 +1232,7 @@ continue_read:
1245 port->interrupt_in_urb->transfer_buffer, 1232 port->interrupt_in_urb->transfer_buffer,
1246 port->interrupt_in_urb->transfer_buffer_length, 1233 port->interrupt_in_urb->transfer_buffer_length,
1247 cypress_read_int_callback, port, 1234 cypress_read_int_callback, port,
1248 port->interrupt_in_urb->interval); 1235 interval);
1249 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 1236 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
1250 if (result) 1237 if (result)
1251 dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); 1238 dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
@@ -1274,6 +1261,8 @@ static void cypress_write_int_callback(struct urb *urb, struct pt_regs *regs)
1274 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 1261 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
1275 priv->write_urb_in_use = 0; 1262 priv->write_urb_in_use = 0;
1276 return; 1263 return;
1264 case -EPIPE: /* no break needed */
1265 usb_clear_halt(port->serial->dev, 0x02);
1277 default: 1266 default:
1278 /* error in the urb, so we have to resubmit it */ 1267 /* error in the urb, so we have to resubmit it */
1279 dbg("%s - Overflow in write", __FUNCTION__); 1268 dbg("%s - Overflow in write", __FUNCTION__);
@@ -1535,3 +1524,5 @@ module_param(debug, bool, S_IRUGO | S_IWUSR);
1535MODULE_PARM_DESC(debug, "Debug enabled or not"); 1524MODULE_PARM_DESC(debug, "Debug enabled or not");
1536module_param(stats, bool, S_IRUGO | S_IWUSR); 1525module_param(stats, bool, S_IRUGO | S_IWUSR);
1537MODULE_PARM_DESC(stats, "Enable statistics or not"); 1526MODULE_PARM_DESC(stats, "Enable statistics or not");
1527module_param(interval, int, S_IRUGO | S_IWUSR);
1528MODULE_PARM_DESC(interval, "Overrides interrupt interval");