summaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/keyspan.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/keyspan.h')
-rw-r--r--drivers/usb/serial/keyspan.h290
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