[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-usb-devel
Subject:    [linux-usb-devel] USB: Add HX type pl2303
From:       Pete Zaitcev <zaitcev () redhat ! com>
Date:       2005-04-29 1:24:42
Message-ID: 20050428182442.2b642cef.zaitcev () redhat ! com
[Download RAW message or body]

This adds so-called "HX" with a backport from 2.6. We ship this with RHEL 3,
so I thought I would post it for great justice, in case someone needs it.
The failure symptom is that adapter gets recognized fine, receive works fine,
but transmit doesn't.

diff -urp -X dontdiff linux-2.4.31-pre1/drivers/usb/serial/pl2303.c \
                linux-2.4.31-pre1-usb/drivers/usb/serial/pl2303.c
--- linux-2.4.31-pre1/drivers/usb/serial/pl2303.c	2004-08-10 13:43:36.000000000 -0700
+++ linux-2.4.31-pre1-usb/drivers/usb/serial/pl2303.c	2005-04-28 09:38:04.000000000 \
-0700 @@ -59,7 +59,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.10"
+#define DRIVER_VERSION "v0.10.1"	/* Takes from 2.6's */
 #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver"
 
 
@@ -156,20 +156,38 @@ static struct usb_serial_device_type pl2
 	.shutdown =		pl2303_shutdown,
 };
 
+enum pl2303_type {
+	type_0,		/* don't know the difference between type 0 and */
+	type_1,		/* type 1, until someone from prolific tells us... */
+	HX,		/* HX version of the pl2303 chip */
+};
+
 struct pl2303_private {
 	spinlock_t lock;
 	wait_queue_head_t delta_msr_wait;
 	u8 line_control;
 	u8 line_status;
 	u8 termios_initialized;
+	enum pl2303_type type;
 };
 
 
 static int pl2303_startup (struct usb_serial *serial)
 {
 	struct pl2303_private *priv;
+	enum pl2303_type type = type_0;
 	int i;
 
+	if (serial->dev->descriptor.bDeviceClass == 0x02)
+		type = type_0;
+	else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40)
+		type = HX;
+	else if (serial->dev->descriptor.bDeviceClass == 0x00)
+		type = type_1;
+	else if (serial->dev->descriptor.bDeviceClass == 0xFF)
+		type = type_1;
+	dbg("device type: %d", type);
+
 	for (i = 0; i < serial->num_ports; ++i) {
 		priv = kmalloc (sizeof (struct pl2303_private), GFP_KERNEL);
 		if (!priv)
@@ -178,6 +196,7 @@ static int pl2303_startup (struct usb_se
 		spin_lock_init(&priv->lock);
 		init_waitqueue_head(&priv->delta_msr_wait);
 		usb_set_serial_port_data(&serial->port[i], priv);
+		priv->type = type;
 	}
 	return 0;
 }
@@ -380,10 +402,17 @@ static void pl2303_set_termios (struct u
 	     buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
 
 	if (cflag & CRTSCTS) {
-		i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
-				     VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE,
-				     0x0, 0x41, NULL, 0, 100);
-		dbg ("0x40:0x1:0x0:0x41  %d", i);
+		__u16 index;
+		if (priv->type == HX)
+			index = 0x61;
+		else
+			index = 0x41;
+		i = usb_control_msg(serial->dev, 
+				    usb_sndctrlpipe(serial->dev, 0),
+				    VENDOR_WRITE_REQUEST,
+				    VENDOR_WRITE_REQUEST_TYPE,
+				    0x0, index, NULL, 0, 100);
+		dbg ("0x40:0x1:0x0:0x%x  %d", index, i);
 	}
 
 	kfree (buf);
@@ -395,6 +424,7 @@ static int pl2303_open (struct usb_seria
 	struct termios tmp_termios;
 	struct usb_serial *serial = port->serial;
 	unsigned char *buf;
+	struct pl2303_private *priv = port->private;
 	int result;
 
 	if (port_paranoia_check (port, __FUNCTION__))
@@ -427,6 +457,18 @@ static int pl2303_open (struct usb_seria
 	SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 1);
 	FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
 	FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0);
+	SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0, 1);
+	SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 1, 0);
+ 
+	if (priv->type == HX) {
+		/* HX chip */
+		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 0x44);
+		/* reset upstream data pipes */
+          	SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 8, 0);
+        	SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 9, 0);
+	} else {
+		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 0x24);
+	}
 
 	kfree(buf);
 


-------------------------------------------------------
SF.Net email is sponsored by: Tell us your software development plans!
Take this survey and enter to win a one-year sub to SourceForge.net
Plus IDC's 2005 look-ahead and a copy of this survey
Click here to start!  http://www.idcswdc.com/cgi-bin/survey?id=105hix
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic