diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-05-10 13:43:32 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-05-10 13:43:32 -0700 |
commit | d4f086f6fe4a9d7921f8515c598446baad2b456a (patch) | |
tree | 7dd3d928b9109136ce28844e58f9bc57e286f3a0 /usb | |
parent | a9e23f5114a08820f93604f65c0711c2b6ce0be4 (diff) | |
download | patches-d4f086f6fe4a9d7921f8515c598446baad2b456a.tar.gz |
updated ark3116 driver to latest version
Diffstat (limited to 'usb')
-rw-r--r-- | usb/usb-serial-ark3116.patch | 291 |
1 files changed, 203 insertions, 88 deletions
diff --git a/usb/usb-serial-ark3116.patch b/usb/usb-serial-ark3116.patch index ad875578d278aa..50aa5c8c9b2362 100644 --- a/usb/usb-serial-ark3116.patch +++ b/usb/usb-serial-ark3116.patch @@ -1,8 +1,9 @@ --- - drivers/usb/serial/Kconfig | 10 + + drivers/usb/serial/Kconfig | 10 drivers/usb/serial/Makefile | 1 - drivers/usb/serial/ark3116.c | 363 +++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 374 insertions(+) + drivers/usb/serial/ark3116.c | 467 +++++++++++++++++++++++++++++++++++++++++++ + drivers/usb/serial/generic.c | 1 + 4 files changed, 479 insertions(+) --- gregkh-2.6.orig/drivers/usb/serial/Kconfig +++ gregkh-2.6/drivers/usb/serial/Kconfig @@ -11,8 +12,8 @@ module will be called anydata. +config USB_SERIAL_ARK3116 -+ tristate "USB ARK Micro 3116 USB Serial Driver" -+ depends on USB_SERIAL ++ tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)" ++ depends on USB_SERIAL && EXPERIMENTAL + help + Say Y here if you want to use a ARK Micro 3116 USB to Serial + device. @@ -35,7 +36,7 @@ obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o --- /dev/null +++ gregkh-2.6/drivers/usb/serial/ark3116.c -@@ -0,0 +1,363 @@ +@@ -0,0 +1,467 @@ +/* + * ark3116 + * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547, @@ -62,7 +63,7 @@ +#include "usb-serial.h" + + -+static int debug = 1; ++static int debug; + +static struct usb_device_id id_table [] = { + { USB_DEVICE(0x6547, 0x0232) }, @@ -89,7 +90,8 @@ + +static inline void ARK3116_RCV(struct usb_serial *serial, int seq, + __u8 request, __u8 requesttype, -+ __u16 value, __u16 index, char *buf) ++ __u16 value, __u16 index, __u8 expected, ++ char *buf) +{ + int result; + result = usb_control_msg(serial->dev, @@ -102,6 +104,18 @@ + dbg("%03d < 0 bytes", seq); +} + ++ ++static inline void ARK3116_RCV_QUIET(struct usb_serial *serial, ++ __u8 request, __u8 requesttype, ++ __u16 value, __u16 index, char *buf) ++{ ++ usb_control_msg(serial->dev, ++ usb_rcvctrlpipe(serial->dev,0), ++ request, requesttype, value, index, ++ buf, 0x0000001, 1000); ++} ++ ++ +static int ark3116_attach(struct usb_serial *serial) +{ + char *buf; @@ -117,7 +131,6 @@ + + usb_set_serial_port_data(serial->port[i], priv); + } -+ return 0; + + buf = kmalloc(1, GFP_KERNEL); + if (!buf) { @@ -125,36 +138,53 @@ + goto cleanup; + } + -+ //<-- seq7 -+ ARK3116_RCV(serial, 7,0xFE,0xC0,0x0000,0x0003, buf); -+ -+ //<-- seq12 -+ ARK3116_RCV(serial, 12,0xFE,0xC0,0x0000,0x0004, buf); -+ -+ //--> seq17 -+ ARK3116_SND(serial, 17,0xFE,0x40,0x0001,0x0004); -+ -+ //<-- seq18 -+ ARK3116_RCV(serial, 18,0xFE,0xC0,0x0000,0x0004, buf); -+ -+ //--> seq19 -+ ARK3116_SND(serial, 19,0xFE,0x40,0x0003,0x0004); -+ -+ //<-- seq20 -+ ARK3116_RCV(serial, 20,0xFE,0xC0,0x0000,0x0006, buf); -+ -+ -+ //set 9600 baud -+ ARK3116_SND(serial, 147,0xFE,0x40,0x0083,0x0003); -+ ARK3116_SND(serial, 148,0xFE,0x40,0x0038,0x0000); -+ ARK3116_SND(serial, 149,0xFE,0x40,0x0001,0x0001); -+ ARK3116_SND(serial, 150,0xFE,0x40,0x0003,0x0003); -+ -+ ARK3116_RCV(serial, 151,0xFE,0xC0,0x0000,0x0004, buf); -+ ARK3116_SND(serial, 152,0xFE,0x40,0x0000,0x0003); -+ -+ ARK3116_RCV(serial, 153,0xFE,0xC0,0x0000,0x0003, buf); -+ ARK3116_SND(serial, 154,0xFE,0x40,0x0003,0x0003); ++ /* 3 */ ++ ARK3116_SND(serial, 3,0xFE,0x40,0x0008,0x0002); ++ ARK3116_SND(serial, 4,0xFE,0x40,0x0008,0x0001); ++ ARK3116_SND(serial, 5,0xFE,0x40,0x0000,0x0008); ++ ARK3116_SND(serial, 6,0xFE,0x40,0x0000,0x000B); ++ ++ /* <-- seq7 */ ++ ARK3116_RCV(serial, 7,0xFE,0xC0,0x0000,0x0003, 0x00, buf); ++ ARK3116_SND(serial, 8,0xFE,0x40,0x0080,0x0003); ++ ARK3116_SND(serial, 9,0xFE,0x40,0x001A,0x0000); ++ ARK3116_SND(serial,10,0xFE,0x40,0x0000,0x0001); ++ ARK3116_SND(serial,11,0xFE,0x40,0x0000,0x0003); ++ ++ /* <-- seq12 */ ++ ARK3116_RCV(serial,12,0xFE,0xC0,0x0000,0x0004, 0x00, buf); ++ ARK3116_SND(serial,13,0xFE,0x40,0x0000,0x0004); ++ ++ /* 14 */ ++ ARK3116_RCV(serial,14,0xFE,0xC0,0x0000,0x0004, 0x00, buf); ++ ARK3116_SND(serial,15,0xFE,0x40,0x0000,0x0004); ++ ++ /* 16 */ ++ ARK3116_RCV(serial,16,0xFE,0xC0,0x0000,0x0004, 0x00, buf); ++ /* --> seq17 */ ++ ARK3116_SND(serial,17,0xFE,0x40,0x0001,0x0004); ++ ++ /* <-- seq18 */ ++ ARK3116_RCV(serial,18,0xFE,0xC0,0x0000,0x0004, 0x01, buf); ++ ++ /* --> seq19 */ ++ ARK3116_SND(serial,19,0xFE,0x40,0x0003,0x0004); ++ ++ ++ /* <-- seq20 */ ++ /* seems like serial port status info (RTS, CTS,...) */ ++ /* returns modem control line status ?! */ ++ ARK3116_RCV(serial,20,0xFE,0xC0,0x0000,0x0006, 0xFF, buf); ++ ++ /* set 9600 baud & do some init ?! */ ++ ARK3116_SND(serial,147,0xFE,0x40,0x0083,0x0003); ++ ARK3116_SND(serial,148,0xFE,0x40,0x0038,0x0000); ++ ARK3116_SND(serial,149,0xFE,0x40,0x0001,0x0001); ++ ARK3116_SND(serial,150,0xFE,0x40,0x0003,0x0003); ++ ARK3116_RCV(serial,151,0xFE,0xC0,0x0000,0x0004,0x03, buf); ++ ARK3116_SND(serial,152,0xFE,0x40,0x0000,0x0003); ++ ARK3116_RCV(serial,153,0xFE,0xC0,0x0000,0x0003,0x00, buf); ++ ARK3116_SND(serial,154,0xFE,0x40,0x0003,0x0003); + + kfree(buf); + return(0); @@ -165,31 +195,11 @@ + return -ENOMEM; +} + -+/* strange, if this is used something goes wrong and the port is unusable :-\ */ -+/* maybe timing problem ?! */ -+/* -+static int ark3116_open(struct usb_serial_port *port, struct file *filp) -+{ -+ struct termios tmp_termios; -+ struct usb_serial *serial = port->serial; -+ -+ dbg("%s - port %d", __FUNCTION__, port->number); -+ -+ //initialise termios: -+ //if (port->tty) { -+ // ark3116_set_termios (port, &tmp_termios); -+ //} -+ -+ //ok -+ return(0); -+} -+*/ -+ +static void ark3116_set_termios(struct usb_serial_port *port, + struct termios *old_termios) +{ + struct usb_serial *serial = port->serial; -+ struct ark3116_private *priv = usb_get_serial_port_data(port); ++ struct ark3116_private *priv = usb_get_serial_port_data(port); + unsigned int cflag = port->tty->termios->c_cflag; + unsigned long flags; + int baud; @@ -199,7 +209,7 @@ + + config = 0; + -+ dbg("ark3116_set_termios port %d", port->number); ++ dbg("%s - port %d", __FUNCTION__, port->number); + + if ((!port->tty) || (!port->tty->termios)) { + dbg("%s - no tty structures", __FUNCTION__); @@ -281,20 +291,24 @@ + /* set baudrate: */ + baud = 0; + switch (cflag & CBAUD){ -+ case B0: err ("Can't do B0 yet"); break; -+ case B150: baud = 150; break; -+ case B300: baud = 300; break; -+ case B600: baud = 600; break; -+ case B1200: baud = 1200; break; -+ case B1800: baud = 1800; break; -+ case B2400: baud = 2400; break; -+ case B4800: baud = 4800; break; -+ case B9600: baud = 9600; break; -+ case B19200: baud = 19200; break; -+ case B38400: baud = 38400; break; -+ case B57600: baud = 57600; break; -+ case B115200: baud = 115200; break; -+ case B230400: baud = 230400; break; ++ case B0: ++ err("can't set 0baud, using 9600 instead"); ++ break; ++ case B75: baud = 75; break; ++ case B150: baud = 150; break; ++ case B300: baud = 300; break; ++ case B600: baud = 600; break; ++ case B1200: baud = 1200; break; ++ case B1800: baud = 1800; break; ++ case B2400: baud = 2400; break; ++ case B4800: baud = 4800; break; ++ case B9600: baud = 9600; break; ++ case B19200: baud = 19200; break; ++ case B38400: baud = 38400; break; ++ case B57600: baud = 57600; break; ++ case B115200: baud = 115200; break; ++ case B230400: baud = 230400; break; ++ case B460800: baud = 460800; break; + default: + dbg("does not support the baudrate requested (fix it)"); + break; @@ -308,35 +322,101 @@ + * found by try'n'error, be careful, maybe there are other options + * for multiplicator etc! + */ -+ ark3116_baud = 3000000 / baud; ++ if (baud == 460800) ++ /* strange, for 460800 the formula is wrong ++ * (dont use round(), then 9600baud is wrong) */ ++ ark3116_baud = 7; ++ else ++ ark3116_baud = 3000000 / baud; + + /* ? */ -+ ARK3116_SND(serial, 147,0xFE,0x40,0x0083,0x0003); ++ ARK3116_RCV(serial,0,0xFE,0xC0,0x0000,0x0003, 0x03, buf); ++ /* offset = buf[0]; */ ++ /* offset = 0x03; */ ++ /* dbg("using 0x%04X as target for 0x0003:",0x0080+offset); */ ++ + + /* set baudrate */ + dbg("setting baudrate to %d (->reg=%d)",baud,ark3116_baud); -+ ARK3116_SND(serial, 148,0xFE,0x40,(ark3116_baud & 0x00FF) ,0x0000); -+ ARK3116_SND(serial, 149,0xFE,0x40,(ark3116_baud & 0xFF00)>>8,0x0001); ++ ARK3116_SND(serial,147,0xFE,0x40,0x0083,0x0003); ++ ARK3116_SND(serial,148,0xFE,0x40,(ark3116_baud & 0x00FF) ,0x0000); ++ ARK3116_SND(serial,149,0xFE,0x40,(ark3116_baud & 0xFF00)>>8,0x0001); ++ ARK3116_SND(serial,150,0xFE,0x40,0x0003,0x0003); + + /* ? */ -+ ARK3116_SND(serial, 150,0xFE,0x40,0x0003,0x0003); -+ -+ /* ? */ -+ ARK3116_RCV(serial, 151,0xFE,0xC0,0x0000,0x0004, buf); -+ ARK3116_SND(serial, 152,0xFE,0x40,0x0000,0x0003); ++ ARK3116_RCV(serial,151,0xFE,0xC0,0x0000,0x0004,0x03, buf); ++ ARK3116_SND(serial,152,0xFE,0x40,0x0000,0x0003); + + /* set data bit count, stop bit count & parity: */ + dbg("updating bit count, stop bit or parity (cfg=0x%02X)", config); -+ ARK3116_RCV(serial, 153,0xFE,0xC0,0x0000,0x0003, buf); -+ ARK3116_SND(serial, 154,0xFE,0x40,config,0x0003); ++ ARK3116_RCV(serial,153,0xFE,0xC0,0x0000,0x0003,0x00, buf); ++ ARK3116_SND(serial,154,0xFE,0x40,config,0x0003); + + if (cflag & CRTSCTS) + dbg("CRTSCTS not supported by chipset ?!"); + ++ /* TEST ARK3116_SND(154,0xFE,0x40,0xFFFF, 0x0006); */ ++ + kfree(buf); + return; +} + ++/* strange, if this is used something goes wrong and the port is unusable */ ++/* maybe timing problem ?! */ ++static int ark3116_open(struct usb_serial_port *port, struct file *filp) ++{ ++ struct termios tmp_termios; ++ struct usb_serial *serial = port->serial; ++ char *buf; ++ int result = 0; ++ ++ dbg("%s - port %d", __FUNCTION__, port->number); ++ ++ buf = kmalloc(1, GFP_KERNEL); ++ if (!buf) { ++ dbg("error kmalloc -> out of mem ?"); ++ return -ENOMEM; ++ } ++ ++ result = usb_serial_generic_open(port, filp); ++ if (result) ++ return result; ++ ++ /* open */ ++ ARK3116_RCV(serial,111,0xFE,0xC0,0x0000,0x0003, 0x02, buf); ++ ++ ARK3116_SND(serial,112,0xFE,0x40,0x0082,0x0003); ++ ARK3116_SND(serial,113,0xFE,0x40,0x001A,0x0000); ++ ARK3116_SND(serial,114,0xFE,0x40,0x0000,0x0001); ++ ARK3116_SND(serial,115,0xFE,0x40,0x0002,0x0003); ++ ++ ARK3116_RCV(serial,116,0xFE,0xC0,0x0000,0x0004, 0x03, buf); ++ ARK3116_SND(serial,117,0xFE,0x40,0x0002,0x0004); ++ ++ ARK3116_RCV(serial,118,0xFE,0xC0,0x0000,0x0004, 0x02, buf); ++ ARK3116_SND(serial,119,0xFE,0x40,0x0000,0x0004); ++ ++ ARK3116_RCV(serial,120,0xFE,0xC0,0x0000,0x0004, 0x00, buf); ++ ++ ARK3116_SND(serial,121,0xFE,0x40,0x0001,0x0004); ++ ++ ARK3116_RCV(serial,122,0xFE,0xC0,0x0000,0x0004, 0x01, buf); ++ ++ ARK3116_SND(serial,123,0xFE,0x40,0x0003,0x0004); ++ ++ /* returns different values (control lines ?!) */ ++ ARK3116_RCV(serial,124,0xFE,0xC0,0x0000,0x0006, 0xFF, buf); ++ ++ /* initialise termios: */ ++ if (port->tty) ++ ark3116_set_termios(port, &tmp_termios); ++ ++ kfree(buf); ++ ++ return result; ++ ++} ++ +static int ark3116_ioctl(struct usb_serial_port *port, struct file *file, + unsigned int cmd, unsigned long arg) +{ @@ -346,8 +426,32 @@ + +static int ark3116_tiocmget(struct usb_serial_port *port, struct file *file) +{ -+ dbg("tiocmget not supported yet..."); -+ return 0; ++ struct usb_serial *serial = port->serial; ++ char *buf; ++ char temp; ++ ++ /* seems like serial port status info (RTS, CTS,...) is stored ++ * in reg(?) 0x0006 ++ * pcb connection point 11 = GND -> sets bit4 of response ++ * pcb connection point 7 = GND -> sets bit6 of response ++ */ ++ ++ buf = kmalloc(1, GFP_KERNEL); ++ if (!buf) { ++ dbg("error kmalloc"); ++ return -ENOMEM; ++ } ++ ++ /* read register: */ ++ ARK3116_RCV_QUIET(serial,0xFE,0xC0,0x0000,0x0006,buf); ++ temp = buf[0]; ++ kfree(buf); ++ ++ /* i do not really know if bit4=CTS and bit6=DSR... was just a ++ * quick guess !! ++ */ ++ return (temp & (1<<4) ? TIOCM_CTS : 0) | ++ (temp & (1<<6) ? TIOCM_DSR : 0); +} + +static struct usb_driver ark3116_driver = { @@ -371,6 +475,7 @@ + .set_termios = ark3116_set_termios, + .ioctl = ark3116_ioctl, + .tiocmget = ark3116_tiocmget, ++ .open = ark3116_open, +}; + +static int __init ark3116_init(void) @@ -399,3 +504,13 @@ +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug enabled or not"); + +--- gregkh-2.6.orig/drivers/usb/serial/generic.c ++++ gregkh-2.6/drivers/usb/serial/generic.c +@@ -138,6 +138,7 @@ int usb_serial_generic_open (struct usb_ + + return result; + } ++EXPORT_SYMBOL_GPL(usb_serial_generic_open); + + static void generic_cleanup (struct usb_serial_port *port) + { |