diff options
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 3dc3768ca71c..8fec5d4455c9 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/smp_lock.h> | ||
36 | #include <linux/tty.h> | 37 | #include <linux/tty.h> |
37 | #include <linux/tty_driver.h> | 38 | #include <linux/tty_driver.h> |
38 | #include <linux/tty_flip.h> | 39 | #include <linux/tty_flip.h> |
@@ -107,6 +108,7 @@ struct ftdi_sio_quirk { | |||
107 | 108 | ||
108 | static int ftdi_jtag_probe(struct usb_serial *serial); | 109 | static int ftdi_jtag_probe(struct usb_serial *serial); |
109 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); | 110 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); |
111 | static int ftdi_NDI_device_setup(struct usb_serial *serial); | ||
110 | static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); | 112 | static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); |
111 | static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); | 113 | static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); |
112 | 114 | ||
@@ -118,6 +120,10 @@ static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = { | |||
118 | .probe = ftdi_mtxorb_hack_setup, | 120 | .probe = ftdi_mtxorb_hack_setup, |
119 | }; | 121 | }; |
120 | 122 | ||
123 | static struct ftdi_sio_quirk ftdi_NDI_device_quirk = { | ||
124 | .probe = ftdi_NDI_device_setup, | ||
125 | }; | ||
126 | |||
121 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { | 127 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { |
122 | .port_probe = ftdi_USB_UIRT_setup, | 128 | .port_probe = ftdi_USB_UIRT_setup, |
123 | }; | 129 | }; |
@@ -191,6 +197,7 @@ static struct usb_device_id id_table_combined [] = { | |||
191 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, | 197 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, |
192 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, | 198 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, |
193 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, | 199 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, |
200 | { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) }, | ||
194 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) }, | 201 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) }, |
195 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, | 202 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, |
196 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, | 203 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, |
@@ -579,6 +586,9 @@ static struct usb_device_id id_table_combined [] = { | |||
579 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, | 586 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, |
580 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, | 587 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, |
581 | { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) }, | 588 | { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) }, |
589 | { USB_DEVICE(FTDI_VID, FTDI_CCSLOAD_N_GO_3_PID) }, | ||
590 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU64_4_PID) }, | ||
591 | { USB_DEVICE(FTDI_VID, FTDI_CCSPRIME8_5_PID) }, | ||
582 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, | 592 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, |
583 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, | 593 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, |
584 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, | 594 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, |
@@ -644,6 +654,16 @@ static struct usb_device_id id_table_combined [] = { | |||
644 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, | 654 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, |
645 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, | 655 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, |
646 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, | 656 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, |
657 | { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID), | ||
658 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
659 | { USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID), | ||
660 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
661 | { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID), | ||
662 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
663 | { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID), | ||
664 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
665 | { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), | ||
666 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
647 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, | 667 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, |
648 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, | 668 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, |
649 | { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, | 669 | { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, |
@@ -660,6 +680,8 @@ static struct usb_device_id id_table_combined [] = { | |||
660 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 680 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
661 | { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), | 681 | { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), |
662 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 682 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
683 | { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID), | ||
684 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
663 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | 685 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, |
664 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, | 686 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, |
665 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, | 687 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, |
@@ -667,7 +689,6 @@ static struct usb_device_id id_table_combined [] = { | |||
667 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, | 689 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, |
668 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, | 690 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, |
669 | { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, | 691 | { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, |
670 | { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) }, | ||
671 | { USB_DEVICE(ATMEL_VID, STK541_PID) }, | 692 | { USB_DEVICE(ATMEL_VID, STK541_PID) }, |
672 | { USB_DEVICE(DE_VID, STB_PID) }, | 693 | { USB_DEVICE(DE_VID, STB_PID) }, |
673 | { USB_DEVICE(DE_VID, WHT_PID) }, | 694 | { USB_DEVICE(DE_VID, WHT_PID) }, |
@@ -677,6 +698,10 @@ static struct usb_device_id id_table_combined [] = { | |||
677 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), | 698 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), |
678 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 699 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
679 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, | 700 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, |
701 | { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, | ||
702 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, | ||
703 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), | ||
704 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
680 | { }, /* Optional parameter entry */ | 705 | { }, /* Optional parameter entry */ |
681 | { } /* Terminating entry */ | 706 | { } /* Terminating entry */ |
682 | }; | 707 | }; |
@@ -1023,6 +1048,16 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, | |||
1023 | case FT2232C: /* FT2232C chip */ | 1048 | case FT2232C: /* FT2232C chip */ |
1024 | case FT232RL: | 1049 | case FT232RL: |
1025 | if (baud <= 3000000) { | 1050 | if (baud <= 3000000) { |
1051 | __u16 product_id = le16_to_cpu( | ||
1052 | port->serial->dev->descriptor.idProduct); | ||
1053 | if (((FTDI_NDI_HUC_PID == product_id) || | ||
1054 | (FTDI_NDI_SPECTRA_SCU_PID == product_id) || | ||
1055 | (FTDI_NDI_FUTURE_2_PID == product_id) || | ||
1056 | (FTDI_NDI_FUTURE_3_PID == product_id) || | ||
1057 | (FTDI_NDI_AURORA_SCU_PID == product_id)) && | ||
1058 | (baud == 19200)) { | ||
1059 | baud = 1200000; | ||
1060 | } | ||
1026 | div_value = ftdi_232bm_baud_to_divisor(baud); | 1061 | div_value = ftdi_232bm_baud_to_divisor(baud); |
1027 | } else { | 1062 | } else { |
1028 | dbg("%s - Baud rate too high!", __func__); | 1063 | dbg("%s - Baud rate too high!", __func__); |
@@ -1554,6 +1589,39 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) | |||
1554 | } /* ftdi_HE_TIRA1_setup */ | 1589 | } /* ftdi_HE_TIRA1_setup */ |
1555 | 1590 | ||
1556 | /* | 1591 | /* |
1592 | * Module parameter to control latency timer for NDI FTDI-based USB devices. | ||
1593 | * If this value is not set in modprobe.conf.local its value will be set to 1ms. | ||
1594 | */ | ||
1595 | static int ndi_latency_timer = 1; | ||
1596 | |||
1597 | /* Setup for the NDI FTDI-based USB devices, which requires hardwired | ||
1598 | * baudrate (19200 gets mapped to 1200000). | ||
1599 | * | ||
1600 | * Called from usbserial:serial_probe. | ||
1601 | */ | ||
1602 | static int ftdi_NDI_device_setup(struct usb_serial *serial) | ||
1603 | { | ||
1604 | struct usb_device *udev = serial->dev; | ||
1605 | int latency = ndi_latency_timer; | ||
1606 | int rv = 0; | ||
1607 | char buf[1]; | ||
1608 | |||
1609 | if (latency == 0) | ||
1610 | latency = 1; | ||
1611 | if (latency > 99) | ||
1612 | latency = 99; | ||
1613 | |||
1614 | dbg("%s setting NDI device latency to %d", __func__, latency); | ||
1615 | dev_info(&udev->dev, "NDI device with a latency value of %d", latency); | ||
1616 | |||
1617 | rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
1618 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | ||
1619 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | ||
1620 | latency, 0, buf, 0, WDR_TIMEOUT); | ||
1621 | return 0; | ||
1622 | } | ||
1623 | |||
1624 | /* | ||
1557 | * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko | 1625 | * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko |
1558 | * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from | 1626 | * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from |
1559 | * userspace using openocd. | 1627 | * userspace using openocd. |
@@ -2121,7 +2189,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
2121 | /* Note that the error flag is duplicated for | 2189 | /* Note that the error flag is duplicated for |
2122 | every character received since we don't know | 2190 | every character received since we don't know |
2123 | which character it applied to */ | 2191 | which character it applied to */ |
2124 | if (!usb_serial_handle_sysrq_char(port, | 2192 | if (!usb_serial_handle_sysrq_char(tty, port, |
2125 | data[packet_offset + i])) | 2193 | data[packet_offset + i])) |
2126 | tty_insert_flip_char(tty, | 2194 | tty_insert_flip_char(tty, |
2127 | data[packet_offset + i], | 2195 | data[packet_offset + i], |
@@ -2622,3 +2690,5 @@ MODULE_PARM_DESC(vendor, "User specified vendor ID (default=" | |||
2622 | module_param(product, ushort, 0); | 2690 | module_param(product, ushort, 0); |
2623 | MODULE_PARM_DESC(product, "User specified product ID"); | 2691 | MODULE_PARM_DESC(product, "User specified product ID"); |
2624 | 2692 | ||
2693 | module_param(ndi_latency_timer, int, S_IRUGO | S_IWUSR); | ||
2694 | MODULE_PARM_DESC(ndi_latency_timer, "NDI device latency timer override"); | ||