diff options
Diffstat (limited to 'drivers/usb/serial/keyspan.h')
-rw-r--r-- | drivers/usb/serial/keyspan.h | 290 |
1 files changed, 263 insertions, 27 deletions
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 8d249916c..0cd2a70b0 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h @@ -19,6 +19,11 @@ and Keyspan, Inc the manufacturers of the Keyspan USB-serial products. Thanks Guys :) + Thanks to Paulus for miscellaneous tidy ups, some largish chunks + of much nicer and/or completely new code and (perhaps most uniquely) + having the patience to sit down and explain why and where he'd changed + stuff. + Tip 'o the hat to Linuxcare for supporting staff in their work on open source projects. @@ -41,12 +46,18 @@ static void keyspan_shutdown (struct usb_serial *serial); static void keyspan_rx_throttle (struct usb_serial_port *port); static void keyspan_rx_unthrottle (struct usb_serial_port *port); static int keyspan_write_room (struct usb_serial_port *port); + static int keyspan_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count); + +#if 0 static void keyspan_write_bulk_callback (struct urb *urb); -static void keyspan_read_bulk_callback (struct urb *urb); +#endif + +//static void keyspan_usa26_read_int_callback (struct urb *urb); +//static void keyspan_usa28_read_int_callback (struct urb *urb); static int keyspan_chars_in_buffer (struct usb_serial_port *port); static int keyspan_ioctl (struct usb_serial_port *port, struct file *file, @@ -58,12 +69,20 @@ static void keyspan_break_ctl (struct usb_serial_port *port, int break_state); static int keyspan_fake_startup (struct usb_serial *serial); -static int keyspan_usa19_calc_baud (u32 baud_rate, u8 *rate_hi, - u8 *rate_low); -static void keyspan_usa19_setup_urbs (struct usb_serial *serial); -static int keyspan_usa19_send_setup (struct usb_serial *serial, - struct usb_serial_port *port); +static int keyspan_usa19_calc_baud (u32 baud_rate, u32 baudclk, + u8 *rate_hi, u8 *rate_low, u8 *prescaler); +static int keyspan_usa19w_calc_baud (u32 baud_rate, u32 baudclk, + u8 *rate_hi, u8 *rate_low, u8 *prescaler); + +//static void keyspan_usa19_setup_urbs (struct usb_serial *serial); + +static int keyspan_usa28_send_setup (struct usb_serial *serial, + struct usb_serial_port *port); +static int keyspan_usa26_send_setup (struct usb_serial *serial, + struct usb_serial_port *port); +static int keyspan_usa49_send_setup (struct usb_serial *serial, + struct usb_serial_port *port); /* Functions from usbserial.c for ezusb firmware handling */ extern int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit); @@ -109,13 +128,162 @@ struct ezusb_hex_record { static const struct ezusb_hex_record *keyspan_usa19w_firmware = NULL; #endif - +#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA49W + #include "keyspan_usa49w_fw.h" +#else + static const struct ezusb_hex_record *keyspan_usa49w_firmware = NULL; +#endif + /* Values used for baud rate calculation - device specific */ #define KEYSPAN_INVALID_BAUD_RATE (-1) #define KEYSPAN_BAUD_RATE_OK (0) -#define USA19_BAUDCLK (12000000L) +#define KEYSPAN_USA18X_BAUDCLK (12000000L) /* a guess */ +#define KEYSPAN_USA19_BAUDCLK (12000000L) +#define KEYSPAN_USA19W_BAUDCLK (24000000L) +#define KEYSPAN_USA28X_BAUDCLK (12000000L) +#define KEYSPAN_USA49W_BAUDCLK (48000000L) + + /* Some constants used to characterise each device. + There is a four port device due later in the year, + we allow for it now in the following */ +#define KEYSPAN_MAX_NUM_PORTS (4) +#define KEYSPAN_MAX_FLIPS (2) + +typedef struct { + /* product ID value */ + int product_id; + + enum {msg_usa26, msg_usa28, msg_usa49} msg_format; + + /* Number of physical ports */ + int num_ports; + + /* 1 if endpoint flipping used on input, 0 if not */ + int indat_endp_flip; + + /* 1 if endpoint flipping used on output, 0 if not */ + int outdat_endp_flip; + + /* Table mapping input data endpoint IDs to physical + port number and flip if used */ + int indat_endpoints[KEYSPAN_MAX_NUM_PORTS]; + + /* Same for output endpoints */ + int outdat_endpoints[KEYSPAN_MAX_NUM_PORTS]; + + /* Input acknowledge endpoints */ + int inack_endpoints[KEYSPAN_MAX_NUM_PORTS]; + + /* Output control endpoints */ + int outcont_endpoints[KEYSPAN_MAX_NUM_PORTS]; + + /* Endpoint used for input status */ + int instat_endpoint; + + /* Endpoint used for global control functions */ + int glocont_endpoint; + + int (*calculate_baud_rate) (u32 baud_rate, u32 baudclk, + u8 *rate_hi, u8 *rate_low, u8 *prescaler); + u32 baudclk; + +} keyspan_device_details; + + /* Now for each device type we setup the device detail + structure with the appropriate information (provided + in Keyspan's documentation) */ + +static const keyspan_device_details usa18x_device_details = { + 0x112, /* product ID */ + msg_usa26, /* msg type*/ + 1, /* num ports */ + 0, /* indat endpoint flip */ + 1, /* outdat endpoint flip */ + {0x81}, /* per port indat */ + {0x01}, /* per port outdat */ + {0x85}, /* per port inack */ + {0x05}, /* per port outcont */ + 0x87, /* instat endpoint */ + 0x07, /* glocont endpoint */ + keyspan_usa19w_calc_baud, /* calc baud rate */ + KEYSPAN_USA18X_BAUDCLK /* base baud clock */ +}; + +static const keyspan_device_details usa19_device_details = { + 0x107, /* product ID */ + msg_usa28, /* msg type*/ + 1, /* num ports */ + 1, /* indat endpoint flip */ + 1, /* outdat endpoint flip */ + {0x81}, /* per port indat */ + {0x01}, /* per port outdat */ + {0x83}, /* per port inack */ + {0x03}, /* per port outcont */ + 0x84, /* instat endpoint */ + -1, /* glocont endpoint */ + keyspan_usa19_calc_baud, /* calc baud rate */ + KEYSPAN_USA19_BAUDCLK /* base baud clock */ +}; + +static const keyspan_device_details usa19w_device_details = { + 0x108, /* product ID */ + msg_usa26, /* msg type*/ + 1, /* num ports */ + 0, /* indat endpoint flip */ + 1, /* outdat endpoint flip */ + {0x81}, /* per port indat */ + {0x01}, /* per port outdat */ + {0x85}, /* per port inack */ + {0x05}, /* per port outcont */ + 0x87, /* instat endpoint */ + 0x07, /* glocont endpoint */ + keyspan_usa19w_calc_baud, /* calc baud rate */ + KEYSPAN_USA19W_BAUDCLK /* base baud clock */ +}; + +static const keyspan_device_details usa28x_device_details = { + 0x110, /* product ID */ + msg_usa26, /* msg type*/ + 2, /* num ports */ + 0, /* indat endpoint flip */ + 1, /* outdat endpoint flip */ + {0x81, 0x83}, /* per port indat */ + {0x01, 0x03}, /* per port outdat */ + {0x85, 0x86}, /* per port inack */ + {0x05, 0x06}, /* per port outcont */ + 0x87, /* instat endpoint */ + 0x07, /* glocont endpoint */ + keyspan_usa19w_calc_baud, /* calc baud rate */ + KEYSPAN_USA28X_BAUDCLK +}; + +static const keyspan_device_details usa49w_device_details = { + 0x010a, /* product ID */ + msg_usa49, /* msg type*/ + 4, /* num ports */ + 0, /* indat endpoint flip */ + 0, /* outdat endpoint flip */ + { 0x81, 0x82, 0x83, 0x84}, /* per port indat */ + { 0x01, 0x02, 0x03, 0x04}, /* per port outdat */ + {-1, -1, -1, -1}, /* per port inack */ + {-1, -1, -1, -1}, /* per port outcont */ + 0x87, /* instat endpoint */ + 0x07, /* glocont endpoint */ + keyspan_usa19w_calc_baud, /* calc baud rate */ + KEYSPAN_USA49W_BAUDCLK +}; - /* Device info for the Keyspan serial converter */ +static const keyspan_device_details *keyspan_devices[] = { + &usa18x_device_details, + &usa19_device_details, + &usa19w_device_details, + &usa28x_device_details, + &usa49w_device_details, + NULL +}; + + /* Device info for the Keyspan serial converter, used + by the overall usb-serial probe function */ #define KEYSPAN_VENDOR_ID (0x06cd) /* Product IDs for the five products supported, pre-renumeration */ @@ -124,6 +292,7 @@ struct ezusb_hex_record { #define keyspan_usa19w_pre_product_id 0x0106 #define keyspan_usa28_pre_product_id 0x0101 #define keyspan_usa28x_pre_product_id 0x0102 +#define keyspan_usa49w_pre_product_id 0x0109 /* Product IDs post-renumeration */ #define keyspan_usa18x_product_id 0x0112 @@ -131,6 +300,7 @@ struct ezusb_hex_record { #define keyspan_usa19w_product_id 0x0108 #define keyspan_usa28_product_id 0x010f #define keyspan_usa28x_product_id 0x0110 +#define keyspan_usa49w_product_id 0x010a static __devinitdata struct usb_device_id keyspan_ids_combined[] = { {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa18x_pre_product_id}, @@ -138,11 +308,13 @@ static __devinitdata struct usb_device_id keyspan_ids_combined[] = { {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa19w_pre_product_id}, {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa28_pre_product_id}, {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa28x_pre_product_id}, + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa49w_pre_product_id}, {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa18x_product_id}, {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa19_product_id}, {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa19w_product_id}, {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa28_product_id}, {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa28x_product_id}, + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa49w_product_id}, { } /* Terminating entry */ }; @@ -177,6 +349,11 @@ static __devinitdata struct usb_device_id keyspan_usa28x_pre_ids[] = { { } /* Terminating entry */ }; +static __devinitdata struct usb_device_id keyspan_usa49w_pre_ids[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa49w_pre_product_id}, + { } /* Terminating entry */ +}; + static __devinitdata struct usb_device_id keyspan_usa18x_ids[] = { {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa18x_product_id}, { } /* Terminating entry */ @@ -202,10 +379,15 @@ static __devinitdata struct usb_device_id keyspan_usa28x_ids[] = { { } /* Terminating entry */ }; +static __devinitdata struct usb_device_id keyspan_usa49w_ids[] = { + {idVendor: KEYSPAN_VENDOR_ID, idProduct: keyspan_usa49w_product_id}, + { } /* Terminating entry */ +}; + /* Structs for the devices, pre and post renumeration. These are incomplete at present - HAB 20000708 */ struct usb_serial_device_type keyspan_usa18x_pre_device = { - name: "Keyspan USA18X - (prerenumeration)", + name: "Keyspan USA18X - (without firmware)", id_table: keyspan_usa18x_pre_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, @@ -218,7 +400,7 @@ struct usb_serial_device_type keyspan_usa18x_pre_device = { }; struct usb_serial_device_type keyspan_usa19_pre_device = { - name: "Keyspan USA19 - (prerenumeration)", + name: "Keyspan USA19 - (without firmware)", id_table: keyspan_usa19_pre_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, @@ -232,7 +414,7 @@ struct usb_serial_device_type keyspan_usa19_pre_device = { struct usb_serial_device_type keyspan_usa19w_pre_device = { - name: "Keyspan USA19W - (prerenumeration)", + name: "Keyspan USA19W - (without firmware)", id_table: keyspan_usa19w_pre_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, @@ -246,7 +428,7 @@ struct usb_serial_device_type keyspan_usa19w_pre_device = { struct usb_serial_device_type keyspan_usa28_pre_device = { - name: "Keyspan USA28 - (prerenumeration)", + name: "Keyspan USA28 - (without firmware)", id_table: keyspan_usa28_pre_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, @@ -259,7 +441,7 @@ struct usb_serial_device_type keyspan_usa28_pre_device = { }; struct usb_serial_device_type keyspan_usa28x_pre_device = { - name: "Keyspan USA28X - (prerenumeration)", + name: "Keyspan USA28X - (without firmware)", id_table: keyspan_usa28x_pre_ids, needs_interrupt_in: DONT_CARE, needs_bulk_in: DONT_CARE, @@ -271,22 +453,43 @@ struct usb_serial_device_type keyspan_usa28x_pre_device = { startup: keyspan_fake_startup }; +struct usb_serial_device_type keyspan_usa49w_pre_device = { + name: "Keyspan USA49W - (without firmware)", + id_table: keyspan_usa49w_pre_ids, + needs_interrupt_in: DONT_CARE, + needs_bulk_in: DONT_CARE, + needs_bulk_out: DONT_CARE, + num_interrupt_in: NUM_DONT_CARE, + num_bulk_in: NUM_DONT_CARE, + num_bulk_out: NUM_DONT_CARE, + num_ports: 4, + startup: keyspan_fake_startup +}; struct usb_serial_device_type keyspan_usa18x_device = { name: "Keyspan USA18X", id_table: keyspan_usa18x_ids, needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, + needs_bulk_in: MUST_HAVE, + needs_bulk_out: MUST_HAVE, num_interrupt_in: NUM_DONT_CARE, - num_bulk_in: NUM_DONT_CARE, - num_bulk_out: NUM_DONT_CARE, + num_bulk_in: 3, + num_bulk_out: 4, num_ports: 1, open: keyspan_open, close: keyspan_close, + write: keyspan_write, + write_room: keyspan_write_room, + //write_bulk_callback: Not used - we define our own herbs + //read_int_callback: keyspan_usa26_read_int_callback, + chars_in_buffer: keyspan_chars_in_buffer, throttle: keyspan_rx_throttle, unthrottle: keyspan_rx_unthrottle, + ioctl: keyspan_ioctl, set_termios: keyspan_set_termios, + break_ctl: keyspan_break_ctl, + startup: keyspan_startup, + shutdown: keyspan_shutdown, }; struct usb_serial_device_type keyspan_usa19_device = { @@ -303,8 +506,8 @@ struct usb_serial_device_type keyspan_usa19_device = { close: keyspan_close, write: keyspan_write, write_room: keyspan_write_room, - write_bulk_callback: keyspan_write_bulk_callback, - read_int_callback: keyspan_read_bulk_callback, +// write_bulk_callback: keyspan_write_bulk_callback, +// read_int_callback: keyspan_usa28_read_int_callback, chars_in_buffer: keyspan_chars_in_buffer, throttle: keyspan_rx_throttle, unthrottle: keyspan_rx_unthrottle, @@ -320,17 +523,26 @@ struct usb_serial_device_type keyspan_usa19w_device = { name: "Keyspan USA19W", id_table: keyspan_usa19w_ids, needs_interrupt_in: DONT_CARE, - needs_bulk_in: DONT_CARE, - needs_bulk_out: DONT_CARE, + needs_bulk_in: MUST_HAVE, + needs_bulk_out: MUST_HAVE, num_interrupt_in: NUM_DONT_CARE, - num_bulk_in: NUM_DONT_CARE, - num_bulk_out: NUM_DONT_CARE, + num_bulk_in: 3, + num_bulk_out: 4, num_ports: 1, open: keyspan_open, close: keyspan_close, + write: keyspan_write, + write_room: keyspan_write_room, + //write_bulk_callback: Not used - we define our own herbs + //read_int_callback: keyspan_usa26_read_int_callback, + chars_in_buffer: keyspan_chars_in_buffer, throttle: keyspan_rx_throttle, unthrottle: keyspan_rx_unthrottle, + ioctl: keyspan_ioctl, set_termios: keyspan_set_termios, + break_ctl: keyspan_break_ctl, + startup: keyspan_startup, + shutdown: keyspan_shutdown, }; @@ -366,8 +578,8 @@ struct usb_serial_device_type keyspan_usa28x_device = { close: keyspan_close, write: keyspan_write, write_room: keyspan_write_room, - write_bulk_callback: keyspan_write_bulk_callback, - read_int_callback: keyspan_read_bulk_callback, +// write_bulk_callback: keyspan_write_bulk_callback, +// read_int_callback: keyspan_usa26_read_int_callback, chars_in_buffer: keyspan_chars_in_buffer, throttle: keyspan_rx_throttle, unthrottle: keyspan_rx_unthrottle, @@ -377,10 +589,34 @@ struct usb_serial_device_type keyspan_usa28x_device = { startup: keyspan_startup, shutdown: keyspan_shutdown, +}; +struct usb_serial_device_type keyspan_usa49w_device = { + name: "Keyspan USA49W", + id_table: keyspan_usa49w_ids, + needs_interrupt_in: DONT_CARE, + needs_bulk_in: MUST_HAVE, + needs_bulk_out: MUST_HAVE, + num_interrupt_in: NUM_DONT_CARE, + num_bulk_in: 5, + num_bulk_out: 5, + num_ports: 4, + open: keyspan_open, + close: keyspan_close, + write: keyspan_write, + write_room: keyspan_write_room, + //write_bulk_callback: Not used - we define our own herbs + //read_int_callback: keyspan_usa26_read_int_callback, + chars_in_buffer: keyspan_chars_in_buffer, + throttle: keyspan_rx_throttle, + unthrottle: keyspan_rx_unthrottle, + ioctl: keyspan_ioctl, + set_termios: keyspan_set_termios, + break_ctl: keyspan_break_ctl, + startup: keyspan_startup, + shutdown: keyspan_shutdown, }; - #endif |