2 * USB Cypress M8 driver
5 * Lonnie Mendez (dignome@gmail.com)
6 * Copyright (C) 2003,2004
7 * Neil Whelchel (koyama@firstlight.net)
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * See Documentation/usb/usb-serial.txt for more information on using this driver
16 * See http://geocities.com/i0xox0i for information on this driver and the
17 * earthmate usb device.
20 * Lonnie Mendez <dignome@gmail.com>
22 * Incorporated write buffering from pl2303 driver. Fixed bug with line
23 * handling so both lines are raised in cypress_open. (was dropping rts)
24 * Various code cleanups made as well along with other misc bug fixes.
26 * Lonnie Mendez <dignome@gmail.com>
28 * Driver modified to support dynamic line settings. Various improvments
33 * Driver first released.
37 * Improve transfer speeds - both read/write are somewhat slow
39 * Improve debugging. Show modem line status with debug output and
40 * implement filtering for certain data as a module parameter.
43 /* Thanks to Neil Whelchel for writing the first cypress m8 implementation for linux. */
44 /* Thanks to cypress for providing references for the hid reports. */
45 /* Thanks to Jiang Zhang for providing links and for general help. */
46 /* Code originates and was built up from ftdi_sio, belkin, pl2303 and others. */
49 #include <linux/config.h>
50 #include <linux/kernel.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/tty.h>
55 #include <linux/tty_driver.h>
56 #include <linux/tty_flip.h>
57 #include <linux/module.h>
58 #include <linux/moduleparam.h>
59 #include <linux/spinlock.h>
60 #include <linux/usb.h>
61 #include <linux/serial.h>
62 #include <linux/delay.h>
63 #include <asm/uaccess.h>
65 #include "usb-serial.h"
66 #include "cypress_m8.h"
69 #ifdef CONFIG_USB_SERIAL_DEBUG
79 #define DRIVER_VERSION "v1.08"
80 #define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>"
81 #define DRIVER_DESC "Cypress USB to Serial Driver"
83 /* write buffer size defines */
84 #define CYPRESS_BUF_SIZE 1024
85 #define CYPRESS_CLOSING_WAIT (30*HZ)
87 static struct usb_device_id id_table_earthmate
[] = {
88 { USB_DEVICE(VENDOR_ID_DELORME
, PRODUCT_ID_EARTHMATEUSB
) },
89 { } /* Terminating entry */
92 static struct usb_device_id id_table_cyphidcomrs232
[] = {
93 { USB_DEVICE(VENDOR_ID_CYPRESS
, PRODUCT_ID_CYPHIDCOM
) },
94 { } /* Terminating entry */
97 static struct usb_device_id id_table_combined
[] = {
98 { USB_DEVICE(VENDOR_ID_DELORME
, PRODUCT_ID_EARTHMATEUSB
) },
99 { USB_DEVICE(VENDOR_ID_CYPRESS
, PRODUCT_ID_CYPHIDCOM
) },
100 { } /* Terminating entry */
103 MODULE_DEVICE_TABLE (usb
, id_table_combined
);
105 static struct usb_driver cypress_driver
= {
107 .probe
= usb_serial_probe
,
108 .disconnect
= usb_serial_disconnect
,
109 .id_table
= id_table_combined
,
112 struct cypress_private
{
113 spinlock_t lock
; /* private lock */
114 int chiptype
; /* identifier of device, for quirks/etc */
115 int bytes_in
; /* used for statistics */
116 int bytes_out
; /* used for statistics */
117 int cmd_count
; /* used for statistics */
118 int cmd_ctrl
; /* always set this to 1 before issuing a command */
119 struct cypress_buf
*buf
; /* write buffer */
120 int write_urb_in_use
; /* write urb in use indicator */
121 int termios_initialized
;
122 __u8 line_control
; /* holds dtr / rts value */
123 __u8 current_status
; /* received from last read - info on dsr,cts,cd,ri,etc */
124 __u8 current_config
; /* stores the current configuration byte */
125 __u8 rx_flags
; /* throttling - used from whiteheat/ftdi_sio */
126 int baud_rate
; /* stores current baud rate in integer form */
127 int cbr_mask
; /* stores current baud rate in masked form */
128 int isthrottled
; /* if throttled, discard reads */
129 wait_queue_head_t delta_msr_wait
; /* used for TIOCMIWAIT */
130 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 */
132 struct termios tmp_termios
; /* stores the old termios settings */
133 char calledfromopen
; /* used when issuing lines on open - fixes rts drop bug */
136 /* write buffer structure */
138 unsigned int buf_size
;
144 /* function prototypes for the Cypress USB to serial device */
145 static int cypress_earthmate_startup (struct usb_serial
*serial
);
146 static int cypress_hidcom_startup (struct usb_serial
*serial
);
147 static void cypress_shutdown (struct usb_serial
*serial
);
148 static int cypress_open (struct usb_serial_port
*port
, struct file
*filp
);
149 static void cypress_close (struct usb_serial_port
*port
, struct file
*filp
);
150 static int cypress_write (struct usb_serial_port
*port
, const unsigned char *buf
, int count
);
151 static void cypress_send (struct usb_serial_port
*port
);
152 static int cypress_write_room (struct usb_serial_port
*port
);
153 static int cypress_ioctl (struct usb_serial_port
*port
, struct file
* file
, unsigned int cmd
, unsigned long arg
);
154 static void cypress_set_termios (struct usb_serial_port
*port
, struct termios
* old
);
155 static int cypress_tiocmget (struct usb_serial_port
*port
, struct file
*file
);
156 static int cypress_tiocmset (struct usb_serial_port
*port
, struct file
*file
, unsigned int set
, unsigned int clear
);
157 static int cypress_chars_in_buffer (struct usb_serial_port
*port
);
158 static void cypress_throttle (struct usb_serial_port
*port
);
159 static void cypress_unthrottle (struct usb_serial_port
*port
);
160 static void cypress_read_int_callback (struct urb
*urb
, struct pt_regs
*regs
);
161 static void cypress_write_int_callback (struct urb
*urb
, struct pt_regs
*regs
);
162 /* baud helper functions */
163 static int mask_to_rate (unsigned mask
);
164 static unsigned rate_to_mask (int rate
);
165 /* write buffer functions */
166 static struct cypress_buf
*cypress_buf_alloc(unsigned int size
);
167 static void cypress_buf_free(struct cypress_buf
*cb
);
168 static void cypress_buf_clear(struct cypress_buf
*cb
);
169 static unsigned int cypress_buf_data_avail(struct cypress_buf
*cb
);
170 static unsigned int cypress_buf_space_avail(struct cypress_buf
*cb
);
171 static unsigned int cypress_buf_put(struct cypress_buf
*cb
, const char *buf
,
173 static unsigned int cypress_buf_get(struct cypress_buf
*cb
, char *buf
,
177 static struct usb_serial_device_type cypress_earthmate_device
= {
178 .owner
= THIS_MODULE
,
179 .name
= "DeLorme Earthmate USB",
180 .short_name
= "earthmate",
181 .id_table
= id_table_earthmate
,
182 .num_interrupt_in
= 1,
183 .num_interrupt_out
= 1,
184 .num_bulk_in
= NUM_DONT_CARE
,
185 .num_bulk_out
= NUM_DONT_CARE
,
187 .attach
= cypress_earthmate_startup
,
188 .shutdown
= cypress_shutdown
,
189 .open
= cypress_open
,
190 .close
= cypress_close
,
191 .write
= cypress_write
,
192 .write_room
= cypress_write_room
,
193 .ioctl
= cypress_ioctl
,
194 .set_termios
= cypress_set_termios
,
195 .tiocmget
= cypress_tiocmget
,
196 .tiocmset
= cypress_tiocmset
,
197 .chars_in_buffer
= cypress_chars_in_buffer
,
198 .throttle
= cypress_throttle
,
199 .unthrottle
= cypress_unthrottle
,
200 .read_int_callback
= cypress_read_int_callback
,
201 .write_int_callback
= cypress_write_int_callback
,
204 static struct usb_serial_device_type cypress_hidcom_device
= {
205 .owner
= THIS_MODULE
,
206 .name
= "HID->COM RS232 Adapter",
207 .short_name
= "cyphidcom",
208 .id_table
= id_table_cyphidcomrs232
,
209 .num_interrupt_in
= 1,
210 .num_interrupt_out
= 1,
211 .num_bulk_in
= NUM_DONT_CARE
,
212 .num_bulk_out
= NUM_DONT_CARE
,
214 .attach
= cypress_hidcom_startup
,
215 .shutdown
= cypress_shutdown
,
216 .open
= cypress_open
,
217 .close
= cypress_close
,
218 .write
= cypress_write
,
219 .write_room
= cypress_write_room
,
220 .ioctl
= cypress_ioctl
,
221 .set_termios
= cypress_set_termios
,
222 .tiocmget
= cypress_tiocmget
,
223 .tiocmset
= cypress_tiocmset
,
224 .chars_in_buffer
= cypress_chars_in_buffer
,
225 .throttle
= cypress_throttle
,
226 .unthrottle
= cypress_unthrottle
,
227 .read_int_callback
= cypress_read_int_callback
,
228 .write_int_callback
= cypress_write_int_callback
,
232 /*****************************************************************************
233 * Cypress serial helper functions
234 *****************************************************************************/
237 /* This function can either set or retreive the current serial line settings */
238 static 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 i
, n_baud_rate
= 0, retval
= 0;
242 struct cypress_private
*priv
;
243 __u8 feature_buffer
[5];
247 dbg("%s", __FUNCTION__
);
249 priv
= usb_get_serial_port_data(port
);
251 switch(cypress_request_type
) {
252 case CYPRESS_SET_CONFIG
:
255 * The general purpose firmware for the Cypress M8 allows for a maximum speed
256 * 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 * project please add your own chiptype and modify the code likewise. The
259 * Cypress HID->COM device will work successfully up to 115200bps.
261 if (baud_mask
!= priv
->cbr_mask
) {
262 dbg("%s - baud rate is changing", __FUNCTION__
);
263 if ( priv
->chiptype
== CT_EARTHMATE
) {
264 /* 300 and 600 baud rates are supported under the generic firmware,
265 * but are not used with NMEA and SiRF protocols */
267 if ( (baud_mask
== B300
) || (baud_mask
== B600
) ) {
268 err("%s - failed setting baud rate, unsupported speed (default to 4800)",
271 } else if ( (n_baud_rate
= mask_to_rate(baud_mask
)) == -1) {
272 err("%s - failed setting baud rate, unsupported speed (default to 4800)",
276 } else if (priv
->chiptype
== CT_CYPHIDCOM
) {
277 if ( (n_baud_rate
= mask_to_rate(baud_mask
)) == -1) {
278 err("%s - failed setting baud rate, unsupported speed (default to 4800)",
282 } else if (priv
->chiptype
== CT_GENERIC
) {
283 if ( (n_baud_rate
= mask_to_rate(baud_mask
)) == -1) {
284 err("%s - failed setting baud rate, unsupported speed (default to 4800)",
289 info("%s - please define your chiptype, using 4800bps default", __FUNCTION__
);
292 } else { /* baud rate not changing, keep the old */
293 n_baud_rate
= priv
->baud_rate
;
295 dbg("%s - baud rate is being sent as %d", __FUNCTION__
, n_baud_rate
);
299 * This algorithm accredited to Jiang Jay Zhang... thanks for all the help!
301 for (i
= 0; i
< 4; ++i
) {
302 feature_buffer
[i
] = ( n_baud_rate
>> (i
*8) & 0xFF );
305 config
= 0; // reset config byte
306 config
|= data_bits
; // assign data bits in 2 bit space ( max 3 )
308 config
|= (stop_bits
<< 3); // assign stop bits in 1 bit space
309 config
|= (parity_enable
<< 4); // assign parity flag in 1 bit space
310 config
|= (parity_type
<< 5); // assign parity type in 1 bit space
312 config
|= (reset
<< 7); // assign reset at end of byte, 1 bit space
314 feature_buffer
[4] = config
;
316 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],
318 feature_buffer
[2], feature_buffer
[3], feature_buffer
[4]);
320 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
,
322 0x0300, 0, feature_buffer
, 5, 500);
325 err("%s - failed sending serial line settings - %d", __FUNCTION__
, retval
);
327 spin_lock_irqsave(&priv
->lock
, flags
);
328 priv
->baud_rate
= n_baud_rate
;
329 priv
->cbr_mask
= baud_mask
;
330 priv
->current_config
= config
;
332 spin_unlock_irqrestore(&priv
->lock
, flags
);
335 case CYPRESS_GET_CONFIG
:
336 dbg("%s - retreiving serial line settings", __FUNCTION__
);
337 /* reset values in feature buffer */
338 memset(feature_buffer
, 0, 5);
340 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 0x0300, 0, feature_buffer
, 5, 500);
344 err("%s - failed to retreive serial line settings - %d", __FUNCTION__
, retval
);
347 spin_lock_irqsave(&priv
->lock
, flags
);
348 /* store the config in one byte, and later use bit masks to check values */
349 priv
->current_config
= feature_buffer
[4];
350 /* reverse the process above to get the baud_mask value */
351 n_baud_rate
= 0; // reset bits
352 for (i
= 0; i
< 4; ++i
) {
353 n_baud_rate
|= ( feature_buffer
[i
] << (i
*8) );
356 priv
->baud_rate
= n_baud_rate
;
357 if ( (priv
->cbr_mask
= rate_to_mask(n_baud_rate
)) == 0x40)
358 dbg("%s - failed setting the baud mask (not defined)", __FUNCTION__
);
360 spin_unlock_irqrestore(&priv
->lock
, flags
);
364 err("%s - unsupported serial control command issued", __FUNCTION__
);
367 } /* cypress_serial_control */
370 /* given a baud mask, it will return speed on success */
371 static int mask_to_rate (unsigned mask
)
376 case B0
: rate
= 0; break;
377 case B300
: rate
= 300; break;
378 case B600
: rate
= 600; break;
379 case B1200
: rate
= 1200; break;
380 case B2400
: rate
= 2400; break;
381 case B4800
: rate
= 4800; break;
382 case B9600
: rate
= 9600; break;
383 case B19200
: rate
= 19200; break;
384 case B38400
: rate
= 38400; break;
385 case B57600
: rate
= 57600; break;
386 case B115200
: rate
= 115200; break;
394 static unsigned rate_to_mask (int rate
)
399 case 0: mask
= B0
; break;
400 case 300: mask
= B300
; break;
401 case 600: mask
= B600
; break;
402 case 1200: mask
= B1200
; break;
403 case 2400: mask
= B2400
; break;
404 case 4800: mask
= B4800
; break;
405 case 9600: mask
= B9600
; break;
406 case 19200: mask
= B19200
; break;
407 case 38400: mask
= B38400
; break;
408 case 57600: mask
= B57600
; break;
409 case 115200: mask
= B115200
; break;
410 default: mask
= 0x40;
415 /*****************************************************************************
416 * Cypress serial driver functions
417 *****************************************************************************/
420 static int generic_startup (struct usb_serial
*serial
)
422 struct cypress_private
*priv
;
424 dbg("%s - port %d", __FUNCTION__
, serial
->port
[0]->number
);
426 priv
= kmalloc(sizeof (struct cypress_private
), GFP_KERNEL
);
430 memset(priv
, 0x00, sizeof (struct cypress_private
));
431 spin_lock_init(&priv
->lock
);
432 priv
->buf
= cypress_buf_alloc(CYPRESS_BUF_SIZE
);
433 if (priv
->buf
== NULL
) {
437 init_waitqueue_head(&priv
->delta_msr_wait
);
439 usb_reset_configuration (serial
->dev
);
442 priv
->line_control
= 0;
443 priv
->termios_initialized
= 0;
444 priv
->calledfromopen
= 0;
446 usb_set_serial_port_data(serial
->port
[0], priv
);
452 static int cypress_earthmate_startup (struct usb_serial
*serial
)
454 struct cypress_private
*priv
;
456 dbg("%s", __FUNCTION__
);
458 if (generic_startup(serial
)) {
459 dbg("%s - Failed setting up port %d", __FUNCTION__
, serial
->port
[0]->number
);
463 priv
= usb_get_serial_port_data(serial
->port
[0]);
464 priv
->chiptype
= CT_EARTHMATE
;
467 } /* cypress_earthmate_startup */
470 static int cypress_hidcom_startup (struct usb_serial
*serial
)
472 struct cypress_private
*priv
;
474 dbg("%s", __FUNCTION__
);
476 if (generic_startup(serial
)) {
477 dbg("%s - Failed setting up port %d", __FUNCTION__
, serial
->port
[0]->number
);
481 priv
= usb_get_serial_port_data(serial
->port
[0]);
482 priv
->chiptype
= CT_CYPHIDCOM
;
485 } /* cypress_hidcom_startup */
488 static void cypress_shutdown (struct usb_serial
*serial
)
490 struct cypress_private
*priv
;
492 dbg ("%s - port %d", __FUNCTION__
, serial
->port
[0]->number
);
494 /* all open ports are closed at this point */
496 priv
= usb_get_serial_port_data(serial
->port
[0]);
499 cypress_buf_free(priv
->buf
);
501 usb_set_serial_port_data(serial
->port
[0], NULL
);
506 static int cypress_open (struct usb_serial_port
*port
, struct file
*filp
)
508 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
509 struct usb_serial
*serial
= port
->serial
;
513 dbg("%s - port %d", __FUNCTION__
, port
->number
);
515 /* clear halts before open */
516 usb_clear_halt(serial
->dev
, 0x00);
517 usb_clear_halt(serial
->dev
, 0x81);
518 usb_clear_halt(serial
->dev
, 0x02);
520 spin_lock_irqsave(&priv
->lock
, flags
);
521 /* reset read/write statistics */
526 spin_unlock_irqrestore(&priv
->lock
, flags
);
528 /* setting to zero could cause data loss */
529 port
->tty
->low_latency
= 1;
531 /* raise both lines and set termios */
532 spin_lock_irqsave(&priv
->lock
, flags
);
533 priv
->line_control
= CONTROL_DTR
| CONTROL_RTS
;
534 priv
->calledfromopen
= 1;
536 spin_unlock_irqrestore(&priv
->lock
, flags
);
537 result
= cypress_write(port
, NULL
, 0);
540 dev_err(&port
->dev
, "%s - failed setting the control lines - error %d\n", __FUNCTION__
, result
);
543 dbg("%s - success setting the control lines", __FUNCTION__
);
545 cypress_set_termios(port
, &priv
->tmp_termios
);
547 /* setup the port and start reading from the device */
548 if(!port
->interrupt_in_urb
){
549 err("%s - interrupt_in_urb is empty!", __FUNCTION__
);
553 usb_fill_int_urb(port
->interrupt_in_urb
, serial
->dev
,
554 usb_rcvintpipe(serial
->dev
, port
->interrupt_in_endpointAddress
),
555 port
->interrupt_in_urb
->transfer_buffer
, port
->interrupt_in_urb
->transfer_buffer_length
,
556 cypress_read_int_callback
, port
, port
->interrupt_in_urb
->interval
);
557 result
= usb_submit_urb(port
->interrupt_in_urb
, GFP_KERNEL
);
560 dev_err(&port
->dev
, "%s - failed submitting read urb, error %d\n", __FUNCTION__
, result
);
567 static void cypress_close(struct usb_serial_port
*port
, struct file
* filp
)
569 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
570 unsigned int c_cflag
;
576 dbg("%s - port %d", __FUNCTION__
, port
->number
);
578 /* wait for data to drain from buffer */
579 spin_lock_irqsave(&priv
->lock
, flags
);
580 timeout
= CYPRESS_CLOSING_WAIT
;
581 init_waitqueue_entry(&wait
, current
);
582 add_wait_queue(&port
->tty
->write_wait
, &wait
);
584 set_current_state(TASK_INTERRUPTIBLE
);
585 if (cypress_buf_data_avail(priv
->buf
) == 0
586 || timeout
== 0 || signal_pending(current
)
587 || !usb_get_intfdata(port
->serial
->interface
))
589 spin_unlock_irqrestore(&priv
->lock
, flags
);
590 timeout
= schedule_timeout(timeout
);
591 spin_lock_irqsave(&priv
->lock
, flags
);
593 set_current_state(TASK_RUNNING
);
594 remove_wait_queue(&port
->tty
->write_wait
, &wait
);
595 /* clear out any remaining data in the buffer */
596 cypress_buf_clear(priv
->buf
);
597 spin_unlock_irqrestore(&priv
->lock
, flags
);
599 /* wait for characters to drain from device */
600 bps
= tty_get_baud_rate(port
->tty
);
602 timeout
= max((HZ
*2560)/bps
,HZ
/10);
605 set_current_state(TASK_INTERRUPTIBLE
);
606 schedule_timeout(timeout
);
608 dbg("%s - stopping urbs", __FUNCTION__
);
609 usb_kill_urb (port
->interrupt_in_urb
);
610 usb_kill_urb (port
->interrupt_out_urb
);
613 c_cflag
= port
->tty
->termios
->c_cflag
;
614 if (c_cflag
& HUPCL
) {
615 /* drop dtr and rts */
616 priv
= usb_get_serial_port_data(port
);
617 spin_lock_irqsave(&priv
->lock
, flags
);
618 priv
->line_control
= 0;
620 spin_unlock_irqrestore(&priv
->lock
, flags
);
621 cypress_write(port
, NULL
, 0);
626 dev_info (&port
->dev
, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
627 priv
->bytes_in
, priv
->bytes_out
, priv
->cmd_count
);
628 } /* cypress_close */
631 static int cypress_write(struct usb_serial_port
*port
, const unsigned char *buf
, int count
)
633 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
636 dbg("%s - port %d, %d bytes", __FUNCTION__
, port
->number
, count
);
638 /* line control commands, which need to be executed immediately,
639 are not put into the buffer for obvious reasons.
641 if (priv
->cmd_ctrl
) {
649 spin_lock_irqsave(&priv
->lock
, flags
);
650 count
= cypress_buf_put(priv
->buf
, buf
, count
);
651 spin_unlock_irqrestore(&priv
->lock
, flags
);
657 } /* cypress_write */
660 static void cypress_send(struct usb_serial_port
*port
)
662 int count
= 0, result
, offset
, actual_size
;
663 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
666 dbg("%s - port %d", __FUNCTION__
, port
->number
);
667 dbg("%s - interrupt out size is %d", __FUNCTION__
, port
->interrupt_out_size
);
669 spin_lock_irqsave(&priv
->lock
, flags
);
670 if (priv
->write_urb_in_use
) {
671 dbg("%s - can't write, urb in use", __FUNCTION__
);
672 spin_unlock_irqrestore(&priv
->lock
, flags
);
675 spin_unlock_irqrestore(&priv
->lock
, flags
);
678 memset(port
->interrupt_out_urb
->transfer_buffer
, 0, port
->interrupt_out_size
);
680 spin_lock_irqsave(&priv
->lock
, flags
);
681 switch (port
->interrupt_out_size
) {
683 // this is for the CY7C64013...
685 port
->interrupt_out_buffer
[0] = priv
->line_control
;
688 // this is for the CY7C63743...
690 port
->interrupt_out_buffer
[0] = priv
->line_control
;
693 dbg("%s - wrong packet size", __FUNCTION__
);
694 spin_unlock_irqrestore(&priv
->lock
, flags
);
698 if (priv
->line_control
& CONTROL_RESET
)
699 priv
->line_control
&= ~CONTROL_RESET
;
701 if (priv
->cmd_ctrl
) {
703 dbg("%s - line control command being issued", __FUNCTION__
);
704 spin_unlock_irqrestore(&priv
->lock
, flags
);
707 spin_unlock_irqrestore(&priv
->lock
, flags
);
709 count
= cypress_buf_get(priv
->buf
, &port
->interrupt_out_buffer
[offset
],
710 port
->interrupt_out_size
-offset
);
716 switch (port
->interrupt_out_size
) {
718 port
->interrupt_out_buffer
[1] = count
;
721 port
->interrupt_out_buffer
[0] |= count
;
724 dbg("%s - count is %d", __FUNCTION__
, count
);
727 spin_lock_irqsave(&priv
->lock
, flags
);
728 priv
->write_urb_in_use
= 1;
729 spin_unlock_irqrestore(&priv
->lock
, flags
);
734 actual_size
= count
+ (port
->interrupt_out_size
== 32 ? 2 : 1);
736 usb_serial_debug_data(debug
, &port
->dev
, __FUNCTION__
, port
->interrupt_out_size
,
737 port
->interrupt_out_urb
->transfer_buffer
);
739 port
->interrupt_out_urb
->transfer_buffer_length
= actual_size
;
740 port
->interrupt_out_urb
->dev
= port
->serial
->dev
;
741 result
= usb_submit_urb (port
->interrupt_out_urb
, GFP_ATOMIC
);
743 dev_err(&port
->dev
, "%s - failed submitting write urb, error %d\n", __FUNCTION__
,
745 priv
->write_urb_in_use
= 0;
748 spin_lock_irqsave(&priv
->lock
, flags
);
749 if (priv
->cmd_ctrl
) {
752 priv
->bytes_out
+= count
; /* do not count the line control and size bytes */
753 spin_unlock_irqrestore(&priv
->lock
, flags
);
755 schedule_work(&port
->work
);
759 /* returns how much space is available in the soft buffer */
760 static int cypress_write_room(struct usb_serial_port
*port
)
762 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
766 dbg("%s - port %d", __FUNCTION__
, port
->number
);
768 spin_lock_irqsave(&priv
->lock
, flags
);
769 room
= cypress_buf_space_avail(priv
->buf
);
770 spin_unlock_irqrestore(&priv
->lock
, flags
);
772 dbg("%s - returns %d", __FUNCTION__
, room
);
777 static int cypress_tiocmget (struct usb_serial_port
*port
, struct file
*file
)
779 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
780 __u8 status
, control
;
781 unsigned int result
= 0;
784 dbg("%s - port %d", __FUNCTION__
, port
->number
);
786 spin_lock_irqsave(&priv
->lock
, flags
);
787 control
= priv
->line_control
;
788 status
= priv
->current_status
;
789 spin_unlock_irqrestore(&priv
->lock
, flags
);
791 result
= ((control
& CONTROL_DTR
) ? TIOCM_DTR
: 0)
792 | ((control
& CONTROL_RTS
) ? TIOCM_RTS
: 0)
793 | ((status
& UART_CTS
) ? TIOCM_CTS
: 0)
794 | ((status
& UART_DSR
) ? TIOCM_DSR
: 0)
795 | ((status
& UART_RI
) ? TIOCM_RI
: 0)
796 | ((status
& UART_CD
) ? TIOCM_CD
: 0);
798 dbg("%s - result = %x", __FUNCTION__
, result
);
804 static int cypress_tiocmset (struct usb_serial_port
*port
, struct file
*file
,
805 unsigned int set
, unsigned int clear
)
807 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
810 dbg("%s - port %d", __FUNCTION__
, port
->number
);
812 spin_lock_irqsave(&priv
->lock
, flags
);
814 priv
->line_control
|= CONTROL_RTS
;
816 priv
->line_control
|= CONTROL_DTR
;
817 if (clear
& TIOCM_RTS
)
818 priv
->line_control
&= ~CONTROL_RTS
;
819 if (clear
& TIOCM_DTR
)
820 priv
->line_control
&= ~CONTROL_DTR
;
821 spin_unlock_irqrestore(&priv
->lock
, flags
);
824 return cypress_write(port
, NULL
, 0);
828 static int cypress_ioctl (struct usb_serial_port
*port
, struct file
* file
, unsigned int cmd
, unsigned long arg
)
830 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
832 dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__
, port
->number
, cmd
);
836 if (copy_to_user((void __user
*)arg
, port
->tty
->termios
, sizeof(struct termios
))) {
842 if (copy_from_user(port
->tty
->termios
, (void __user
*)arg
, sizeof(struct termios
))) {
845 /* here we need to call cypress_set_termios to invoke the new settings */
846 cypress_set_termios(port
, &priv
->tmp_termios
);
849 /* these are called when setting baud rate from gpsd */
851 if (copy_to_user((void __user
*)arg
, port
->tty
->termios
, sizeof(struct termios
))) {
857 if (copy_from_user(port
->tty
->termios
, (void __user
*)arg
, sizeof(struct termios
))) {
860 /* here we need to call cypress_set_termios to invoke the new settings */
861 cypress_set_termios(port
, &priv
->tmp_termios
);
864 /* This code comes from drivers/char/serial.c and ftdi_sio.c */
866 while (priv
!= NULL
) {
867 interruptible_sleep_on(&priv
->delta_msr_wait
);
868 /* see if a signal did it */
869 if (signal_pending(current
))
872 char diff
= priv
->diff_status
;
875 return -EIO
; /* no change => error */
878 /* consume all events */
879 priv
->diff_status
= 0;
881 /* return 0 if caller wanted to know about these bits */
882 if ( ((arg
& TIOCM_RNG
) && (diff
& UART_RI
)) ||
883 ((arg
& TIOCM_DSR
) && (diff
& UART_DSR
)) ||
884 ((arg
& TIOCM_CD
) && (diff
& UART_CD
)) ||
885 ((arg
& TIOCM_CTS
) && (diff
& UART_CTS
)) ) {
888 /* otherwise caller can't care less about what happened,
889 * and so we continue to wait for more events.
899 dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __FUNCTION__
, cmd
);
902 } /* cypress_ioctl */
905 static void cypress_set_termios (struct usb_serial_port
*port
, struct termios
*old_termios
)
907 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
908 struct tty_struct
*tty
;
909 int data_bits
, stop_bits
, parity_type
, parity_enable
;
910 unsigned cflag
, iflag
, baud_mask
;
915 dbg("%s - port %d", __FUNCTION__
, port
->number
);
918 if ((!tty
) || (!tty
->termios
)) {
919 dbg("%s - no tty structures", __FUNCTION__
);
923 spin_lock_irqsave(&priv
->lock
, flags
);
924 if (!priv
->termios_initialized
) {
925 if (priv
->chiptype
== CT_EARTHMATE
) {
926 *(tty
->termios
) = tty_std_termios
;
927 tty
->termios
->c_cflag
= B4800
| CS8
| CREAD
| HUPCL
| CLOCAL
;
928 } else if (priv
->chiptype
== CT_CYPHIDCOM
) {
929 *(tty
->termios
) = tty_std_termios
;
930 tty
->termios
->c_cflag
= B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
;
932 priv
->termios_initialized
= 1;
934 spin_unlock_irqrestore(&priv
->lock
, flags
);
936 cflag
= tty
->termios
->c_cflag
;
937 iflag
= tty
->termios
->c_iflag
;
939 /* check if there are new settings */
941 if ((cflag
!= old_termios
->c_cflag
) ||
942 (RELEVANT_IFLAG(iflag
) != RELEVANT_IFLAG(old_termios
->c_iflag
))) {
943 dbg("%s - attempting to set new termios settings", __FUNCTION__
);
944 /* should make a copy of this in case something goes wrong in the function, we can restore it */
945 spin_lock_irqsave(&priv
->lock
, flags
);
946 priv
->tmp_termios
= *(tty
->termios
);
947 spin_unlock_irqrestore(&priv
->lock
, flags
);
949 dbg("%s - nothing to do, exiting", __FUNCTION__
);
955 /* set number of data bits, parity, stop bits */
956 /* when parity is disabled the parity type bit is ignored */
958 stop_bits
= cflag
& CSTOPB
? 1 : 0; /* 1 means 2 stop bits, 0 means 1 stop bit */
960 if (cflag
& PARENB
) {
962 parity_type
= cflag
& PARODD
? 1 : 0; /* 1 means odd parity, 0 means even parity */
964 parity_enable
= parity_type
= 0;
967 switch (cflag
& CSIZE
) {
968 case CS5
: data_bits
= 0; break;
969 case CS6
: data_bits
= 1; break;
970 case CS7
: data_bits
= 2; break;
971 case CS8
: data_bits
= 3; break;
972 default: err("%s - CSIZE was set, but not CS5-CS8", __FUNCTION__
); data_bits
= 3;
977 spin_lock_irqsave(&priv
->lock
, flags
);
978 oldlines
= priv
->line_control
;
979 if ((cflag
& CBAUD
) == B0
) {
980 /* drop dtr and rts */
981 dbg("%s - dropping the lines, baud rate 0bps", __FUNCTION__
);
983 priv
->line_control
&= ~(CONTROL_DTR
| CONTROL_RTS
);
985 baud_mask
= (cflag
& CBAUD
);
987 case B300
: dbg("%s - setting baud 300bps", __FUNCTION__
); break;
988 case B600
: dbg("%s - setting baud 600bps", __FUNCTION__
); break;
989 case B1200
: dbg("%s - setting baud 1200bps", __FUNCTION__
); break;
990 case B2400
: dbg("%s - setting baud 2400bps", __FUNCTION__
); break;
991 case B4800
: dbg("%s - setting baud 4800bps", __FUNCTION__
); break;
992 case B9600
: dbg("%s - setting baud 9600bps", __FUNCTION__
); break;
993 case B19200
: dbg("%s - setting baud 19200bps", __FUNCTION__
); break;
994 case B38400
: dbg("%s - setting baud 38400bps", __FUNCTION__
); break;
995 case B57600
: dbg("%s - setting baud 57600bps", __FUNCTION__
); break;
996 case B115200
: dbg("%s - setting baud 115200bps", __FUNCTION__
); break;
997 default: dbg("%s - unknown masked baud rate", __FUNCTION__
);
999 priv
->line_control
|= CONTROL_DTR
;
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
;
1006 priv
->line_control
&= ~CONTROL_RTS
;
1009 spin_unlock_irqrestore(&priv
->lock
, flags
);
1011 dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, %d data_bits (+5)", __FUNCTION__
,
1012 stop_bits
, parity_enable
, parity_type
, data_bits
);
1014 cypress_serial_control(port
, baud_mask
, data_bits
, stop_bits
, parity_enable
,
1015 parity_type
, 0, CYPRESS_SET_CONFIG
);
1017 msleep(50); /* give some time between change and read (50ms) */
1019 /* 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 */
1021 cypress_serial_control(port
, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG
);
1023 /* Here we can define custom tty settings for devices
1025 * the main tty termios flag base comes from empeg.c
1028 spin_lock_irqsave(&priv
->lock
, flags
);
1029 if ( (priv
->chiptype
== CT_EARTHMATE
) && (priv
->baud_rate
== 4800) ) {
1031 dbg("Using custom termios settings for a baud rate of 4800bps.");
1032 /* define custom termios settings for NMEA protocol */
1035 tty
->termios
->c_iflag
/* input modes - */
1036 &= ~(IGNBRK
/* disable ignore break */
1037 | BRKINT
/* disable break causes interrupt */
1038 | PARMRK
/* disable mark parity errors */
1039 | ISTRIP
/* disable clear high bit of input characters */
1040 | INLCR
/* disable translate NL to CR */
1041 | IGNCR
/* disable ignore CR */
1042 | ICRNL
/* disable translate CR to NL */
1043 | IXON
); /* disable enable XON/XOFF flow control */
1045 tty
->termios
->c_oflag
/* output modes */
1046 &= ~OPOST
; /* disable postprocess output characters */
1048 tty
->termios
->c_lflag
/* line discipline modes */
1049 &= ~(ECHO
/* disable echo input characters */
1050 | ECHONL
/* disable echo new line */
1051 | ICANON
/* disable erase, kill, werase, and rprnt special characters */
1052 | ISIG
/* disable interrupt, quit, and suspend special characters */
1053 | IEXTEN
); /* disable non-POSIX special characters */
1055 } else if (priv
->chiptype
== CT_CYPHIDCOM
) {
1057 // Software app handling it for device...
1060 linechange
= (priv
->line_control
!= oldlines
);
1061 spin_unlock_irqrestore(&priv
->lock
, flags
);
1063 /* if necessary, set lines */
1064 if (!priv
->calledfromopen
&& linechange
) {
1066 cypress_write(port
, NULL
, 0);
1069 if (priv
->calledfromopen
)
1070 priv
->calledfromopen
= 0;
1072 } /* cypress_set_termios */
1075 /* returns amount of data still left in soft buffer */
1076 static int cypress_chars_in_buffer(struct usb_serial_port
*port
)
1078 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
1080 unsigned long flags
;
1082 dbg("%s - port %d", __FUNCTION__
, port
->number
);
1084 spin_lock_irqsave(&priv
->lock
, flags
);
1085 chars
= cypress_buf_data_avail(priv
->buf
);
1086 spin_unlock_irqrestore(&priv
->lock
, flags
);
1088 dbg("%s - returns %d", __FUNCTION__
, chars
);
1093 static void cypress_throttle (struct usb_serial_port
*port
)
1095 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
1096 unsigned long flags
;
1098 dbg("%s - port %d", __FUNCTION__
, port
->number
);
1100 spin_lock_irqsave(&priv
->lock
, flags
);
1101 priv
->rx_flags
= THROTTLED
;
1102 spin_unlock_irqrestore(&priv
->lock
, flags
);
1106 static void cypress_unthrottle (struct usb_serial_port
*port
)
1108 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
1109 int actually_throttled
, result
;
1110 unsigned long flags
;
1112 dbg("%s - port %d", __FUNCTION__
, port
->number
);
1114 spin_lock_irqsave(&priv
->lock
, flags
);
1115 actually_throttled
= priv
->rx_flags
& ACTUALLY_THROTTLED
;
1117 spin_unlock_irqrestore(&priv
->lock
, flags
);
1119 if (actually_throttled
) {
1120 port
->interrupt_in_urb
->dev
= port
->serial
->dev
;
1122 result
= usb_submit_urb(port
->interrupt_in_urb
, GFP_ATOMIC
);
1124 dev_err(&port
->dev
, "%s - failed submitting read urb, error %d\n", __FUNCTION__
, result
);
1129 static void cypress_read_int_callback(struct urb
*urb
, struct pt_regs
*regs
)
1131 struct usb_serial_port
*port
= (struct usb_serial_port
*)urb
->context
;
1132 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
1133 struct tty_struct
*tty
;
1134 unsigned char *data
= urb
->transfer_buffer
;
1135 unsigned long flags
;
1136 char tty_flag
= TTY_NORMAL
;
1142 dbg("%s - port %d", __FUNCTION__
, port
->number
);
1145 dbg("%s - nonzero read status received: %d", __FUNCTION__
, urb
->status
);
1149 spin_lock_irqsave(&priv
->lock
, flags
);
1150 if (priv
->rx_flags
& THROTTLED
) {
1151 dbg("%s - now throttling", __FUNCTION__
);
1152 priv
->rx_flags
|= ACTUALLY_THROTTLED
;
1153 spin_unlock_irqrestore(&priv
->lock
, flags
);
1156 spin_unlock_irqrestore(&priv
->lock
, flags
);
1160 dbg("%s - bad tty pointer - exiting", __FUNCTION__
);
1164 spin_lock_irqsave(&priv
->lock
, flags
);
1165 switch(urb
->actual_length
) {
1167 // This is for the CY7C64013...
1168 priv
->current_status
= data
[0] & 0xF8;
1175 // This is for the CY7C63743...
1176 priv
->current_status
= data
[0] & 0xF8;
1177 bytes
= (data
[0] & 0x07)+1;
1183 dbg("%s - wrong packet size - received %d bytes", __FUNCTION__
, urb
->actual_length
);
1184 spin_unlock_irqrestore(&priv
->lock
, flags
);
1187 spin_unlock_irqrestore(&priv
->lock
, flags
);
1189 usb_serial_debug_data (debug
, &port
->dev
, __FUNCTION__
, urb
->actual_length
, data
);
1191 spin_lock_irqsave(&priv
->lock
, flags
);
1192 /* check to see if status has changed */
1194 if (priv
->current_status
!= priv
->prev_status
) {
1195 priv
->diff_status
|= priv
->current_status
^ priv
->prev_status
;
1196 wake_up_interruptible(&priv
->delta_msr_wait
);
1197 priv
->prev_status
= priv
->current_status
;
1200 spin_unlock_irqrestore(&priv
->lock
, flags
);
1202 /* hangup, as defined in acm.c... this might be a bad place for it though */
1203 if (tty
&& !(tty
->termios
->c_cflag
& CLOCAL
) && !(priv
->current_status
& UART_CD
)) {
1204 dbg("%s - calling hangup", __FUNCTION__
);
1209 /* There is one error bit... I'm assuming it is a parity error indicator
1210 * as the generic firmware will set this bit to 1 if a parity error occurs.
1211 * I can not find reference to any other error events.
1214 spin_lock_irqsave(&priv
->lock
, flags
);
1215 if (priv
->current_status
& CYP_ERROR
) {
1216 spin_unlock_irqrestore(&priv
->lock
, flags
);
1217 tty_flag
= TTY_PARITY
;
1218 dbg("%s - Parity Error detected", __FUNCTION__
);
1220 spin_unlock_irqrestore(&priv
->lock
, flags
);
1222 /* process read if there is data other than line status */
1223 if (tty
&& (bytes
> i
)) {
1224 for (; i
< bytes
; ++i
) {
1225 dbg("pushing byte number %d - %d - %c",i
,data
[i
],data
[i
]);
1226 if(tty
->flip
.count
>= TTY_FLIPBUF_SIZE
) {
1227 tty_flip_buffer_push(tty
);
1229 tty_insert_flip_char(tty
, data
[i
], tty_flag
);
1231 tty_flip_buffer_push(port
->tty
);
1234 spin_lock_irqsave(&priv
->lock
, flags
);
1235 priv
->bytes_in
+= bytes
; /* control and status byte(s) are also counted */
1236 spin_unlock_irqrestore(&priv
->lock
, flags
);
1240 /* Continue trying to always read... unless the port has closed. */
1242 if (port
->open_count
> 0) {
1243 usb_fill_int_urb(port
->interrupt_in_urb
, port
->serial
->dev
,
1244 usb_rcvintpipe(port
->serial
->dev
, port
->interrupt_in_endpointAddress
),
1245 port
->interrupt_in_urb
->transfer_buffer
,
1246 port
->interrupt_in_urb
->transfer_buffer_length
,
1247 cypress_read_int_callback
, port
,
1248 port
->interrupt_in_urb
->interval
);
1249 result
= usb_submit_urb(port
->interrupt_in_urb
, GFP_ATOMIC
);
1251 dev_err(&urb
->dev
->dev
, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__
, result
);
1255 } /* cypress_read_int_callback */
1258 static void cypress_write_int_callback(struct urb
*urb
, struct pt_regs
*regs
)
1260 struct usb_serial_port
*port
= (struct usb_serial_port
*)urb
->context
;
1261 struct cypress_private
*priv
= usb_get_serial_port_data(port
);
1264 dbg("%s - port %d", __FUNCTION__
, port
->number
);
1266 switch (urb
->status
) {
1273 /* this urb is terminated, clean up */
1274 dbg("%s - urb shutting down with status: %d", __FUNCTION__
, urb
->status
);
1275 priv
->write_urb_in_use
= 0;
1278 /* error in the urb, so we have to resubmit it */
1279 dbg("%s - Overflow in write", __FUNCTION__
);
1280 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__
, urb
->status
);
1281 port
->interrupt_out_urb
->transfer_buffer_length
= 1;
1282 port
->interrupt_out_urb
->dev
= port
->serial
->dev
;
1283 result
= usb_submit_urb(port
->interrupt_out_urb
, GFP_ATOMIC
);
1285 dev_err(&urb
->dev
->dev
, "%s - failed resubmitting write urb, error %d\n",
1286 __FUNCTION__
, result
);
1291 priv
->write_urb_in_use
= 0;
1293 /* send any buffered data */
1298 /*****************************************************************************
1299 * Write buffer functions - buffering code from pl2303 used
1300 *****************************************************************************/
1305 * Allocate a circular buffer and all associated memory.
1308 static struct cypress_buf
*cypress_buf_alloc(unsigned int size
)
1311 struct cypress_buf
*cb
;
1317 cb
= (struct cypress_buf
*)kmalloc(sizeof(struct cypress_buf
), GFP_KERNEL
);
1321 cb
->buf_buf
= kmalloc(size
, GFP_KERNEL
);
1322 if (cb
->buf_buf
== NULL
) {
1327 cb
->buf_size
= size
;
1328 cb
->buf_get
= cb
->buf_put
= cb
->buf_buf
;
1338 * Free the buffer and all associated memory.
1341 static void cypress_buf_free(struct cypress_buf
*cb
)
1344 if (cb
->buf_buf
!= NULL
)
1354 * Clear out all data in the circular buffer.
1357 static void cypress_buf_clear(struct cypress_buf
*cb
)
1360 cb
->buf_get
= cb
->buf_put
;
1361 /* equivalent to a get of all data available */
1366 * cypress_buf_data_avail
1368 * Return the number of bytes of data available in the circular
1372 static unsigned int cypress_buf_data_avail(struct cypress_buf
*cb
)
1375 return ((cb
->buf_size
+ cb
->buf_put
- cb
->buf_get
) % cb
->buf_size
);
1382 * cypress_buf_space_avail
1384 * Return the number of bytes of space available in the circular
1388 static unsigned int cypress_buf_space_avail(struct cypress_buf
*cb
)
1391 return ((cb
->buf_size
+ cb
->buf_get
- cb
->buf_put
- 1) % cb
->buf_size
);
1400 * Copy data data from a user buffer and put it into the circular buffer.
1401 * Restrict to the amount of space available.
1403 * Return the number of bytes copied.
1406 static unsigned int cypress_buf_put(struct cypress_buf
*cb
, const char *buf
,
1416 len
= cypress_buf_space_avail(cb
);
1423 len
= cb
->buf_buf
+ cb
->buf_size
- cb
->buf_put
;
1425 memcpy(cb
->buf_put
, buf
, len
);
1426 memcpy(cb
->buf_buf
, buf
+len
, count
- len
);
1427 cb
->buf_put
= cb
->buf_buf
+ count
- len
;
1429 memcpy(cb
->buf_put
, buf
, count
);
1431 cb
->buf_put
+= count
;
1432 else /* count == len */
1433 cb
->buf_put
= cb
->buf_buf
;
1444 * Get data from the circular buffer and copy to the given buffer.
1445 * Restrict to the amount of data available.
1447 * Return the number of bytes copied.
1450 static unsigned int cypress_buf_get(struct cypress_buf
*cb
, char *buf
,
1460 len
= cypress_buf_data_avail(cb
);
1467 len
= cb
->buf_buf
+ cb
->buf_size
- cb
->buf_get
;
1469 memcpy(buf
, cb
->buf_get
, len
);
1470 memcpy(buf
+len
, cb
->buf_buf
, count
- len
);
1471 cb
->buf_get
= cb
->buf_buf
+ count
- len
;
1473 memcpy(buf
, cb
->buf_get
, count
);
1475 cb
->buf_get
+= count
;
1476 else /* count == len */
1477 cb
->buf_get
= cb
->buf_buf
;
1484 /*****************************************************************************
1486 *****************************************************************************/
1488 static int __init
cypress_init(void)
1492 dbg("%s", __FUNCTION__
);
1494 retval
= usb_serial_register(&cypress_earthmate_device
);
1496 goto failed_em_register
;
1497 retval
= usb_serial_register(&cypress_hidcom_device
);
1499 goto failed_hidcom_register
;
1500 retval
= usb_register(&cypress_driver
);
1502 goto failed_usb_register
;
1504 info(DRIVER_DESC
" " DRIVER_VERSION
);
1506 failed_usb_register
:
1507 usb_deregister(&cypress_driver
);
1508 failed_hidcom_register
:
1509 usb_serial_deregister(&cypress_hidcom_device
);
1511 usb_serial_deregister(&cypress_earthmate_device
);
1517 static void __exit
cypress_exit (void)
1519 dbg("%s", __FUNCTION__
);
1521 usb_deregister (&cypress_driver
);
1522 usb_serial_deregister (&cypress_earthmate_device
);
1523 usb_serial_deregister (&cypress_hidcom_device
);
1527 module_init(cypress_init
);
1528 module_exit(cypress_exit
);
1530 MODULE_AUTHOR( DRIVER_AUTHOR
);
1531 MODULE_DESCRIPTION( DRIVER_DESC
);
1532 MODULE_VERSION( DRIVER_VERSION
);
1533 MODULE_LICENSE("GPL");
1535 module_param(debug
, bool, S_IRUGO
| S_IWUSR
);
1536 MODULE_PARM_DESC(debug
, "Debug enabled or not");
1537 module_param(stats
, bool, S_IRUGO
| S_IWUSR
);
1538 MODULE_PARM_DESC(stats
, "Enable statistics or not");