aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ftdi_sio.c
diff options
context:
space:
mode:
authorMartin Geleynse <mgeleyns@ndigital.com>2009-07-02 13:10:35 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-07-12 18:16:39 -0400
commitb760dac290c3482e6883d5f79a2357c82239a3ff (patch)
tree6065446d10300f058706a8be30f5444003a7a8da /drivers/usb/serial/ftdi_sio.c
parente12df02a171d1c10ee664e6571c0e4cb7e1b7c92 (diff)
USB: ftdi: support NDI devices
It enhances the driver for FTDI-based USB serial adapters to recognize and support Northern Digital Inc (NDI) measurement equipment. NDI has been providing this patch for various kernel flavors for several years and we would like to see these changes built in to the driver so that our equipement works without the need for customers to patch the kernel themselves. The patch makes small modifications to 2 files: ./drivers/usb/serial/ftdi_sio.c and ./drivers/usb/serial/ftdi_sio.h. It accomplishes 3 things: 1. Define the VID and PIDs to allow the driver to recognize the NDI devices. 2. Map the 19200 baud rate setting to our higher baud rate of 1.2Mb We would have chosen to map 38400 to the higher rate, similar to what several other vendors have done, but some of our legacy customers actually use 38400, therefore we remap 19200 to the higher rate. 3. We set the default transmit latency in the FTDI chip to 1ms for our devices. Our devices are typically polled at 60Hz and the default ftdi latency seriously affects turn-around time and results in missed data frames. We have created a modprobe option that allows this setting to be increased. This has proven necessary particularly in some virtualized environments. Signed-off-by: Martin P. Geleynse <mgeleyns@ndigital.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r--drivers/usb/serial/ftdi_sio.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index e9e9c78dceb3..88eb5878914a 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -107,6 +107,7 @@ struct ftdi_sio_quirk {
107 107
108static int ftdi_jtag_probe(struct usb_serial *serial); 108static int ftdi_jtag_probe(struct usb_serial *serial);
109static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); 109static int ftdi_mtxorb_hack_setup(struct usb_serial *serial);
110static int ftdi_NDI_device_setup(struct usb_serial *serial);
110static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); 111static void ftdi_USB_UIRT_setup(struct ftdi_private *priv);
111static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); 112static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
112 113
@@ -118,6 +119,10 @@ static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = {
118 .probe = ftdi_mtxorb_hack_setup, 119 .probe = ftdi_mtxorb_hack_setup,
119}; 120};
120 121
122static struct ftdi_sio_quirk ftdi_NDI_device_quirk = {
123 .probe = ftdi_NDI_device_setup,
124};
125
121static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { 126static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
122 .port_probe = ftdi_USB_UIRT_setup, 127 .port_probe = ftdi_USB_UIRT_setup,
123}; 128};
@@ -648,6 +653,16 @@ static struct usb_device_id id_table_combined [] = {
648 { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, 653 { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
649 { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, 654 { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
650 { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, 655 { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
656 { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID),
657 .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
658 { USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID),
659 .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
660 { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID),
661 .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
662 { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID),
663 .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
664 { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID),
665 .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
651 { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, 666 { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
652 { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, 667 { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
653 { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, 668 { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
@@ -671,7 +686,6 @@ static struct usb_device_id id_table_combined [] = {
671 { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, 686 { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
672 { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, 687 { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
673 { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, 688 { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) },
674 { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) },
675 { USB_DEVICE(ATMEL_VID, STK541_PID) }, 689 { USB_DEVICE(ATMEL_VID, STK541_PID) },
676 { USB_DEVICE(DE_VID, STB_PID) }, 690 { USB_DEVICE(DE_VID, STB_PID) },
677 { USB_DEVICE(DE_VID, WHT_PID) }, 691 { USB_DEVICE(DE_VID, WHT_PID) },
@@ -1027,6 +1041,16 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty,
1027 case FT2232C: /* FT2232C chip */ 1041 case FT2232C: /* FT2232C chip */
1028 case FT232RL: 1042 case FT232RL:
1029 if (baud <= 3000000) { 1043 if (baud <= 3000000) {
1044 __u16 product_id = le16_to_cpu(
1045 port->serial->dev->descriptor.idProduct);
1046 if (((FTDI_NDI_HUC_PID == product_id) ||
1047 (FTDI_NDI_SPECTRA_SCU_PID == product_id) ||
1048 (FTDI_NDI_FUTURE_2_PID == product_id) ||
1049 (FTDI_NDI_FUTURE_3_PID == product_id) ||
1050 (FTDI_NDI_AURORA_SCU_PID == product_id)) &&
1051 (baud == 19200)) {
1052 baud = 1200000;
1053 }
1030 div_value = ftdi_232bm_baud_to_divisor(baud); 1054 div_value = ftdi_232bm_baud_to_divisor(baud);
1031 } else { 1055 } else {
1032 dbg("%s - Baud rate too high!", __func__); 1056 dbg("%s - Baud rate too high!", __func__);
@@ -1558,6 +1582,39 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
1558} /* ftdi_HE_TIRA1_setup */ 1582} /* ftdi_HE_TIRA1_setup */
1559 1583
1560/* 1584/*
1585 * Module parameter to control latency timer for NDI FTDI-based USB devices.
1586 * If this value is not set in modprobe.conf.local its value will be set to 1ms.
1587 */
1588static int ndi_latency_timer = 1;
1589
1590/* Setup for the NDI FTDI-based USB devices, which requires hardwired
1591 * baudrate (19200 gets mapped to 1200000).
1592 *
1593 * Called from usbserial:serial_probe.
1594 */
1595static int ftdi_NDI_device_setup(struct usb_serial *serial)
1596{
1597 struct usb_device *udev = serial->dev;
1598 int latency = ndi_latency_timer;
1599 int rv = 0;
1600 char buf[1];
1601
1602 if (latency == 0)
1603 latency = 1;
1604 if (latency > 99)
1605 latency = 99;
1606
1607 dbg("%s setting NDI device latency to %d", __func__, latency);
1608 dev_info(&udev->dev, "NDI device with a latency value of %d", latency);
1609
1610 rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
1611 FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
1612 FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
1613 latency, 0, buf, 0, WDR_TIMEOUT);
1614 return 0;
1615}
1616
1617/*
1561 * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko 1618 * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko
1562 * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from 1619 * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from
1563 * userspace using openocd. 1620 * userspace using openocd.
@@ -2626,3 +2683,5 @@ MODULE_PARM_DESC(vendor, "User specified vendor ID (default="
2626module_param(product, ushort, 0); 2683module_param(product, ushort, 0);
2627MODULE_PARM_DESC(product, "User specified product ID"); 2684MODULE_PARM_DESC(product, "User specified product ID");
2628 2685
2686module_param(ndi_latency_timer, int, S_IRUGO | S_IWUSR);
2687MODULE_PARM_DESC(ndi_latency_timer, "NDI device latency timer override");