aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/serial/ftdi_sio.c90
-rw-r--r--drivers/usb/serial/ftdi_sio.h10
2 files changed, 89 insertions, 11 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 59c7501840cb..80ccfa13e0b3 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -47,7 +47,7 @@
47/* 47/*
48 * Version Information 48 * Version Information
49 */ 49 */
50#define DRIVER_VERSION "v1.4.3" 50#define DRIVER_VERSION "v1.5.0"
51#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" 51#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>"
52#define DRIVER_DESC "USB FTDI Serial Converters Driver" 52#define DRIVER_DESC "USB FTDI Serial Converters Driver"
53 53
@@ -82,7 +82,8 @@ struct ftdi_private {
82 int rx_processed; 82 int rx_processed;
83 unsigned long rx_bytes; 83 unsigned long rx_bytes;
84 84
85 __u16 interface; /* FT2232C port interface (0 for FT232/245) */ 85 __u16 interface; /* FT2232C, FT2232H or FT4232H port interface
86 (0 for FT232/245) */
86 87
87 speed_t force_baud; /* if non-zero, force the baud rate to 88 speed_t force_baud; /* if non-zero, force the baud rate to
88 this value */ 89 this value */
@@ -164,6 +165,7 @@ static struct usb_device_id id_table_combined [] = {
164 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, 165 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
165 { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, 166 { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
166 { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, 167 { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
168 { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) },
167 { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, 169 { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
168 { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, 170 { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
169 { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, 171 { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
@@ -694,6 +696,8 @@ static const char *ftdi_chip_name[] = {
694 [FT232BM] = "FT232BM", 696 [FT232BM] = "FT232BM",
695 [FT2232C] = "FT2232C", 697 [FT2232C] = "FT2232C",
696 [FT232RL] = "FT232RL", 698 [FT232RL] = "FT232RL",
699 [FT2232H] = "FT2232H",
700 [FT4232H] = "FT4232H"
697}; 701};
698 702
699 703
@@ -745,6 +749,8 @@ static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base);
745static unsigned short int ftdi_232am_baud_to_divisor(int baud); 749static unsigned short int ftdi_232am_baud_to_divisor(int baud);
746static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base); 750static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base);
747static __u32 ftdi_232bm_baud_to_divisor(int baud); 751static __u32 ftdi_232bm_baud_to_divisor(int baud);
752static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base);
753static __u32 ftdi_2232h_baud_to_divisor(int baud);
748 754
749static struct usb_serial_driver ftdi_sio_device = { 755static struct usb_serial_driver ftdi_sio_device = {
750 .driver = { 756 .driver = {
@@ -839,6 +845,36 @@ static __u32 ftdi_232bm_baud_to_divisor(int baud)
839 return ftdi_232bm_baud_base_to_divisor(baud, 48000000); 845 return ftdi_232bm_baud_base_to_divisor(baud, 48000000);
840} 846}
841 847
848static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base)
849{
850 static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
851 __u32 divisor;
852 int divisor3;
853
854 /* hi-speed baud rate is 10-bit sampling instead of 16-bit */
855 divisor3 = (base / 10 / baud) * 8;
856
857 divisor = divisor3 >> 3;
858 divisor |= (__u32)divfrac[divisor3 & 0x7] << 14;
859 /* Deal with special cases for highest baud rates. */
860 if (divisor == 1)
861 divisor = 0;
862 else if (divisor == 0x4001)
863 divisor = 1;
864 /*
865 * Set this bit to turn off a divide by 2.5 on baud rate generator
866 * This enables baud rates up to 12Mbaud but cannot reach below 1200
867 * baud with this bit set
868 */
869 divisor |= 0x00020000;
870 return divisor;
871}
872
873static __u32 ftdi_2232h_baud_to_divisor(int baud)
874{
875 return ftdi_2232h_baud_base_to_divisor(baud, 120000000);
876}
877
842#define set_mctrl(port, set) update_mctrl((port), (set), 0) 878#define set_mctrl(port, set) update_mctrl((port), (set), 0)
843#define clear_mctrl(port, clear) update_mctrl((port), 0, (clear)) 879#define clear_mctrl(port, clear) update_mctrl((port), 0, (clear))
844 880
@@ -997,6 +1033,19 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty,
997 baud = 9600; 1033 baud = 9600;
998 } 1034 }
999 break; 1035 break;
1036 case FT2232H: /* FT2232H chip */
1037 case FT4232H: /* FT4232H chip */
1038 if ((baud <= 12000000) & (baud >= 1200)) {
1039 div_value = ftdi_2232h_baud_to_divisor(baud);
1040 } else if (baud < 1200) {
1041 div_value = ftdi_232bm_baud_to_divisor(baud);
1042 } else {
1043 dbg("%s - Baud rate too high!", __func__);
1044 div_value = ftdi_232bm_baud_to_divisor(9600);
1045 div_okay = 0;
1046 baud = 9600;
1047 }
1048 break;
1000 } /* priv->chip_type */ 1049 } /* priv->chip_type */
1001 1050
1002 if (div_okay) { 1051 if (div_okay) {
@@ -1197,14 +1246,29 @@ static void ftdi_determine_type(struct usb_serial_port *port)
1197 if (interfaces > 1) { 1246 if (interfaces > 1) {
1198 int inter; 1247 int inter;
1199 1248
1200 /* Multiple interfaces. Assume FT2232C. */ 1249 /* Multiple interfaces.*/
1201 priv->chip_type = FT2232C; 1250 if (version == 0x0800) {
1251 priv->chip_type = FT4232H;
1252 /* Hi-speed - baud clock runs at 120MHz */
1253 priv->baud_base = 120000000 / 2;
1254 } else if (version == 0x0700) {
1255 priv->chip_type = FT2232H;
1256 /* Hi-speed - baud clock runs at 120MHz */
1257 priv->baud_base = 120000000 / 2;
1258 } else
1259 priv->chip_type = FT2232C;
1260
1202 /* Determine interface code. */ 1261 /* Determine interface code. */
1203 inter = serial->interface->altsetting->desc.bInterfaceNumber; 1262 inter = serial->interface->altsetting->desc.bInterfaceNumber;
1204 if (inter == 0) 1263 if (inter == 0) {
1205 priv->interface = PIT_SIOA; 1264 priv->interface = INTERFACE_A;
1206 else 1265 } else if (inter == 1) {
1207 priv->interface = PIT_SIOB; 1266 priv->interface = INTERFACE_B;
1267 } else if (inter == 2) {
1268 priv->interface = INTERFACE_C;
1269 } else if (inter == 3) {
1270 priv->interface = INTERFACE_D;
1271 }
1208 /* BM-type devices have a bug where bcdDevice gets set 1272 /* BM-type devices have a bug where bcdDevice gets set
1209 * to 0x200 when iSerialNumber is 0. */ 1273 * to 0x200 when iSerialNumber is 0. */
1210 if (version < 0x500) { 1274 if (version < 0x500) {
@@ -1315,7 +1379,9 @@ static int create_sysfs_attrs(struct usb_serial_port *port)
1315 if ((!retval) && 1379 if ((!retval) &&
1316 (priv->chip_type == FT232BM || 1380 (priv->chip_type == FT232BM ||
1317 priv->chip_type == FT2232C || 1381 priv->chip_type == FT2232C ||
1318 priv->chip_type == FT232RL)) { 1382 priv->chip_type == FT232RL ||
1383 priv->chip_type == FT2232H ||
1384 priv->chip_type == FT4232H)) {
1319 retval = device_create_file(&port->dev, 1385 retval = device_create_file(&port->dev,
1320 &dev_attr_latency_timer); 1386 &dev_attr_latency_timer);
1321 } 1387 }
@@ -1334,7 +1400,9 @@ static void remove_sysfs_attrs(struct usb_serial_port *port)
1334 device_remove_file(&port->dev, &dev_attr_event_char); 1400 device_remove_file(&port->dev, &dev_attr_event_char);
1335 if (priv->chip_type == FT232BM || 1401 if (priv->chip_type == FT232BM ||
1336 priv->chip_type == FT2232C || 1402 priv->chip_type == FT2232C ||
1337 priv->chip_type == FT232RL) { 1403 priv->chip_type == FT232RL ||
1404 priv->chip_type == FT2232H ||
1405 priv->chip_type == FT4232H) {
1338 device_remove_file(&port->dev, &dev_attr_latency_timer); 1406 device_remove_file(&port->dev, &dev_attr_latency_timer);
1339 } 1407 }
1340 } 1408 }
@@ -2333,6 +2401,8 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
2333 case FT232BM: 2401 case FT232BM:
2334 case FT2232C: 2402 case FT2232C:
2335 case FT232RL: 2403 case FT232RL:
2404 case FT2232H:
2405 case FT4232H:
2336 /* the 8U232AM returns a two byte value (the sio is a 1 byte 2406 /* the 8U232AM returns a two byte value (the sio is a 1 byte
2337 value) - in the same format as the data returned from the in 2407 value) - in the same format as the data returned from the in
2338 point */ 2408 point */
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 0a09118f315e..f1d440a728a3 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -10,7 +10,7 @@
10 * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side, 10 * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side,
11 * USB on the other. 11 * USB on the other.
12 * 12 *
13 * Thanx to FTDI (http://www.ftdi.co.uk) for so kindly providing details 13 * Thanx to FTDI (http://www.ftdichip.com) for so kindly providing details
14 * of the protocol required to talk to the device and ongoing assistence 14 * of the protocol required to talk to the device and ongoing assistence
15 * during development. 15 * during development.
16 * 16 *
@@ -28,6 +28,7 @@
28#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ 28#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
29#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ 29#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
30#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ 30#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */
31#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */
31#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ 32#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */
32#define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ 33#define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */
33#define FTDI_NF_RIC_PID 0x0001 /* Product Id */ 34#define FTDI_NF_RIC_PID 0x0001 /* Product Id */
@@ -876,6 +877,11 @@
876#define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */ 877#define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */
877#define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */ 878#define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */
878 879
880/* Interface indicies for FT2232, FT2232H and FT4232H devices*/
881#define INTERFACE_A 1
882#define INTERFACE_B 2
883#define INTERFACE_C 3
884#define INTERFACE_D 4
879 885
880/* 886/*
881 * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 887 * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3
@@ -1039,6 +1045,8 @@ typedef enum {
1039 FT232BM = 3, 1045 FT232BM = 3,
1040 FT2232C = 4, 1046 FT2232C = 4,
1041 FT232RL = 5, 1047 FT232RL = 5,
1048 FT2232H = 6,
1049 FT4232H = 7
1042} ftdi_chip_type_t; 1050} ftdi_chip_type_t;
1043 1051
1044typedef enum { 1052typedef enum {