aboutsummaryrefslogtreecommitdiffstats
path: root/usb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-05-10 13:43:32 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2006-05-10 13:43:32 -0700
commitd4f086f6fe4a9d7921f8515c598446baad2b456a (patch)
tree7dd3d928b9109136ce28844e58f9bc57e286f3a0 /usb
parenta9e23f5114a08820f93604f65c0711c2b6ce0be4 (diff)
downloadpatches-d4f086f6fe4a9d7921f8515c598446baad2b456a.tar.gz
updated ark3116 driver to latest version
Diffstat (limited to 'usb')
-rw-r--r--usb/usb-serial-ark3116.patch291
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)
+ {