aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/cypress_m8.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/cypress_m8.c')
-rw-r--r--drivers/usb/serial/cypress_m8.c189
1 files changed, 91 insertions, 98 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index d165f42d560d..012e63e05806 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
@@ -86,6 +89,7 @@ static int stats;
86 89
87static struct usb_device_id id_table_earthmate [] = { 90static struct usb_device_id id_table_earthmate [] = {
88 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, 91 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
92 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
89 { } /* Terminating entry */ 93 { } /* Terminating entry */
90}; 94};
91 95
@@ -96,6 +100,7 @@ static struct usb_device_id id_table_cyphidcomrs232 [] = {
96 100
97static struct usb_device_id id_table_combined [] = { 101static struct usb_device_id id_table_combined [] = {
98 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, 102 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
103 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
99 { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, 104 { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
100 { } /* Terminating entry */ 105 { } /* Terminating entry */
101}; 106};
@@ -130,7 +135,6 @@ struct cypress_private {
130 char prev_status, diff_status; /* used for TIOCMIWAIT */ 135 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 */ 136 /* 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 */ 137 struct termios tmp_termios; /* stores the old termios settings */
133 char calledfromopen; /* used when issuing lines on open - fixes rts drop bug */
134}; 138};
135 139
136/* write buffer structure */ 140/* write buffer structure */
@@ -168,10 +172,8 @@ static void cypress_buf_free(struct cypress_buf *cb);
168static void cypress_buf_clear(struct cypress_buf *cb); 172static void cypress_buf_clear(struct cypress_buf *cb);
169static unsigned int cypress_buf_data_avail(struct cypress_buf *cb); 173static unsigned int cypress_buf_data_avail(struct cypress_buf *cb);
170static unsigned int cypress_buf_space_avail(struct cypress_buf *cb); 174static unsigned int cypress_buf_space_avail(struct cypress_buf *cb);
171static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, 175static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, unsigned int count);
172 unsigned int count); 176static 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 177
176 178
177static struct usb_serial_device_type cypress_earthmate_device = { 179static struct usb_serial_device_type cypress_earthmate_device = {
@@ -234,14 +236,13 @@ static struct usb_serial_device_type cypress_hidcom_device = {
234 *****************************************************************************/ 236 *****************************************************************************/
235 237
236 238
237/* This function can either set or retreive the current serial line settings */ 239/* This function can either set or retrieve the current serial line settings */
238static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_mask, int data_bits, int stop_bits, 240static 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) 241 int parity_enable, int parity_type, int reset, int cypress_request_type)
240{ 242{
241 int i, n_baud_rate = 0, retval = 0; 243 int new_baudrate = 0, retval = 0, tries = 0;
242 struct cypress_private *priv; 244 struct cypress_private *priv;
243 __u8 feature_buffer[5]; 245 __u8 feature_buffer[8];
244 __u8 config;
245 unsigned long flags; 246 unsigned long flags;
246 247
247 dbg("%s", __FUNCTION__); 248 dbg("%s", __FUNCTION__);
@@ -256,7 +257,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 257 * 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 258 * 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 259 * project please add your own chiptype and modify the code likewise. The
259 * Cypress HID->COM device will work successfully up to 115200bps. 260 * Cypress HID->COM device will work successfully up to 115200bps (but the
261 * actual throughput is around 3kBps).
260 */ 262 */
261 if (baud_mask != priv->cbr_mask) { 263 if (baud_mask != priv->cbr_mask) {
262 dbg("%s - baud rate is changing", __FUNCTION__); 264 dbg("%s - baud rate is changing", __FUNCTION__);
@@ -265,109 +267,114 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m
265 * but are not used with NMEA and SiRF protocols */ 267 * but are not used with NMEA and SiRF protocols */
266 268
267 if ( (baud_mask == B300) || (baud_mask == B600) ) { 269 if ( (baud_mask == B300) || (baud_mask == B600) ) {
268 err("%s - failed setting baud rate, unsupported speed (default to 4800)", 270 err("%s - failed setting baud rate, unsupported speed",
269 __FUNCTION__); 271 __FUNCTION__);
270 n_baud_rate = 4800; 272 new_baudrate = priv->baud_rate;
271 } else if ( (n_baud_rate = mask_to_rate(baud_mask)) == -1) { 273 } else if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
272 err("%s - failed setting baud rate, unsupported speed (default to 4800)", 274 err("%s - failed setting baud rate, unsupported speed",
273 __FUNCTION__); 275 __FUNCTION__);
274 n_baud_rate = 4800; 276 new_baudrate = priv->baud_rate;
275 } 277 }
276 } else if (priv->chiptype == CT_CYPHIDCOM) { 278 } else if (priv->chiptype == CT_CYPHIDCOM) {
277 if ( (n_baud_rate = mask_to_rate(baud_mask)) == -1) { 279 if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
278 err("%s - failed setting baud rate, unsupported speed (default to 4800)", 280 err("%s - failed setting baud rate, unsupported speed",
279 __FUNCTION__); 281 __FUNCTION__);
280 n_baud_rate = 4800; 282 new_baudrate = priv->baud_rate;
281 } 283 }
282 } else if (priv->chiptype == CT_GENERIC) { 284 } else if (priv->chiptype == CT_GENERIC) {
283 if ( (n_baud_rate = mask_to_rate(baud_mask)) == -1) { 285 if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
284 err("%s - failed setting baud rate, unsupported speed (default to 4800)", 286 err("%s - failed setting baud rate, unsupported speed",
285 __FUNCTION__); 287 __FUNCTION__);
286 n_baud_rate = 4800; 288 new_baudrate = priv->baud_rate;
287 } 289 }
288 } else { 290 } else {
289 info("%s - please define your chiptype, using 4800bps default", __FUNCTION__); 291 info("%s - please define your chiptype", __FUNCTION__);
290 n_baud_rate = 4800; 292 new_baudrate = priv->baud_rate;
291 } 293 }
292 } else { /* baud rate not changing, keep the old */ 294 } else { /* baud rate not changing, keep the old */
293 n_baud_rate = priv->baud_rate; 295 new_baudrate = priv->baud_rate;
294 } 296 }
295 dbg("%s - baud rate is being sent as %d", __FUNCTION__, n_baud_rate); 297 dbg("%s - baud rate is being sent as %d", __FUNCTION__, new_baudrate);
296
297 298
298 /* 299 memset(feature_buffer, 0, 8);
299 * This algorithm accredited to Jiang Jay Zhang... thanks for all the help! 300 /* fill the feature_buffer with new configuration */
300 */ 301 *((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 302
305 config = 0; // reset config byte 303 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 */ 304 /* 1 bit gap */
308 config |= (stop_bits << 3); // assign stop bits in 1 bit space 305 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 306 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 307 feature_buffer[4] |= (parity_type << 5); /* assign parity type in 1 bit space */
311 /* 1 bit gap */ 308 /* 1 bit gap */
312 config |= (reset << 7); // assign reset at end of byte, 1 bit space 309 feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */
313
314 feature_buffer[4] = config;
315 310
316 dbg("%s - device is being sent this feature report:", __FUNCTION__); 311 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], 312 dbg("%s - %02X - %02X - %02X - %02X - %02X", __FUNCTION__, feature_buffer[0], feature_buffer[1],
318 feature_buffer[2], feature_buffer[3], feature_buffer[4]); 313 feature_buffer[2], feature_buffer[3], feature_buffer[4]);
319 314
315 do {
320 retval = usb_control_msg (port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), 316 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, 317 HID_REQ_SET_REPORT, USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
322 0x0300, 0, feature_buffer, 5, 500); 318 0x0300, 0, feature_buffer, 8, 500);
319
320 if (tries++ >= 3)
321 break;
323 322
324 if (retval != 5) 323 if (retval == EPIPE)
324 usb_clear_halt(port->serial->dev, 0x00);
325 } while (retval != 8 && retval != ENODEV);
326
327 if (retval != 8)
325 err("%s - failed sending serial line settings - %d", __FUNCTION__, retval); 328 err("%s - failed sending serial line settings - %d", __FUNCTION__, retval);
326 else { 329 else {
327 spin_lock_irqsave(&priv->lock, flags); 330 spin_lock_irqsave(&priv->lock, flags);
328 priv->baud_rate = n_baud_rate; 331 priv->baud_rate = new_baudrate;
329 priv->cbr_mask = baud_mask; 332 priv->cbr_mask = baud_mask;
330 priv->current_config = config; 333 priv->current_config = feature_buffer[4];
331 ++priv->cmd_count;
332 spin_unlock_irqrestore(&priv->lock, flags); 334 spin_unlock_irqrestore(&priv->lock, flags);
333 } 335 }
334 break; 336 break;
335 case CYPRESS_GET_CONFIG: 337 case CYPRESS_GET_CONFIG:
336 dbg("%s - retreiving serial line settings", __FUNCTION__); 338 dbg("%s - retreiving serial line settings", __FUNCTION__);
337 /* reset values in feature buffer */ 339 /* set initial values in feature buffer */
338 memset(feature_buffer, 0, 5); 340 memset(feature_buffer, 0, 8);
339 341
342 do {
340 retval = usb_control_msg (port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), 343 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, 344 HID_REQ_GET_REPORT, USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
342 0x0300, 0, feature_buffer, 5, 500); 345 0x0300, 0, feature_buffer, 8, 500);
346
347 if (tries++ >= 3)
348 break;
349
350 if (retval == EPIPE)
351 usb_clear_halt(port->serial->dev, 0x00);
352 } while (retval != 5 && retval != ENODEV);
353
343 if (retval != 5) { 354 if (retval != 5) {
344 err("%s - failed to retreive serial line settings - %d", __FUNCTION__, retval); 355 err("%s - failed to retreive serial line settings - %d", __FUNCTION__, retval);
345 return retval; 356 return retval;
346 } else { 357 } else {
347 spin_lock_irqsave(&priv->lock, flags); 358 spin_lock_irqsave(&priv->lock, flags);
359
348 /* store the config in one byte, and later use bit masks to check values */ 360 /* store the config in one byte, and later use bit masks to check values */
349 priv->current_config = feature_buffer[4]; 361 priv->current_config = feature_buffer[4];
350 /* reverse the process above to get the baud_mask value */ 362 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 363
356 priv->baud_rate = n_baud_rate; 364 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__); 365 dbg("%s - failed setting the baud mask (not defined)", __FUNCTION__);
359 ++priv->cmd_count;
360 spin_unlock_irqrestore(&priv->lock, flags); 366 spin_unlock_irqrestore(&priv->lock, flags);
361 } 367 }
362 break;
363 default:
364 err("%s - unsupported serial control command issued", __FUNCTION__);
365 } 368 }
369 spin_lock_irqsave(&priv->lock, flags);
370 ++priv->cmd_count;
371 spin_unlock_irqrestore(&priv->lock, flags);
372
366 return retval; 373 return retval;
367} /* cypress_serial_control */ 374} /* cypress_serial_control */
368 375
369 376
370/* given a baud mask, it will return speed on success */ 377/* given a baud mask, it will return integer baud on success */
371static int mask_to_rate (unsigned mask) 378static int mask_to_rate (unsigned mask)
372{ 379{
373 int rate; 380 int rate;
@@ -438,11 +445,12 @@ static int generic_startup (struct usb_serial *serial)
438 445
439 usb_reset_configuration (serial->dev); 446 usb_reset_configuration (serial->dev);
440 447
448 interval = 1;
441 priv->cmd_ctrl = 0; 449 priv->cmd_ctrl = 0;
442 priv->line_control = 0; 450 priv->line_control = 0;
443 priv->termios_initialized = 0; 451 priv->termios_initialized = 0;
444 priv->calledfromopen = 0;
445 priv->rx_flags = 0; 452 priv->rx_flags = 0;
453 priv->cbr_mask = B300;
446 usb_set_serial_port_data(serial->port[0], priv); 454 usb_set_serial_port_data(serial->port[0], priv);
447 455
448 return (0); 456 return (0);
@@ -513,7 +521,6 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
513 dbg("%s - port %d", __FUNCTION__, port->number); 521 dbg("%s - port %d", __FUNCTION__, port->number);
514 522
515 /* clear halts before open */ 523 /* clear halts before open */
516 usb_clear_halt(serial->dev, 0x00);
517 usb_clear_halt(serial->dev, 0x81); 524 usb_clear_halt(serial->dev, 0x81);
518 usb_clear_halt(serial->dev, 0x02); 525 usb_clear_halt(serial->dev, 0x02);
519 526
@@ -531,7 +538,6 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
531 /* raise both lines and set termios */ 538 /* raise both lines and set termios */
532 spin_lock_irqsave(&priv->lock, flags); 539 spin_lock_irqsave(&priv->lock, flags);
533 priv->line_control = CONTROL_DTR | CONTROL_RTS; 540 priv->line_control = CONTROL_DTR | CONTROL_RTS;
534 priv->calledfromopen = 1;
535 priv->cmd_ctrl = 1; 541 priv->cmd_ctrl = 1;
536 spin_unlock_irqrestore(&priv->lock, flags); 542 spin_unlock_irqrestore(&priv->lock, flags);
537 result = cypress_write(port, NULL, 0); 543 result = cypress_write(port, NULL, 0);
@@ -553,7 +559,7 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
553 usb_fill_int_urb(port->interrupt_in_urb, serial->dev, 559 usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
554 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress), 560 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
555 port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length, 561 port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length,
556 cypress_read_int_callback, port, port->interrupt_in_urb->interval); 562 cypress_read_int_callback, port, interval);
557 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 563 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
558 564
559 if (result){ 565 if (result){
@@ -680,12 +686,12 @@ static void cypress_send(struct usb_serial_port *port)
680 spin_lock_irqsave(&priv->lock, flags); 686 spin_lock_irqsave(&priv->lock, flags);
681 switch (port->interrupt_out_size) { 687 switch (port->interrupt_out_size) {
682 case 32: 688 case 32:
683 // this is for the CY7C64013... 689 /* this is for the CY7C64013... */
684 offset = 2; 690 offset = 2;
685 port->interrupt_out_buffer[0] = priv->line_control; 691 port->interrupt_out_buffer[0] = priv->line_control;
686 break; 692 break;
687 case 8: 693 case 8:
688 // this is for the CY7C63743... 694 /* this is for the CY7C63743... */
689 offset = 1; 695 offset = 1;
690 port->interrupt_out_buffer[0] = priv->line_control; 696 port->interrupt_out_buffer[0] = priv->line_control;
691 break; 697 break;
@@ -738,6 +744,7 @@ send:
738 744
739 port->interrupt_out_urb->transfer_buffer_length = actual_size; 745 port->interrupt_out_urb->transfer_buffer_length = actual_size;
740 port->interrupt_out_urb->dev = port->serial->dev; 746 port->interrupt_out_urb->dev = port->serial->dev;
747 port->interrupt_out_urb->interval = interval;
741 result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC); 748 result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC);
742 if (result) { 749 if (result) {
743 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, 750 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__,
@@ -910,7 +917,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
910 unsigned cflag, iflag, baud_mask; 917 unsigned cflag, iflag, baud_mask;
911 unsigned long flags; 918 unsigned long flags;
912 __u8 oldlines; 919 __u8 oldlines;
913 int linechange; 920 int linechange = 0;
914 921
915 dbg("%s - port %d", __FUNCTION__, port->number); 922 dbg("%s - port %d", __FUNCTION__, port->number);
916 923
@@ -996,15 +1003,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
996 case B115200: dbg("%s - setting baud 115200bps", __FUNCTION__); break; 1003 case B115200: dbg("%s - setting baud 115200bps", __FUNCTION__); break;
997 default: dbg("%s - unknown masked baud rate", __FUNCTION__); 1004 default: dbg("%s - unknown masked baud rate", __FUNCTION__);
998 } 1005 }
999 priv->line_control |= CONTROL_DTR; 1006 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 } 1007 }
1009 spin_unlock_irqrestore(&priv->lock, flags); 1008 spin_unlock_irqrestore(&priv->lock, flags);
1010 1009
@@ -1014,8 +1013,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, 1013 cypress_serial_control(port, baud_mask, data_bits, stop_bits, parity_enable,
1015 parity_type, 0, CYPRESS_SET_CONFIG); 1014 parity_type, 0, CYPRESS_SET_CONFIG);
1016 1015
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 1016 /* 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 */ 1017 * 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); 1018 cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
@@ -1031,7 +1028,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."); 1028 dbg("Using custom termios settings for a baud rate of 4800bps.");
1032 /* define custom termios settings for NMEA protocol */ 1029 /* define custom termios settings for NMEA protocol */
1033 1030
1034
1035 tty->termios->c_iflag /* input modes - */ 1031 tty->termios->c_iflag /* input modes - */
1036 &= ~(IGNBRK /* disable ignore break */ 1032 &= ~(IGNBRK /* disable ignore break */
1037 | BRKINT /* disable break causes interrupt */ 1033 | BRKINT /* disable break causes interrupt */
@@ -1052,23 +1048,16 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
1052 | ISIG /* disable interrupt, quit, and suspend special characters */ 1048 | ISIG /* disable interrupt, quit, and suspend special characters */
1053 | IEXTEN); /* disable non-POSIX special characters */ 1049 | IEXTEN); /* disable non-POSIX special characters */
1054 1050
1055 } else if (priv->chiptype == CT_CYPHIDCOM) { 1051 } /* CT_CYPHIDCOM: Application should handle this for device */
1056
1057 // Software app handling it for device...
1058 1052
1059 }
1060 linechange = (priv->line_control != oldlines); 1053 linechange = (priv->line_control != oldlines);
1061 spin_unlock_irqrestore(&priv->lock, flags); 1054 spin_unlock_irqrestore(&priv->lock, flags);
1062 1055
1063 /* if necessary, set lines */ 1056 /* if necessary, set lines */
1064 if (!priv->calledfromopen && linechange) { 1057 if (linechange) {
1065 priv->cmd_ctrl = 1; 1058 priv->cmd_ctrl = 1;
1066 cypress_write(port, NULL, 0); 1059 cypress_write(port, NULL, 0);
1067 } 1060 }
1068
1069 if (priv->calledfromopen)
1070 priv->calledfromopen = 0;
1071
1072} /* cypress_set_termios */ 1061} /* cypress_set_termios */
1073 1062
1074 1063
@@ -1164,7 +1153,7 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
1164 spin_lock_irqsave(&priv->lock, flags); 1153 spin_lock_irqsave(&priv->lock, flags);
1165 switch(urb->actual_length) { 1154 switch(urb->actual_length) {
1166 case 32: 1155 case 32:
1167 // This is for the CY7C64013... 1156 /* This is for the CY7C64013... */
1168 priv->current_status = data[0] & 0xF8; 1157 priv->current_status = data[0] & 0xF8;
1169 bytes = data[1]+2; 1158 bytes = data[1]+2;
1170 i=2; 1159 i=2;
@@ -1172,7 +1161,7 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
1172 havedata = 1; 1161 havedata = 1;
1173 break; 1162 break;
1174 case 8: 1163 case 8:
1175 // This is for the CY7C63743... 1164 /* This is for the CY7C63743... */
1176 priv->current_status = data[0] & 0xF8; 1165 priv->current_status = data[0] & 0xF8;
1177 bytes = (data[0] & 0x07)+1; 1166 bytes = (data[0] & 0x07)+1;
1178 i=1; 1167 i=1;
@@ -1245,7 +1234,7 @@ continue_read:
1245 port->interrupt_in_urb->transfer_buffer, 1234 port->interrupt_in_urb->transfer_buffer,
1246 port->interrupt_in_urb->transfer_buffer_length, 1235 port->interrupt_in_urb->transfer_buffer_length,
1247 cypress_read_int_callback, port, 1236 cypress_read_int_callback, port,
1248 port->interrupt_in_urb->interval); 1237 interval);
1249 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 1238 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
1250 if (result) 1239 if (result)
1251 dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); 1240 dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
@@ -1274,6 +1263,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); 1263 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
1275 priv->write_urb_in_use = 0; 1264 priv->write_urb_in_use = 0;
1276 return; 1265 return;
1266 case -EPIPE: /* no break needed */
1267 usb_clear_halt(port->serial->dev, 0x02);
1277 default: 1268 default:
1278 /* error in the urb, so we have to resubmit it */ 1269 /* error in the urb, so we have to resubmit it */
1279 dbg("%s - Overflow in write", __FUNCTION__); 1270 dbg("%s - Overflow in write", __FUNCTION__);
@@ -1535,3 +1526,5 @@ module_param(debug, bool, S_IRUGO | S_IWUSR);
1535MODULE_PARM_DESC(debug, "Debug enabled or not"); 1526MODULE_PARM_DESC(debug, "Debug enabled or not");
1536module_param(stats, bool, S_IRUGO | S_IWUSR); 1527module_param(stats, bool, S_IRUGO | S_IWUSR);
1537MODULE_PARM_DESC(stats, "Enable statistics or not"); 1528MODULE_PARM_DESC(stats, "Enable statistics or not");
1529module_param(interval, int, S_IRUGO | S_IWUSR);
1530MODULE_PARM_DESC(interval, "Overrides interrupt interval");