15fd54aceSGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0+ 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * USB FTDI SIO driver 41da177e4SLinus Torvalds * 5659597b7SJohan Hovold * Copyright (C) 2009 - 2013 6d3901a06SJohan Hovold * Johan Hovold (jhovold@gmail.com) 71da177e4SLinus Torvalds * Copyright (C) 1999 - 2001 81da177e4SLinus Torvalds * Greg Kroah-Hartman (greg@kroah.com) 91da177e4SLinus Torvalds * Bill Ryder (bryder@sgi.com) 101da177e4SLinus Torvalds * Copyright (C) 2002 111da177e4SLinus Torvalds * Kuba Ober (kuba@mareimbrium.org) 121da177e4SLinus Torvalds * 13ecefae6dSMauro Carvalho Chehab * See Documentation/usb/usb-serial.rst for more information on using this 14464cbb24SAlan Cox * driver 151da177e4SLinus Torvalds * 161da177e4SLinus Torvalds * See http://ftdi-usb-sio.sourceforge.net for up to date testing info 171da177e4SLinus Torvalds * and extra documentation 181da177e4SLinus Torvalds * 19504b55ccSGreg Kroah-Hartman * Change entries from 2004 and earlier can be found in versions of this 20504b55ccSGreg Kroah-Hartman * file in kernel versions prior to the 2.6.24 release. 211da177e4SLinus Torvalds * 221da177e4SLinus Torvalds */ 231da177e4SLinus Torvalds 241da177e4SLinus Torvalds /* Bill Ryder - bryder@sgi.com - wrote the FTDI_SIO implementation */ 251da177e4SLinus Torvalds /* Thanx to FTDI for so kindly providing details of the protocol required */ 261da177e4SLinus Torvalds /* to talk to the device */ 27464cbb24SAlan Cox /* Thanx to gkh and the rest of the usb dev group for all code I have 28464cbb24SAlan Cox assimilated :-) */ 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds #include <linux/kernel.h> 311da177e4SLinus Torvalds #include <linux/errno.h> 321da177e4SLinus Torvalds #include <linux/slab.h> 331da177e4SLinus Torvalds #include <linux/tty.h> 341da177e4SLinus Torvalds #include <linux/tty_driver.h> 351da177e4SLinus Torvalds #include <linux/tty_flip.h> 361da177e4SLinus Torvalds #include <linux/module.h> 371da177e4SLinus Torvalds #include <linux/spinlock.h> 38bd09a9f5SAlessio Igor Bogani #include <linux/mutex.h> 39464cbb24SAlan Cox #include <linux/uaccess.h> 401da177e4SLinus Torvalds #include <linux/usb.h> 411da177e4SLinus Torvalds #include <linux/serial.h> 42ba93cc7dSKaroly Pados #include <linux/gpio/driver.h> 43a969888cSGreg Kroah-Hartman #include <linux/usb/serial.h> 441da177e4SLinus Torvalds #include "ftdi_sio.h" 4531844d55SAndreas Mohr #include "ftdi_sio_ids.h" 461da177e4SLinus Torvalds 47d3901a06SJohan Hovold #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>, Andreas Mohr, Johan Hovold <jhovold@gmail.com>" 481da177e4SLinus Torvalds #define DRIVER_DESC "USB FTDI Serial Converters Driver" 491da177e4SLinus Torvalds 50366e89aaSJohan Hovold enum ftdi_chip_type { 51366e89aaSJohan Hovold SIO, 5201aeb31fSJohan Hovold FT232A, 5301aeb31fSJohan Hovold FT232B, 54366e89aaSJohan Hovold FT2232C, 5501aeb31fSJohan Hovold FT232R, 5601aeb31fSJohan Hovold FT232H, 57366e89aaSJohan Hovold FT2232H, 58366e89aaSJohan Hovold FT4232H, 59cfebcd53SAmireddy mallikarjuna reddy FT4232HA, 60cfebcd53SAmireddy mallikarjuna reddy FT232HP, 61cfebcd53SAmireddy mallikarjuna reddy FT233HP, 62cfebcd53SAmireddy mallikarjuna reddy FT2232HP, 63cfebcd53SAmireddy mallikarjuna reddy FT2233HP, 64cfebcd53SAmireddy mallikarjuna reddy FT4232HP, 65cfebcd53SAmireddy mallikarjuna reddy FT4233HP, 66366e89aaSJohan Hovold FTX, 67366e89aaSJohan Hovold }; 681da177e4SLinus Torvalds 690ffbbe25SOliver Neukum struct ftdi_private { 703bb36aa2SGreg Kroah-Hartman enum ftdi_chip_type chip_type; 710ffbbe25SOliver Neukum int baud_base; /* baud base clock for divisor setting */ 72464cbb24SAlan Cox int custom_divisor; /* custom_divisor kludge, this is for 73464cbb24SAlan Cox baud_base (different from what goes to the 74464cbb24SAlan Cox chip!) */ 7516410115SJohan Hovold u16 last_set_data_value; /* the last data state set - needed for doing 76464cbb24SAlan Cox * a break 77464cbb24SAlan Cox */ 780ffbbe25SOliver Neukum int flags; /* some ASYNC_xxxx flags are supported */ 790ffbbe25SOliver Neukum unsigned long last_dtr_rts; /* saved modem control outputs */ 80fca5430dSSimon Arlott char prev_status; /* Used for TIOCMIWAIT */ 81c466cd2bSGreg Kroah-Hartman char transmit_empty; /* If transmitter is empty or not */ 82027bf37dSJohan Hovold u16 channel; /* channel index, or 0 for legacy types */ 830ffbbe25SOliver Neukum 84464cbb24SAlan Cox speed_t force_baud; /* if non-zero, force the baud rate to 85464cbb24SAlan Cox this value */ 86464cbb24SAlan Cox int force_rtscts; /* if non-zero, force RTS-CTS to always 87464cbb24SAlan Cox be enabled */ 880ffbbe25SOliver Neukum 89557aaa7fSAlan Cox unsigned int latency; /* latency setting in use */ 90895f28baSMark Adamson unsigned short max_packet_size; 919c67d28eSAlessio Igor Bogani struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */ 92ba93cc7dSKaroly Pados #ifdef CONFIG_GPIOLIB 93ba93cc7dSKaroly Pados struct gpio_chip gc; 94ba93cc7dSKaroly Pados struct mutex gpio_lock; /* protects GPIO state */ 95ba93cc7dSKaroly Pados bool gpio_registered; /* is the gpiochip in kernel registered */ 96ba93cc7dSKaroly Pados bool gpio_used; /* true if the user requested a gpio */ 97ba93cc7dSKaroly Pados u8 gpio_altfunc; /* which pins are in gpio mode */ 98ba93cc7dSKaroly Pados u8 gpio_output; /* pin directions cache */ 99ba93cc7dSKaroly Pados u8 gpio_value; /* pin value for outputs */ 100ba93cc7dSKaroly Pados #endif 1010ffbbe25SOliver Neukum }; 1020ffbbe25SOliver Neukum 1038f977e42SIan Abbott /* struct ftdi_sio_quirk is used by devices requiring special attention. */ 1048f977e42SIan Abbott struct ftdi_sio_quirk { 105fa91d43bSTony Lindgren int (*probe)(struct usb_serial *); 106464cbb24SAlan Cox /* Special settings for probed ports. */ 107464cbb24SAlan Cox void (*port_probe)(struct ftdi_private *); 1088f977e42SIan Abbott }; 1098f977e42SIan Abbott 11020734345SHarald Welte static int ftdi_jtag_probe(struct usb_serial *serial); 111b760dac2SMartin Geleynse static int ftdi_NDI_device_setup(struct usb_serial *serial); 1126ec2f46cSJean-Christophe PLAGNIOL-VILLARD static int ftdi_stmclite_probe(struct usb_serial *serial); 113c96fbdd0SJean-Christophe PLAGNIOL-VILLARD static int ftdi_8u2232c_probe(struct usb_serial *serial); 1140ffbbe25SOliver Neukum static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); 1150ffbbe25SOliver Neukum static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); 1168f977e42SIan Abbott 1173c77f7c9SJulia Lawall static const struct ftdi_sio_quirk ftdi_jtag_quirk = { 11820734345SHarald Welte .probe = ftdi_jtag_probe, 119fa91d43bSTony Lindgren }; 120fa91d43bSTony Lindgren 1213c77f7c9SJulia Lawall static const struct ftdi_sio_quirk ftdi_NDI_device_quirk = { 122b760dac2SMartin Geleynse .probe = ftdi_NDI_device_setup, 123b760dac2SMartin Geleynse }; 124b760dac2SMartin Geleynse 1253c77f7c9SJulia Lawall static const struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { 1260ffbbe25SOliver Neukum .port_probe = ftdi_USB_UIRT_setup, 1278f977e42SIan Abbott }; 1288f977e42SIan Abbott 1293c77f7c9SJulia Lawall static const struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { 1300ffbbe25SOliver Neukum .port_probe = ftdi_HE_TIRA1_setup, 1311da177e4SLinus Torvalds }; 1321da177e4SLinus Torvalds 1333c77f7c9SJulia Lawall static const struct ftdi_sio_quirk ftdi_stmclite_quirk = { 1346ec2f46cSJean-Christophe PLAGNIOL-VILLARD .probe = ftdi_stmclite_probe, 1356ec2f46cSJean-Christophe PLAGNIOL-VILLARD }; 1366ec2f46cSJean-Christophe PLAGNIOL-VILLARD 1373c77f7c9SJulia Lawall static const struct ftdi_sio_quirk ftdi_8u2232c_quirk = { 138c96fbdd0SJean-Christophe PLAGNIOL-VILLARD .probe = ftdi_8u2232c_probe, 139c96fbdd0SJean-Christophe PLAGNIOL-VILLARD }; 140c96fbdd0SJean-Christophe PLAGNIOL-VILLARD 1411da177e4SLinus Torvalds /* 1421da177e4SLinus Torvalds * The 8U232AM has the same API as the sio except for: 1431da177e4SLinus Torvalds * - it can support MUCH higher baudrates; up to: 1441da177e4SLinus Torvalds * o 921600 for RS232 and 2000000 for RS422/485 at 48MHz 1451da177e4SLinus Torvalds * o 230400 at 12MHz 1461da177e4SLinus Torvalds * so .. 8U232AM's baudrate setting codes are different 1471da177e4SLinus Torvalds * - it has a two byte status code. 1481da177e4SLinus Torvalds * - it returns characters every 16ms (the FTDI does it every 40ms) 1491da177e4SLinus Torvalds * 1501da177e4SLinus Torvalds * the bcdDevice value is used to differentiate FT232BM and FT245BM from 1511da177e4SLinus Torvalds * the earlier FT8U232AM and FT8U232BM. For now, include all known VID/PID 1521da177e4SLinus Torvalds * combinations in both tables. 1538f977e42SIan Abbott * FIXME: perhaps bcdDevice can also identify 12MHz FT8U232AM devices, 1548f977e42SIan Abbott * but I don't know if those ever went into mass production. [Ian Abbott] 1551da177e4SLinus Torvalds */ 1561da177e4SLinus Torvalds 1571da177e4SLinus Torvalds 1581da177e4SLinus Torvalds 15965e1ec67SAndreas Mohr /* 160e17c1aa2SJohan Hovold * Device ID not listed? Test it using 161e17c1aa2SJohan Hovold * /sys/bus/usb-serial/drivers/ftdi_sio/new_id and send a patch or report. 16265e1ec67SAndreas Mohr */ 1635c6b98ddSJohan Hovold static const struct usb_device_id id_table_combined[] = { 1647f2719f0SPerry Hung { USB_DEVICE(FTDI_VID, FTDI_BRICK_PID) }, 165ce7e9065SArtur Zimmer { USB_DEVICE(FTDI_VID, FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID) }, 1665a9443f0SChristian Simon { USB_DEVICE(FTDI_VID, FTDI_CTI_MINI_PID) }, 1675a9443f0SChristian Simon { USB_DEVICE(FTDI_VID, FTDI_CTI_NANO_PID) }, 1682011e924SJonathan Davies { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, 1692011e924SJonathan Davies { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, 17001ba0856SAndrew Ewert { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, 1716552cc7fSJohan Hovold { USB_DEVICE(FTDI_VID, FTDI_BM_ATOM_NANO_PID) }, 17265e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, 17367847baeSBjørn Mork { USB_DEVICE(FTDI_VID, FTDI_EV3CON_PID) }, 1746e1ab3edSPeter Mack { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, 1756e1ab3edSPeter Mack { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, 1766e1ab3edSPeter Mack { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, 1776e1ab3edSPeter Mack { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_3_PID) }, 1786e1ab3edSPeter Mack { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_4_PID) }, 1796e1ab3edSPeter Mack { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_5_PID) }, 1806e1ab3edSPeter Mack { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_6_PID) }, 1816e1ab3edSPeter Mack { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_7_PID) }, 182b6180ef7Sdranch@trinnet.net { USB_DEVICE(FTDI_VID, FTDI_USINT_CAT_PID) }, 183b6180ef7Sdranch@trinnet.net { USB_DEVICE(FTDI_VID, FTDI_USINT_WKEY_PID) }, 184b6180ef7Sdranch@trinnet.net { USB_DEVICE(FTDI_VID, FTDI_USINT_RS232_PID) }, 18572a9f958SRazvan Gavril { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, 1861da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, 18769737dfaSLuiz Fernando N. Capitulino { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, 188d099321bSLuiz Fernando N. Capitulino { USB_DEVICE(FTDI_VID, FTDI_IPLUS2_PID) }, 189fad14a0dSFrank Sievertsen { USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) }, 1901da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, 1911da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, 1921da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, 193d8b21606SGard Spreemann { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, 194c96fbdd0SJean-Christophe PLAGNIOL-VILLARD { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) , 195c96fbdd0SJean-Christophe PLAGNIOL-VILLARD .driver_info = (kernel_ulong_t)&ftdi_8u2232c_quirk }, 196094c2e6dSMark Adamson { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) }, 197309427b6SUwe Bonnes { USB_DEVICE(FTDI_VID, FTDI_232H_PID) }, 198dc0827c1SJim Paris { USB_DEVICE(FTDI_VID, FTDI_FTX_PID) }, 199cfebcd53SAmireddy mallikarjuna reddy { USB_DEVICE(FTDI_VID, FTDI_FT2233HP_PID) }, 200cfebcd53SAmireddy mallikarjuna reddy { USB_DEVICE(FTDI_VID, FTDI_FT4233HP_PID) }, 201cfebcd53SAmireddy mallikarjuna reddy { USB_DEVICE(FTDI_VID, FTDI_FT2232HP_PID) }, 202cfebcd53SAmireddy mallikarjuna reddy { USB_DEVICE(FTDI_VID, FTDI_FT4232HP_PID) }, 203cfebcd53SAmireddy mallikarjuna reddy { USB_DEVICE(FTDI_VID, FTDI_FT233HP_PID) }, 204cfebcd53SAmireddy mallikarjuna reddy { USB_DEVICE(FTDI_VID, FTDI_FT232HP_PID) }, 205cfebcd53SAmireddy mallikarjuna reddy { USB_DEVICE(FTDI_VID, FTDI_FT4232HA_PID) }, 206c0f8d561SChristophe Mariac { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, 2071da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, 2082adb80e9SGuido Scholz { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, 209ec3815c3Smail@rainerkeller.de { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_SNIFFER_PID) }, 210ec3815c3Smail@rainerkeller.de { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) }, 211ec3815c3Smail@rainerkeller.de { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) }, 21299c1e4f8SRainer Keller { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) }, 21358f8b6c4SStefani Seibold { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_BOOST_PID) }, 214d7e14b37SMartin Teichmann { USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) }, 21571381439SGomella, Andrew (NIH/NHLBI) [F] { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_CC_PID) }, 21671381439SGomella, Andrew (NIH/NHLBI) [F] { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_AGP_PID) }, 2171da177e4SLinus Torvalds { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, 2181da177e4SLinus Torvalds { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, 219f2ee6955SAlan Cox { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, 22076f24e3fSUlrich Hahn { USB_DEVICE(FTDI_VID, FTDI_TAGSYS_LP101_PID) }, 22176f24e3fSUlrich Hahn { USB_DEVICE(FTDI_VID, FTDI_TAGSYS_P200X_PID) }, 222ea233f80SGalen Seitz { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) }, 2231da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, 2241da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, 2251da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) }, 2261da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_XF_633_PID) }, 2271da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_XF_631_PID) }, 2281da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_XF_635_PID) }, 2291da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_XF_640_PID) }, 2301da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_XF_642_PID) }, 2311da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) }, 23274bdf22bSHakan Kvist { USB_DEVICE(FTDI_VID, FTDI_URBAN_0_PID) }, 23374bdf22bSHakan Kvist { USB_DEVICE(FTDI_VID, FTDI_URBAN_1_PID) }, 2341da177e4SLinus Torvalds { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, 2351da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) }, 2368f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) }, 2378f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MTXORB_1_PID) }, 2388f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MTXORB_2_PID) }, 2398f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MTXORB_3_PID) }, 2408f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, 2418f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, 2428f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, 243b34efeeaSFolkert van Heusden { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) }, 2446fdbad80SJacques Viviers { USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) }, 2458da0e55cSDavid Bauer { USB_DEVICE(FTDI_VID, FTDI_AUTO_M3_OP_COM_V2_PID) }, 246ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) }, 247ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, 248ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, 249ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0103_PID) }, 250ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0104_PID) }, 251ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0105_PID) }, 252ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0106_PID) }, 253ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0107_PID) }, 254ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0108_PID) }, 255ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0109_PID) }, 256ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010A_PID) }, 257ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010B_PID) }, 258ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010C_PID) }, 259ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010D_PID) }, 260ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010E_PID) }, 261ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010F_PID) }, 262ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0110_PID) }, 263ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0111_PID) }, 264ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0112_PID) }, 265ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0113_PID) }, 266ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0114_PID) }, 267ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0115_PID) }, 268ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0116_PID) }, 269ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0117_PID) }, 270ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0118_PID) }, 271ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0119_PID) }, 272ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011A_PID) }, 273ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011B_PID) }, 274ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011C_PID) }, 275ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011D_PID) }, 276ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011E_PID) }, 277ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011F_PID) }, 278ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0120_PID) }, 279ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0121_PID) }, 280ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0122_PID) }, 281ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0123_PID) }, 282ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0124_PID) }, 283ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0125_PID) }, 284ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0126_PID) }, 28519de4278SJohan Hovold { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0127_PID) }, 286ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0128_PID) }, 287ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0129_PID) }, 288ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012A_PID) }, 289ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012B_PID) }, 29019de4278SJohan Hovold { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012C_PID) }, 291ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012D_PID) }, 292ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012E_PID) }, 293ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012F_PID) }, 294ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0130_PID) }, 295ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0131_PID) }, 296ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0132_PID) }, 297ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0133_PID) }, 298ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0134_PID) }, 299ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0135_PID) }, 300ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0136_PID) }, 301ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0137_PID) }, 302ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0138_PID) }, 303ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0139_PID) }, 304ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013A_PID) }, 305ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013B_PID) }, 306ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013C_PID) }, 307ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013D_PID) }, 308ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013E_PID) }, 309ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013F_PID) }, 310ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0140_PID) }, 311ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0141_PID) }, 312ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0142_PID) }, 313ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0143_PID) }, 314ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0144_PID) }, 315ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0145_PID) }, 316ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0146_PID) }, 317ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0147_PID) }, 318ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0148_PID) }, 319ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0149_PID) }, 320ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014A_PID) }, 321ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014B_PID) }, 322ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014C_PID) }, 323ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014D_PID) }, 324ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014E_PID) }, 325ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014F_PID) }, 326ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0150_PID) }, 327ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0151_PID) }, 328ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0152_PID) }, 32919de4278SJohan Hovold { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0153_PID) }, 33019de4278SJohan Hovold { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0154_PID) }, 33119de4278SJohan Hovold { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0155_PID) }, 33219de4278SJohan Hovold { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0156_PID) }, 33319de4278SJohan Hovold { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0157_PID) }, 33419de4278SJohan Hovold { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0158_PID) }, 335ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0159_PID) }, 336ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015A_PID) }, 337ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015B_PID) }, 338ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015C_PID) }, 339ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015D_PID) }, 340ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015E_PID) }, 341ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015F_PID) }, 342ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0160_PID) }, 343ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0161_PID) }, 344ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0162_PID) }, 345ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0163_PID) }, 346ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0164_PID) }, 347ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0165_PID) }, 348ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0166_PID) }, 349ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0167_PID) }, 350ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0168_PID) }, 351ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0169_PID) }, 352ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016A_PID) }, 353ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016B_PID) }, 354ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016C_PID) }, 355ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016D_PID) }, 356ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016E_PID) }, 357ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016F_PID) }, 358ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0170_PID) }, 359ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0171_PID) }, 360ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0172_PID) }, 361ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0173_PID) }, 362ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0174_PID) }, 363ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0175_PID) }, 364ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0176_PID) }, 365ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0177_PID) }, 366ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0178_PID) }, 367ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0179_PID) }, 368ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017A_PID) }, 369ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017B_PID) }, 370ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017C_PID) }, 371ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017D_PID) }, 372ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017E_PID) }, 373ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017F_PID) }, 374ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0180_PID) }, 375ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0181_PID) }, 376ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0182_PID) }, 377ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0183_PID) }, 378ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0184_PID) }, 379ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0185_PID) }, 380ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0186_PID) }, 381ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0187_PID) }, 382ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0188_PID) }, 383ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0189_PID) }, 384ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018A_PID) }, 385ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018B_PID) }, 386ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018C_PID) }, 387ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018D_PID) }, 388ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018E_PID) }, 389ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018F_PID) }, 390ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0190_PID) }, 391ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0191_PID) }, 392ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0192_PID) }, 393ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0193_PID) }, 394ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0194_PID) }, 395ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0195_PID) }, 396ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0196_PID) }, 397ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0197_PID) }, 398ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0198_PID) }, 399ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0199_PID) }, 400ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019A_PID) }, 401ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019B_PID) }, 402ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019C_PID) }, 403ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019D_PID) }, 404ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019E_PID) }, 405ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019F_PID) }, 406ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A0_PID) }, 407ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A1_PID) }, 408ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A2_PID) }, 409ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A3_PID) }, 410ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A4_PID) }, 411ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A5_PID) }, 412ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A6_PID) }, 413ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A7_PID) }, 414ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A8_PID) }, 415ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A9_PID) }, 416ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AA_PID) }, 417ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AB_PID) }, 418ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AC_PID) }, 419ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AD_PID) }, 420ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AE_PID) }, 421ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AF_PID) }, 422ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B0_PID) }, 423ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B1_PID) }, 424ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B2_PID) }, 425ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B3_PID) }, 426ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B4_PID) }, 427ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B5_PID) }, 428ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B6_PID) }, 429ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B7_PID) }, 430ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B8_PID) }, 431ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B9_PID) }, 432ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BA_PID) }, 433ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BB_PID) }, 434ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BC_PID) }, 435ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BD_PID) }, 436ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BE_PID) }, 437ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BF_PID) }, 438ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C0_PID) }, 439ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C1_PID) }, 440ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C2_PID) }, 441ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C3_PID) }, 442ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C4_PID) }, 443ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C5_PID) }, 444ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C6_PID) }, 445ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C7_PID) }, 446ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C8_PID) }, 447ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C9_PID) }, 448ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CA_PID) }, 449ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CB_PID) }, 450ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CC_PID) }, 451ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CD_PID) }, 452ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CE_PID) }, 453ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CF_PID) }, 454ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D0_PID) }, 455ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D1_PID) }, 456ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D2_PID) }, 457ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D3_PID) }, 458ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D4_PID) }, 459ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D5_PID) }, 460ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D6_PID) }, 461ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D7_PID) }, 462ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D8_PID) }, 463ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D9_PID) }, 464ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DA_PID) }, 465ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DB_PID) }, 466ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DC_PID) }, 467ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DD_PID) }, 468ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DE_PID) }, 469ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DF_PID) }, 470ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E0_PID) }, 471ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E1_PID) }, 472ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E2_PID) }, 473ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E3_PID) }, 474ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E4_PID) }, 475ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E5_PID) }, 476ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E6_PID) }, 477ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E7_PID) }, 478ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E8_PID) }, 479ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E9_PID) }, 480ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EA_PID) }, 481ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EB_PID) }, 482ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EC_PID) }, 483ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01ED_PID) }, 484ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EE_PID) }, 485ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EF_PID) }, 486ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F0_PID) }, 487ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F1_PID) }, 488ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F2_PID) }, 489ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F3_PID) }, 490ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F4_PID) }, 491ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F5_PID) }, 492ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F6_PID) }, 493ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F7_PID) }, 494ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F8_PID) }, 495ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F9_PID) }, 496ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FA_PID) }, 497ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FB_PID) }, 498ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FC_PID) }, 499ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FD_PID) }, 500ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FE_PID) }, 501ebb3770cSRay Molenkamp { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FF_PID) }, 502204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_4701_PID) }, 503204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9300_PID) }, 504204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9301_PID) }, 505204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9302_PID) }, 506204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9303_PID) }, 507204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9304_PID) }, 508204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9305_PID) }, 509204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9306_PID) }, 510204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9307_PID) }, 511204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9308_PID) }, 512204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9309_PID) }, 513204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930A_PID) }, 514204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930B_PID) }, 515204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930C_PID) }, 516204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930D_PID) }, 517204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930E_PID) }, 518204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930F_PID) }, 519204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9310_PID) }, 520204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9311_PID) }, 521204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9312_PID) }, 522204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9313_PID) }, 523204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9314_PID) }, 524204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9315_PID) }, 525204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9316_PID) }, 526204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9317_PID) }, 527204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9318_PID) }, 528204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9319_PID) }, 529204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931A_PID) }, 530204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931B_PID) }, 531204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931C_PID) }, 532204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931D_PID) }, 533204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931E_PID) }, 534204ec6e0STroy Clark { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931F_PID) }, 5358f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, 5361da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, 537274a4bbcSDave Platt { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, 538868e440dSJelle Foks { USB_DEVICE(FTDI_VID, FTDI_USBX_707_PID) }, 5391da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) }, 5401da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) }, 5411da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) }, 5421da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2104_PID) }, 543a1484827SJustin Carlson { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2106_PID) }, 5441da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2201_1_PID) }, 5451da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2201_2_PID) }, 5461da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2202_1_PID) }, 5471da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2202_2_PID) }, 5481da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2203_1_PID) }, 5491da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2203_2_PID) }, 5501da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_1_PID) }, 5511da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_2_PID) }, 5521da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_3_PID) }, 5531da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_4_PID) }, 5541da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_1_PID) }, 5551da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_2_PID) }, 5561da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_3_PID) }, 5571da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_4_PID) }, 5581da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_1_PID) }, 5591da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_2_PID) }, 5601da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_3_PID) }, 5611da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_4_PID) }, 5621da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_1_PID) }, 5631da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_2_PID) }, 5641da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_3_PID) }, 5651da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_4_PID) }, 5661da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_5_PID) }, 5671da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_6_PID) }, 5681da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_7_PID) }, 5691da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_8_PID) }, 5701da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_1_PID) }, 5711da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_2_PID) }, 5721da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_3_PID) }, 5731da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_4_PID) }, 5741da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_5_PID) }, 5751da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_6_PID) }, 5761da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_7_PID) }, 5771da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_8_PID) }, 5781da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_1_PID) }, 5791da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_2_PID) }, 5801da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_3_PID) }, 5811da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_4_PID) }, 5821da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_5_PID) }, 5831da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_6_PID) }, 5841da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_7_PID) }, 5851da177e4SLinus Torvalds { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) }, 5866d161b99SScott Dial { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_1_PID) }, 5876d161b99SScott Dial { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_2_PID) }, 5886d161b99SScott Dial { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_3_PID) }, 5896d161b99SScott Dial { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_4_PID) }, 5901da177e4SLinus Torvalds { USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) }, 5911da177e4SLinus Torvalds { USB_DEVICE(OCT_VID, OCT_US101_PID) }, 59211a31d84SJohan Hovold { USB_DEVICE(OCT_VID, OCT_DK201_PID) }, 5938f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_HE_TIRA1_PID), 5948f977e42SIan Abbott .driver_info = (kernel_ulong_t)&ftdi_HE_TIRA1_quirk }, 5958f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID), 5968f977e42SIan Abbott .driver_info = (kernel_ulong_t)&ftdi_USB_UIRT_quirk }, 5971da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_1) }, 5981da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, PROTEGO_R2X0) }, 5991da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_3) }, 6001da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_4) }, 6018f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E808_PID) }, 6028f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E809_PID) }, 6038f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80A_PID) }, 6048f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80B_PID) }, 6058f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80C_PID) }, 6068f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80D_PID) }, 6078f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80E_PID) }, 6088f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80F_PID) }, 6098f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E888_PID) }, 6108f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E889_PID) }, 6118f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88A_PID) }, 6128f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88B_PID) }, 6138f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88C_PID) }, 6148f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88D_PID) }, 6158f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88E_PID) }, 6168f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88F_PID) }, 6171da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, 61847900743SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, 619e6ac4a40SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_ELV_UR100_PID) }, 620e6ac4a40SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) }, 621207c47e1SThomas Riewe { USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) }, 622bde62185SMartin Hagelin { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, 6234eaf60e0SThomas Schleusener { USB_DEVICE(FTDI_VID, FTDI_IBS_US485_PID) }, 6244eaf60e0SThomas Schleusener { USB_DEVICE(FTDI_VID, FTDI_IBS_PICPRO_PID) }, 6254eaf60e0SThomas Schleusener { USB_DEVICE(FTDI_VID, FTDI_IBS_PCMCIA_PID) }, 6264eaf60e0SThomas Schleusener { USB_DEVICE(FTDI_VID, FTDI_IBS_PK1_PID) }, 6274eaf60e0SThomas Schleusener { USB_DEVICE(FTDI_VID, FTDI_IBS_RS232MON_PID) }, 6284eaf60e0SThomas Schleusener { USB_DEVICE(FTDI_VID, FTDI_IBS_APP70_PID) }, 6294eaf60e0SThomas Schleusener { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, 6304eaf60e0SThomas Schleusener { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, 63137909fe5SBenedek László { USB_DEVICE(FTDI_VID, FTDI_TAVIR_STK500_PID) }, 63254575b05SAntonio Ospite { USB_DEVICE(FTDI_VID, FTDI_TIAO_UMPA_PID), 63354575b05SAntonio Ospite .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 634d0839d75SGeorge McCollister { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLXM_PID), 635d0839d75SGeorge McCollister .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 636422c2537SGeorge McCollister { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLX_PLUS_PID) }, 637422c2537SGeorge McCollister { USB_DEVICE(FTDI_VID, FTDI_NT_ORION_IO_PID) }, 638bc96c72dSGeorge McCollister { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONMX_PID) }, 6394899c054SDoug Goldstein { USB_DEVICE(FTDI_VID, FTDI_SYNAPSE_SS200_PID) }, 6401fb8dc36SMatthijs Kooijman { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX_PID) }, 6411fb8dc36SMatthijs Kooijman { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX2_PID) }, 6421fb8dc36SMatthijs Kooijman { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX2WI_PID) }, 6431fb8dc36SMatthijs Kooijman { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX3_PID) }, 644e6ac4a40SIan Abbott /* 64565e1ec67SAndreas Mohr * ELV devices: 646e6ac4a40SIan Abbott */ 647c249f911SSven Killig { USB_DEVICE(FTDI_ELV_VID, FTDI_ELV_WS300_PID) }, 64865e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) }, 64965e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) }, 65065e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) }, 65165e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_WS550_PID) }, 65265e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_EC3000_PID) }, 65365e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_WS888_PID) }, 65465e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_TWS550_PID) }, 65565e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_FEM_PID) }, 65642f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, 65742f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, 65842f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, 65942f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) }, 66042f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) }, 66142f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) }, 66242f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) }, 66342f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) }, 66442f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, 66542f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, 66642f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, 66742f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, 66842f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, 66942f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, 67042f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, 67142f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, 67265e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_UTP8_PID) }, 67342f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, 67465e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_WS444PC_PID) }, 67542f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, 6764ae897dfSSven Andersen { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) }, 67742f8aa94SPeter Stark { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, 678b5894a50SAndré Schenk { USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) }, 67965e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_UMS100_PID) }, 68065e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_TFD128_PID) }, 68165e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_FM3RX_PID) }, 68265e1ec67SAndreas Mohr { USB_DEVICE(FTDI_VID, FTDI_ELV_WS777_PID) }, 6836977495cSRobert Deliën { USB_DEVICE(FTDI_VID, FTDI_PALMSENS_PID) }, 6846977495cSRobert Deliën { USB_DEVICE(FTDI_VID, FTDI_IVIUM_XSTAT_PID) }, 6858f977e42SIan Abbott { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, 6868f977e42SIan Abbott { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, 6878f977e42SIan Abbott { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, 6888f977e42SIan Abbott { USB_DEVICE(FTDI_VID, LINX_FUTURE_1_PID) }, 6898f977e42SIan Abbott { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) }, 6901da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, 6911da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, 692ec434e9bSJan Capek { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) }, 6939d37ff64SJan Capek { USB_DEVICE(FTDI_VID, FTDI_CCSLOAD_N_GO_3_PID) }, 6949d37ff64SJan Capek { USB_DEVICE(FTDI_VID, FTDI_CCSICDU64_4_PID) }, 6959d37ff64SJan Capek { USB_DEVICE(FTDI_VID, FTDI_CCSPRIME8_5_PID) }, 6961da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, 6971da177e4SLinus Torvalds { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, 6981da177e4SLinus Torvalds { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, 6991da177e4SLinus Torvalds { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) }, 700e6ac4a40SIan Abbott { USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) }, 7011da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) }, 702c3d36c45SVladimir Vukicevic { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, 703ef31fec0SMichael Olberg { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, 7046f92872cSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, 70528fe2eb0SMichael Williamson { USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) }, 70646b72d78SDaniel Sangorrin { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, 707482b0b5dSKonstantin Holoborodko { USB_DEVICE(MITSUBISHI_VID, MITSUBISHI_FXUSB_PID) }, 7081da177e4SLinus Torvalds { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, 7091da177e4SLinus Torvalds { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, 7101da177e4SLinus Torvalds { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, 711a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_USOPTL4_PID) }, 712a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_USPTL4_PID) }, 713a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_2_PID) }, 714a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_PID) }, 715a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR2_PID) }, 716a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR_PID) }, 717a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_485USB9F_2W_PID) }, 718a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_485USB9F_4W_PID) }, 719a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_232USB9M_PID) }, 720a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_485USBTB_2W_PID) }, 721a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_485USBTB_4W_PID) }, 722a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_TTL5USB9M_PID) }, 723a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_TTL3USB9M_PID) }, 724a8cbd90aSCliff Brake { USB_DEVICE(BANDB_VID, BANDB_ZZ_PROG1_USB_PID) }, 7251da177e4SLinus Torvalds { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) }, 7266f92872cSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, 7276f92872cSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, 728a26d31ceSSteffen Sledz { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_3_PID) }, 729e6ac4a40SIan Abbott { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) }, 730e6ac4a40SIan Abbott { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_1_PID) }, 731e6ac4a40SIan Abbott { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_2_PID) }, 732e6ac4a40SIan Abbott { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_3_PID) }, 733e6ac4a40SIan Abbott { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_4_PID) }, 734e6ac4a40SIan Abbott { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) }, 735e6ac4a40SIan Abbott { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) }, 736e6ac4a40SIan Abbott { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, 737edd74ffaSFrans Klaver { USB_DEVICE(XSENS_VID, XSENS_AWINDA_DONGLE_PID) }, 738edd74ffaSFrans Klaver { USB_DEVICE(XSENS_VID, XSENS_AWINDA_STATION_PID) }, 7394bdcde35SPatrick Riphagen { USB_DEVICE(XSENS_VID, XSENS_CONVERTER_PID) }, 7401df5b888SPatrick Riphagen { USB_DEVICE(XSENS_VID, XSENS_MTDEVBOARD_PID) }, 7416ccc48e0SPatrick Riphagen { USB_DEVICE(XSENS_VID, XSENS_MTIUSBCONVERTER_PID) }, 7424bdcde35SPatrick Riphagen { USB_DEVICE(XSENS_VID, XSENS_MTW_PID) }, 7430ba3b2ccSPetr Kubánek { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, 7446f92872cSIan Abbott { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, 7458f977e42SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, 74634d1a8aaSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) }, 74734d1a8aaSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MHAM_YS_PID) }, 7489b1513d9SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, 7499b1513d9SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, 75034d1a8aaSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MHAM_IC_PID) }, 75134d1a8aaSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MHAM_DB9_PID) }, 75234d1a8aaSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MHAM_RS232_PID) }, 75334d1a8aaSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y9_PID) }, 754740a4282SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) }, 755740a4282SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) }, 7569b1513d9SIan Abbott { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, 757c1f8ea7dSSøren Hauberg { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, 758c1f8ea7dSSøren Hauberg { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, 759c9c7746dSRui Santos { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, 760c9c7746dSRui Santos { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, 76109c280a2SRui Santos { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, 762c9c7746dSRui Santos { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) }, 76309c280a2SRui Santos { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HRC_PID) }, 76434910434SFranco Lanza { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16IC_PID) }, 765b4723ae3SIan Abbott { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) }, 766b4723ae3SIan Abbott { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, 767effac8beSPavel Fedin { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, 768641adaaeSLouis Nyffenegger { USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) }, 7697e1c0b86SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_ECLO_COM_1WIRE_PID) }, 770a94b52acSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) }, 771a94b52acSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) }, 772ce40d290SWouter Paesen { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, 773cdd3b156SNathan Bronson { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, 7747e0258fdSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, 77526a538b9SHorst Schirmeier { USB_DEVICE(FTDI_VID, FTDI_NZR_SEM_USB_PID) }, 776a9d61bc4SPieter Maes { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) }, 777a9d61bc4SPieter Maes { USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) }, 778a9d61bc4SPieter Maes { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) }, 779a9d61bc4SPieter Maes { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C2_PID) }, 780a9d61bc4SPieter Maes { USB_DEVICE(ICOM_VID, ICOM_ID_RP2D_PID) }, 781a9d61bc4SPieter Maes { USB_DEVICE(ICOM_VID, ICOM_ID_RP2VT_PID) }, 782a9d61bc4SPieter Maes { USB_DEVICE(ICOM_VID, ICOM_ID_RP2VR_PID) }, 783a9d61bc4SPieter Maes { USB_DEVICE(ICOM_VID, ICOM_ID_RP4KVT_PID) }, 784a9d61bc4SPieter Maes { USB_DEVICE(ICOM_VID, ICOM_ID_RP4KVR_PID) }, 785a9d61bc4SPieter Maes { USB_DEVICE(ICOM_VID, ICOM_ID_RP2KVT_PID) }, 786a9d61bc4SPieter Maes { USB_DEVICE(ICOM_VID, ICOM_ID_RP2KVR_PID) }, 78720a0f47eSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) }, 788eb79b4fdSIan Abbott { USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) }, 78948437486SD. Peter Siddons { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) }, 7905a7fbe7eSBert Vermeulen { USB_DEVICE(TESTO_VID, TESTO_1_PID) }, 7915a7fbe7eSBert Vermeulen { USB_DEVICE(TESTO_VID, TESTO_3_PID) }, 792eaede2cbSRalf Schlatterbeck { USB_DEVICE(FTDI_VID, FTDI_GAMMA_SCOUT_PID) }, 7939978f9e1SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13M_PID) }, 7949978f9e1SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, 7959978f9e1SIan Abbott { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, 79640c36092SKjell Myksvoll { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, 797b760dac2SMartin Geleynse { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID), 798b760dac2SMartin Geleynse .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, 799b760dac2SMartin Geleynse { USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID), 800b760dac2SMartin Geleynse .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, 801b760dac2SMartin Geleynse { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID), 802b760dac2SMartin Geleynse .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, 803b760dac2SMartin Geleynse { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID), 804b760dac2SMartin Geleynse .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, 805b760dac2SMartin Geleynse { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), 806b760dac2SMartin Geleynse .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, 807822c7ef4SMicke Prag { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, 808ee444609SJohan Hovold { USB_DEVICE(NOVITUS_VID, NOVITUS_BONO_E_PID) }, 8099608e5c0SMajor Hayden { USB_DEVICE(FTDI_VID, RTSYSTEMS_USB_VX8_PID) }, 810fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S03_PID) }, 811fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_59_PID) }, 812fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57A_PID) }, 813fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57B_PID) }, 814fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29A_PID) }, 815fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29B_PID) }, 816fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29F_PID) }, 817fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_62B_PID) }, 818fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S01_PID) }, 819fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_63_PID) }, 820fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29C_PID) }, 821fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_81B_PID) }, 822fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_82B_PID) }, 823fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K5D_PID) }, 824fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K4Y_PID) }, 825fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K5G_PID) }, 826fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S05_PID) }, 827fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_60_PID) }, 828fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_61_PID) }, 829fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_62_PID) }, 830fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_63B_PID) }, 831fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_64_PID) }, 832fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_65_PID) }, 833fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_92_PID) }, 834fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_92D_PID) }, 835fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_W5R_PID) }, 836fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_A5R_PID) }, 837fed1f1edSRick Farina (Zero_Chaos) { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_PW1_PID) }, 838762e92faSNeil \"Superna\" ARMSTRONG { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, 839a5f62399SLex Ross { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, 840d7fde2d6SPierre Castella { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, 8414bb0ef19SEd Beroset { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, 84211171d1bSMirko Bordignon { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, 843307369b0SMarcin Kościelnicki { USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) }, 844c7d373c3SMax Mansfield { USB_DEVICE(FTDI_VID, CYBER_CORTEX_AV_PID), 845c7d373c3SMax Mansfield .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 8465f63424aSAndrey Korolyov { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID, 1) }, 8475f63424aSAndrey Korolyov { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID, 1) }, 8485f63424aSAndrey Korolyov { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_TINY_PID, 1) }, 8495f63424aSAndrey Korolyov { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_TINY_H_PID, 1) }, 85020734345SHarald Welte { USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID), 85120734345SHarald Welte .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 85220734345SHarald Welte { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID), 85320734345SHarald Welte .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 854a00c3cadSFrederik Kriewitz { USB_DEVICE(FTDI_VID, LMI_LM3S_DEVEL_BOARD_PID), 855a00c3cadSFrederik Kriewitz .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 856a00c3cadSFrederik Kriewitz { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), 857a00c3cadSFrederik Kriewitz .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 8583687f641SPeter Stuge { USB_DEVICE(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID), 8593687f641SPeter Stuge .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 86014511412SKrzysztof Halasa { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID), 86114511412SKrzysztof Halasa .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 86226ab7053SAtsushi Nemoto { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, 863e03cdf22SGreg Kroah-Hartman { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_SCU18) }, 8642542335cSJon K Hellan { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, 86559c6ccd9SDaniel Suchy 86659c6ccd9SDaniel Suchy /* Papouch devices based on FTDI chip */ 86759c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485_PID) }, 86859c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AP485_PID) }, 86959c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB422_PID) }, 87059c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485_2_PID) }, 87159c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AP485_2_PID) }, 87259c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB422_2_PID) }, 87359c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485S_PID) }, 87459c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485C_PID) }, 87559c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_LEC_PID) }, 87659c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB232_PID) }, 87759c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, 87859c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_IRAMP_PID) }, 87959c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_DRAK5_PID) }, 88059c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO8x8_PID) }, 881a18f80b4SJaroslav Kysela { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, 88259c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO2x2_PID) }, 88359c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO10x1_PID) }, 88459c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO30x3_PID) }, 88559c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO60x3_PID) }, 88659c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO2x16_PID) }, 88759c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO3x32_PID) }, 88859c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_DRAK6_PID) }, 88959c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_UPSUSB_PID) }, 89059c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_MU_PID) }, 89159c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SIMUKEY_PID) }, 892a7787e50SRadek Liboska { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AD4USB_PID) }, 89359c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_GMUX_PID) }, 89459c6ccd9SDaniel Suchy { USB_DEVICE(PAPOUCH_VID, PAPOUCH_GMSR_PID) }, 89559c6ccd9SDaniel Suchy 89696285cb8SGaetan Carlier { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, 89796285cb8SGaetan Carlier { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, 89845eeff84SRobie Basak { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, 899ca80801bSMhayk Whandson { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, 9007f82b6ddSAxel Wachtler { USB_DEVICE(ATMEL_VID, STK541_PID) }, 9017f82b6ddSAxel Wachtler { USB_DEVICE(DE_VID, STB_PID) }, 9027f82b6ddSAxel Wachtler { USB_DEVICE(DE_VID, WHT_PID) }, 903b0d65900SMichael Hennerich { USB_DEVICE(ADI_VID, ADI_GNICE_PID), 904b0d65900SMichael Hennerich .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 90511eaf170SMichael Hennerich { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), 90611eaf170SMichael Hennerich .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 907f08dea73SBjørn Mork { USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID, 908f08dea73SBjørn Mork USB_CLASS_VENDOR_SPEC, 909f08dea73SBjørn Mork USB_SUBCLASS_VENDOR_SPEC, 0x00) }, 91031c5d192SMarek Vasut { USB_DEVICE_INTERFACE_NUMBER(ACTEL_VID, MICROSEMI_ARROW_SF2PLUS_BOARD_PID, 2) }, 911ae27d843SPeter Korsgaard { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, 9121002bb77SNicolas Pitre { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), 9131002bb77SNicolas Pitre .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 914d46130abSDaniel Suchy { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, 915fca4404cSVille Sundberg { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, 916dafc4f7bSÉric Piel { USB_DEVICE(FTDI_VID, PI_C865_PID) }, 917dafc4f7bSÉric Piel { USB_DEVICE(FTDI_VID, PI_C857_PID) }, 918dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_C866_PID) }, 919dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_C663_PID) }, 920dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_C725_PID) }, 921dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_E517_PID) }, 922dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_C863_PID) }, 923b69cc672SÉric Piel { USB_DEVICE(PI_VID, PI_E861_PID) }, 924dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_C867_PID) }, 925dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_E609_PID) }, 926dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_E709_PID) }, 927dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_100F_PID) }, 928dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_1011_PID) }, 929dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_1012_PID) }, 930dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_1013_PID) }, 931dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_1014_PID) }, 932dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_1015_PID) }, 933dafc4f7bSÉric Piel { USB_DEVICE(PI_VID, PI_1016_PID) }, 9347724a1edSOzan Çağlayan { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) }, 935c47aacc6SMarko Hänninen { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, 93650d0678eSDhaval Vasa { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), 93750d0678eSDhaval Vasa .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 93855f13aeaSPeter Korsgaard { USB_DEVICE(FTDI_VID, TI_XDS100V2_PID), 93955f13aeaSPeter Korsgaard .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 940e7d7fcc0SPawel Ludwikow { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, 941c53c2fabSPaul Friedrich { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) }, 942c53c2fabSPaul Friedrich { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) }, 943e7d7fcc0SPawel Ludwikow { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, 9449714080dSMitchell Solomon { USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) }, 9459714080dSMitchell Solomon { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) }, 9469714080dSMitchell Solomon { USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) }, 9479714080dSMitchell Solomon { USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) }, 94877dbd74eSColin Leitner { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_ST_PID), 94977dbd74eSColin Leitner .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 95077dbd74eSColin Leitner { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SLITE_PID), 95177dbd74eSColin Leitner .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 95277dbd74eSColin Leitner { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH2_PID), 95377dbd74eSColin Leitner .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 95477dbd74eSColin Leitner { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID), 95577dbd74eSColin Leitner .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 956afad1964SJohn G. Rogers { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) }, 9573126d823SRich Mattes { USB_DEVICE(FTDI_VID, ACCESIO_COM4SM_PID) }, 958666cc076SMartin Michlmayr { USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID), 959666cc076SMartin Michlmayr .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 96065737388SLuke Lowrey { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_24_MASTER_WING_PID) }, 96165737388SLuke Lowrey { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_PC_WING_PID) }, 96265737388SLuke Lowrey { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_USB_DMX_PID) }, 96365737388SLuke Lowrey { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MIDI_TIMECODE_PID) }, 96465737388SLuke Lowrey { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MINI_WING_PID) }, 96565737388SLuke Lowrey { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MAXI_WING_PID) }, 96665737388SLuke Lowrey { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MEDIA_WING_PID) }, 96765737388SLuke Lowrey { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_WING_PID) }, 9680f266abdSGreg Kroah-Hartman { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) }, 9690f266abdSGreg Kroah-Hartman { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) }, 9700f266abdSGreg Kroah-Hartman { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, 97190451e69SMilan Kocian { USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) }, 9726555ad13SClemens Werther { USB_DEVICE(FTDI_VID, FTDI_FHE_PID) }, 9735363cdc3SFlorian Faber { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, 9747fea0f71SSebastien Bourdeauducq { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), 9757fea0f71SSebastien Bourdeauducq .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 9769f06d15fSAdrian Thomasset { USB_DEVICE(ST_VID, ST_STMCLT_2232_PID), 9779f06d15fSAdrian Thomasset .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 9789f06d15fSAdrian Thomasset { USB_DEVICE(ST_VID, ST_STMCLT_4232_PID), 9796ec2f46cSJean-Christophe PLAGNIOL-VILLARD .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk }, 980fc216ec3SPeter Naulls { USB_DEVICE(FTDI_VID, FTDI_RF_R106) }, 98147594d55SMichał Wróbel { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID), 98247594d55SMichał Wróbel .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 98357e596f3SMichał Wróbel { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) }, 9848cf65dc3STomasz Mloduchowski /* Crucible Devices */ 9858cf65dc3STomasz Mloduchowski { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) }, 986e1466ad5SАлексей Крамаренко { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) }, 9876dbd46c8SJoerg Dorchain /* Cressi Devices */ 9886dbd46c8SJoerg Dorchain { USB_DEVICE(FTDI_VID, FTDI_CRESSI_PID) }, 989efe26e16SMichele Baldessari /* Brainboxes Devices */ 990efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_001_PID) }, 991efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_012_PID) }, 992efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_023_PID) }, 993efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_034_PID) }, 994efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_101_PID) }, 995fbb9b194SCameron Williams { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_159_PID) }, 996efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_1_PID) }, 997efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_2_PID) }, 998efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_3_PID) }, 999efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_4_PID) }, 1000efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_5_PID) }, 1001efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_6_PID) }, 1002efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_7_PID) }, 1003efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_8_PID) }, 1004fbb9b194SCameron Williams { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_235_PID) }, 1005efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_257_PID) }, 1006efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_1_PID) }, 1007efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_2_PID) }, 1008efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_3_PID) }, 1009efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_4_PID) }, 1010efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_313_PID) }, 1011fbb9b194SCameron Williams { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_320_PID) }, 1012efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_324_PID) }, 1013efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_1_PID) }, 1014efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_2_PID) }, 1015efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_357_PID) }, 1016efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_1_PID) }, 1017efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_2_PID) }, 1018efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_3_PID) }, 1019efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_1_PID) }, 1020efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_2_PID) }, 1021efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_1_PID) }, 1022efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) }, 1023efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) }, 1024efe26e16SMichele Baldessari { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) }, 1025646907f5SJaša Bartelj /* ekey Devices */ 1026646907f5SJaša Bartelj { USB_DEVICE(FTDI_VID, FTDI_EKEY_CONV_USB_PID) }, 1027d8279a40SMichal Sojka /* Infineon Devices */ 1028ca006f78SStefan Tauner { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_TC1798_PID, 1) }, 1029ca006f78SStefan Tauner { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_TC2X7_PID, 1) }, 10309c491c37STaylor Braun-Jones /* GE Healthcare devices */ 10319c491c37STaylor Braun-Jones { USB_DEVICE(GE_HEALTHCARE_VID, GE_HEALTHCARE_NEMO_TRACKER_PID) }, 1032f6950344SMark Glover /* Active Research (Actisense) devices */ 1033f6950344SMark Glover { USB_DEVICE(FTDI_VID, ACTISENSE_NDC_PID) }, 1034f6950344SMark Glover { USB_DEVICE(FTDI_VID, ACTISENSE_USG_PID) }, 1035f6950344SMark Glover { USB_DEVICE(FTDI_VID, ACTISENSE_NGT_PID) }, 1036f6950344SMark Glover { USB_DEVICE(FTDI_VID, ACTISENSE_NGW_PID) }, 1037f6950344SMark Glover { USB_DEVICE(FTDI_VID, ACTISENSE_D9AC_PID) }, 1038f6950344SMark Glover { USB_DEVICE(FTDI_VID, ACTISENSE_D9AD_PID) }, 1039f6950344SMark Glover { USB_DEVICE(FTDI_VID, ACTISENSE_D9AE_PID) }, 1040f6950344SMark Glover { USB_DEVICE(FTDI_VID, ACTISENSE_D9AF_PID) }, 1041f6950344SMark Glover { USB_DEVICE(FTDI_VID, CHETCO_SEAGAUGE_PID) }, 1042f6950344SMark Glover { USB_DEVICE(FTDI_VID, CHETCO_SEASWITCH_PID) }, 1043f6950344SMark Glover { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_NMEA2000_PID) }, 1044f6950344SMark Glover { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ETHERNET_PID) }, 1045f6950344SMark Glover { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_WIFI_PID) }, 1046f6950344SMark Glover { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_DISPLAY_PID) }, 1047f6950344SMark Glover { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_LITE_PID) }, 1048f6950344SMark Glover { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ANALOG_PID) }, 10497c239a07SLucien Buchmann /* Belimo Automation devices */ 10507c239a07SLucien Buchmann { USB_DEVICE(FTDI_VID, BELIMO_ZTH_PID) }, 10517c239a07SLucien Buchmann { USB_DEVICE(FTDI_VID, BELIMO_ZIP_PID) }, 1052ea6db90eSJosh Boyer /* ICP DAS I-756xU devices */ 1053ea6db90eSJosh Boyer { USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) }, 1054ea6db90eSJosh Boyer { USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) }, 1055ea6db90eSJosh Boyer { USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) }, 1056ae34d12cSSheng-Hui J. Chu { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) }, 10579bfef729SDoug Brown { USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID), 10589bfef729SDoug Brown .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 1059a6c215e2SJeffrey Chu { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) }, 1060a6c215e2SJeffrey Chu { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) }, 1061c6a36ad3SMax Schulze { USB_DEVICE(AIRBUS_DS_VID, AIRBUS_DS_P8GR) }, 10628d7fa3d4SMans Rullgard /* EZPrototypes devices */ 10638d7fa3d4SMans Rullgard { USB_DEVICE(EZPROTOTYPES_VID, HJELMSLUND_USB485_ISO_PID) }, 1064f8377effSAndreas Fritiofson { USB_DEVICE_INTERFACE_NUMBER(UNJO_VID, UNJO_ISODEBUG_V1_PID, 1) }, 1065357f16d9SBeni Mahler /* Sienna devices */ 1066357f16d9SBeni Mahler { USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) }, 1067357f16d9SBeni Mahler { USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) }, 1068c5a80540SDominik Andreas Schorpp /* IDS GmbH devices */ 1069c5a80540SDominik Andreas Schorpp { USB_DEVICE(IDS_VID, IDS_SI31A_PID) }, 1070c5a80540SDominik Andreas Schorpp { USB_DEVICE(IDS_VID, IDS_CM31A_PID) }, 1071001047eaSNiek Nooijens /* Omron devices */ 1072001047eaSNiek Nooijens { USB_DEVICE(OMRON_VID, OMRON_CS1W_CIF31_PID) }, 1073c1a1f273SFabio D'Urso /* U-Blox devices */ 1074c1a1f273SFabio D'Urso { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) }, 1075c1a1f273SFabio D'Urso { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) }, 10766cf87e5eSMychaela N. Falconia /* FreeCalypso USB adapters */ 10776cf87e5eSMychaela N. Falconia { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_BUF_PID), 10786cf87e5eSMychaela N. Falconia .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 10796cf87e5eSMychaela N. Falconia { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID), 10806cf87e5eSMychaela N. Falconia .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 10811da177e4SLinus Torvalds { } /* Terminating entry */ 10821da177e4SLinus Torvalds }; 10831da177e4SLinus Torvalds 10841da177e4SLinus Torvalds MODULE_DEVICE_TABLE(usb, id_table_combined); 10851da177e4SLinus Torvalds 10864c4c9432SArjan van de Ven static const char *ftdi_chip_name[] = { 10871da177e4SLinus Torvalds [SIO] = "SIO", /* the serial part of FT8U100AX */ 108801aeb31fSJohan Hovold [FT232A] = "FT232A", 108901aeb31fSJohan Hovold [FT232B] = "FT232B", 109064b12fdaSJohan Hovold [FT2232C] = "FT2232C/D", 109101aeb31fSJohan Hovold [FT232R] = "FT232R", 109201aeb31fSJohan Hovold [FT232H] = "FT232H", 1093094c2e6dSMark Adamson [FT2232H] = "FT2232H", 1094309427b6SUwe Bonnes [FT4232H] = "FT4232H", 1095cfebcd53SAmireddy mallikarjuna reddy [FT4232HA] = "FT4232HA", 1096cfebcd53SAmireddy mallikarjuna reddy [FT232HP] = "FT232HP", 1097cfebcd53SAmireddy mallikarjuna reddy [FT233HP] = "FT233HP", 1098cfebcd53SAmireddy mallikarjuna reddy [FT2232HP] = "FT2232HP", 1099cfebcd53SAmireddy mallikarjuna reddy [FT2233HP] = "FT2233HP", 1100cfebcd53SAmireddy mallikarjuna reddy [FT4232HP] = "FT4232HP", 1101cfebcd53SAmireddy mallikarjuna reddy [FT4233HP] = "FT4233HP", 110201aeb31fSJohan Hovold [FTX] = "FT-X", 11031da177e4SLinus Torvalds }; 11041da177e4SLinus Torvalds 11051da177e4SLinus Torvalds 11061da177e4SLinus Torvalds /* Used for TIOCMIWAIT */ 11071da177e4SLinus Torvalds #define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) 11081da177e4SLinus Torvalds #define FTDI_STATUS_B1_MASK (FTDI_RS_BI) 11091da177e4SLinus Torvalds /* End TIOCMIWAIT */ 11101da177e4SLinus Torvalds 1111464cbb24SAlan Cox static void ftdi_set_termios(struct tty_struct *tty, 1112464cbb24SAlan Cox struct usb_serial_port *port, struct ktermios *old); 1113c4133648SJohan Hovold static int ftdi_get_modem_status(struct usb_serial_port *port, 11145fb0432eSJohan Hovold unsigned char status[2]); 11151da177e4SLinus Torvalds 11161da177e4SLinus Torvalds #define WDR_TIMEOUT 5000 /* default urb timeout */ 1117279e1545SIan Abbott #define WDR_SHORT_TIMEOUT 1000 /* shorter urb timeout */ 11181da177e4SLinus Torvalds 11191da177e4SLinus Torvalds /* 11201da177e4SLinus Torvalds * *************************************************************************** 1121fa91d43bSTony Lindgren * Utility functions 11221da177e4SLinus Torvalds * *************************************************************************** 11231da177e4SLinus Torvalds */ 11241da177e4SLinus Torvalds 11251da177e4SLinus Torvalds static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base) 11261da177e4SLinus Torvalds { 11271da177e4SLinus Torvalds unsigned short int divisor; 1128464cbb24SAlan Cox /* divisor shifted 3 bits to the left */ 11296abd8371SNikolaj Fogh int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud); 1130464cbb24SAlan Cox if ((divisor3 & 0x7) == 7) 1131464cbb24SAlan Cox divisor3++; /* round x.7/8 up to x+1 */ 11321da177e4SLinus Torvalds divisor = divisor3 >> 3; 11331da177e4SLinus Torvalds divisor3 &= 0x7; 1134464cbb24SAlan Cox if (divisor3 == 1) 11351ef26803SJohan Hovold divisor |= 0xc000; /* +0.125 */ 1136464cbb24SAlan Cox else if (divisor3 >= 4) 11371ef26803SJohan Hovold divisor |= 0x4000; /* +0.5 */ 1138464cbb24SAlan Cox else if (divisor3 != 0) 11391ef26803SJohan Hovold divisor |= 0x8000; /* +0.25 */ 1140464cbb24SAlan Cox else if (divisor == 1) 1141464cbb24SAlan Cox divisor = 0; /* special case for maximum baud rate */ 11421da177e4SLinus Torvalds return divisor; 11431da177e4SLinus Torvalds } 11441da177e4SLinus Torvalds 11451da177e4SLinus Torvalds static unsigned short int ftdi_232am_baud_to_divisor(int baud) 11461da177e4SLinus Torvalds { 1147464cbb24SAlan Cox return ftdi_232am_baud_base_to_divisor(baud, 48000000); 11481da177e4SLinus Torvalds } 11491da177e4SLinus Torvalds 1150fd54a99aSJohan Hovold static u32 ftdi_232bm_baud_base_to_divisor(int baud, int base) 11511da177e4SLinus Torvalds { 11521da177e4SLinus Torvalds static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; 1153fd54a99aSJohan Hovold u32 divisor; 1154464cbb24SAlan Cox /* divisor shifted 3 bits to the left */ 11556abd8371SNikolaj Fogh int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud); 11561da177e4SLinus Torvalds divisor = divisor3 >> 3; 1157fd54a99aSJohan Hovold divisor |= (u32)divfrac[divisor3 & 0x7] << 14; 11581da177e4SLinus Torvalds /* Deal with special cases for highest baud rates. */ 11591ef26803SJohan Hovold if (divisor == 1) /* 1.0 */ 1160464cbb24SAlan Cox divisor = 0; 11611ef26803SJohan Hovold else if (divisor == 0x4001) /* 1.5 */ 1162464cbb24SAlan Cox divisor = 1; 11631da177e4SLinus Torvalds return divisor; 11641da177e4SLinus Torvalds } 11651da177e4SLinus Torvalds 1166fd54a99aSJohan Hovold static u32 ftdi_232bm_baud_to_divisor(int baud) 11671da177e4SLinus Torvalds { 1168464cbb24SAlan Cox return ftdi_232bm_baud_base_to_divisor(baud, 48000000); 11691da177e4SLinus Torvalds } 11701da177e4SLinus Torvalds 1171fd54a99aSJohan Hovold static u32 ftdi_2232h_baud_base_to_divisor(int baud, int base) 1172094c2e6dSMark Adamson { 1173094c2e6dSMark Adamson static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; 1174fd54a99aSJohan Hovold u32 divisor; 1175094c2e6dSMark Adamson int divisor3; 1176094c2e6dSMark Adamson 1177094c2e6dSMark Adamson /* hi-speed baud rate is 10-bit sampling instead of 16-bit */ 11786abd8371SNikolaj Fogh divisor3 = DIV_ROUND_CLOSEST(8 * base, 10 * baud); 1179094c2e6dSMark Adamson 1180094c2e6dSMark Adamson divisor = divisor3 >> 3; 1181fd54a99aSJohan Hovold divisor |= (u32)divfrac[divisor3 & 0x7] << 14; 1182094c2e6dSMark Adamson /* Deal with special cases for highest baud rates. */ 11831ef26803SJohan Hovold if (divisor == 1) /* 1.0 */ 1184094c2e6dSMark Adamson divisor = 0; 11851ef26803SJohan Hovold else if (divisor == 0x4001) /* 1.5 */ 1186094c2e6dSMark Adamson divisor = 1; 1187094c2e6dSMark Adamson /* 1188094c2e6dSMark Adamson * Set this bit to turn off a divide by 2.5 on baud rate generator 1189094c2e6dSMark Adamson * This enables baud rates up to 12Mbaud but cannot reach below 1200 1190094c2e6dSMark Adamson * baud with this bit set 1191094c2e6dSMark Adamson */ 1192094c2e6dSMark Adamson divisor |= 0x00020000; 1193094c2e6dSMark Adamson return divisor; 1194094c2e6dSMark Adamson } 1195094c2e6dSMark Adamson 1196fd54a99aSJohan Hovold static u32 ftdi_2232h_baud_to_divisor(int baud) 1197094c2e6dSMark Adamson { 1198094c2e6dSMark Adamson return ftdi_2232h_baud_base_to_divisor(baud, 120000000); 1199094c2e6dSMark Adamson } 1200094c2e6dSMark Adamson 120174ede0ffSIan Abbott #define set_mctrl(port, set) update_mctrl((port), (set), 0) 120274ede0ffSIan Abbott #define clear_mctrl(port, clear) update_mctrl((port), 0, (clear)) 120374ede0ffSIan Abbott 1204464cbb24SAlan Cox static int update_mctrl(struct usb_serial_port *port, unsigned int set, 1205464cbb24SAlan Cox unsigned int clear) 12061da177e4SLinus Torvalds { 12071da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 1208bfc51614SGreg Kroah-Hartman struct device *dev = &port->dev; 120916410115SJohan Hovold unsigned value; 12101da177e4SLinus Torvalds int rv; 12111da177e4SLinus Torvalds 121274ede0ffSIan Abbott if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) { 1213bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - DTR|RTS not being set|cleared\n", __func__); 121474ede0ffSIan Abbott return 0; /* no change */ 12151da177e4SLinus Torvalds } 121674ede0ffSIan Abbott 121774ede0ffSIan Abbott clear &= ~set; /* 'set' takes precedence over 'clear' */ 121816410115SJohan Hovold value = 0; 121974ede0ffSIan Abbott if (clear & TIOCM_DTR) 122016410115SJohan Hovold value |= FTDI_SIO_SET_DTR_LOW; 122174ede0ffSIan Abbott if (clear & TIOCM_RTS) 122216410115SJohan Hovold value |= FTDI_SIO_SET_RTS_LOW; 122374ede0ffSIan Abbott if (set & TIOCM_DTR) 122416410115SJohan Hovold value |= FTDI_SIO_SET_DTR_HIGH; 122574ede0ffSIan Abbott if (set & TIOCM_RTS) 122616410115SJohan Hovold value |= FTDI_SIO_SET_RTS_HIGH; 12271da177e4SLinus Torvalds rv = usb_control_msg(port->serial->dev, 12281da177e4SLinus Torvalds usb_sndctrlpipe(port->serial->dev, 0), 12291da177e4SLinus Torvalds FTDI_SIO_SET_MODEM_CTRL_REQUEST, 12301da177e4SLinus Torvalds FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, 1231027bf37dSJohan Hovold value, priv->channel, 123266e47e60SJohan Hovold NULL, 0, WDR_TIMEOUT); 123374ede0ffSIan Abbott if (rv < 0) { 1234bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s Error from MODEM_CTRL urb: DTR %s, RTS %s\n", 1235441b62c1SHarvey Harrison __func__, 1236bfc51614SGreg Kroah-Hartman (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged", 1237bfc51614SGreg Kroah-Hartman (set & TIOCM_RTS) ? "HIGH" : (clear & TIOCM_RTS) ? "LOW" : "unchanged"); 12382c2ee545SJohan Hovold rv = usb_translate_errors(rv); 12391da177e4SLinus Torvalds } else { 1240bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - DTR %s, RTS %s\n", __func__, 1241bfc51614SGreg Kroah-Hartman (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged", 1242bfc51614SGreg Kroah-Hartman (set & TIOCM_RTS) ? "HIGH" : (clear & TIOCM_RTS) ? "LOW" : "unchanged"); 12439b0f2582SAlan Cox /* FIXME: locking on last_dtr_rts */ 124474ede0ffSIan Abbott priv->last_dtr_rts = (priv->last_dtr_rts & ~clear) | set; 12451da177e4SLinus Torvalds } 12461da177e4SLinus Torvalds return rv; 12471da177e4SLinus Torvalds } 12481da177e4SLinus Torvalds 12491da177e4SLinus Torvalds 1250fd54a99aSJohan Hovold static u32 get_ftdi_divisor(struct tty_struct *tty, 1251464cbb24SAlan Cox struct usb_serial_port *port) 1252e49bbce1SJohan Hovold { 12531da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 1254bfc51614SGreg Kroah-Hartman struct device *dev = &port->dev; 1255fd54a99aSJohan Hovold u32 div_value = 0; 12561da177e4SLinus Torvalds int div_okay = 1; 12571da177e4SLinus Torvalds int baud; 12581da177e4SLinus Torvalds 125995da310eSAlan Cox baud = tty_get_baud_rate(tty); 1260bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - tty_get_baud_rate reports speed %d\n", __func__, baud); 12611da177e4SLinus Torvalds 126283c9a2d1SJohan Hovold /* 126383c9a2d1SJohan Hovold * Observe deprecated async-compatible custom_divisor hack, update 126483c9a2d1SJohan Hovold * baudrate if needed. 126583c9a2d1SJohan Hovold */ 12661da177e4SLinus Torvalds if (baud == 38400 && 12671da177e4SLinus Torvalds ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && 12681da177e4SLinus Torvalds (priv->custom_divisor)) { 12691da177e4SLinus Torvalds baud = priv->baud_base / priv->custom_divisor; 1270bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - custom divisor %d sets baud rate to %d\n", 1271464cbb24SAlan Cox __func__, priv->custom_divisor, baud); 12721da177e4SLinus Torvalds } 12731da177e4SLinus Torvalds 1274464cbb24SAlan Cox if (!baud) 1275464cbb24SAlan Cox baud = 9600; 12761da177e4SLinus Torvalds switch (priv->chip_type) { 127725eb9486SJohan Hovold case SIO: 12781da177e4SLinus Torvalds switch (baud) { 12791da177e4SLinus Torvalds case 300: div_value = ftdi_sio_b300; break; 12801da177e4SLinus Torvalds case 600: div_value = ftdi_sio_b600; break; 12811da177e4SLinus Torvalds case 1200: div_value = ftdi_sio_b1200; break; 12821da177e4SLinus Torvalds case 2400: div_value = ftdi_sio_b2400; break; 12831da177e4SLinus Torvalds case 4800: div_value = ftdi_sio_b4800; break; 12841da177e4SLinus Torvalds case 9600: div_value = ftdi_sio_b9600; break; 12851da177e4SLinus Torvalds case 19200: div_value = ftdi_sio_b19200; break; 12861da177e4SLinus Torvalds case 38400: div_value = ftdi_sio_b38400; break; 12871da177e4SLinus Torvalds case 57600: div_value = ftdi_sio_b57600; break; 12881da177e4SLinus Torvalds case 115200: div_value = ftdi_sio_b115200; break; 12897bd7ad3cSJohan Hovold default: 1290bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - Baudrate (%d) requested is not supported\n", 1291464cbb24SAlan Cox __func__, baud); 12921da177e4SLinus Torvalds div_value = ftdi_sio_b9600; 1293669a6db1SAlan Cox baud = 9600; 12941da177e4SLinus Torvalds div_okay = 0; 12951da177e4SLinus Torvalds } 12961da177e4SLinus Torvalds break; 129701aeb31fSJohan Hovold case FT232A: 12981da177e4SLinus Torvalds if (baud <= 3000000) { 12991da177e4SLinus Torvalds div_value = ftdi_232am_baud_to_divisor(baud); 13001da177e4SLinus Torvalds } else { 1301bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - Baud rate too high!\n", __func__); 1302669a6db1SAlan Cox baud = 9600; 13031da177e4SLinus Torvalds div_value = ftdi_232am_baud_to_divisor(9600); 13041da177e4SLinus Torvalds div_okay = 0; 13051da177e4SLinus Torvalds } 13061da177e4SLinus Torvalds break; 130701aeb31fSJohan Hovold case FT232B: 130825eb9486SJohan Hovold case FT2232C: 130901aeb31fSJohan Hovold case FT232R: 131025eb9486SJohan Hovold case FTX: 13111da177e4SLinus Torvalds if (baud <= 3000000) { 1312fd54a99aSJohan Hovold u16 product_id = le16_to_cpu( 1313b760dac2SMartin Geleynse port->serial->dev->descriptor.idProduct); 1314fb571101SMathieu OTHACEHE if (((product_id == FTDI_NDI_HUC_PID) || 1315fb571101SMathieu OTHACEHE (product_id == FTDI_NDI_SPECTRA_SCU_PID) || 1316fb571101SMathieu OTHACEHE (product_id == FTDI_NDI_FUTURE_2_PID) || 1317fb571101SMathieu OTHACEHE (product_id == FTDI_NDI_FUTURE_3_PID) || 1318fb571101SMathieu OTHACEHE (product_id == FTDI_NDI_AURORA_SCU_PID)) && 1319b760dac2SMartin Geleynse (baud == 19200)) { 1320b760dac2SMartin Geleynse baud = 1200000; 1321b760dac2SMartin Geleynse } 13221da177e4SLinus Torvalds div_value = ftdi_232bm_baud_to_divisor(baud); 13231da177e4SLinus Torvalds } else { 1324bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - Baud rate too high!\n", __func__); 13251da177e4SLinus Torvalds div_value = ftdi_232bm_baud_to_divisor(9600); 13261da177e4SLinus Torvalds div_okay = 0; 1327669a6db1SAlan Cox baud = 9600; 13281da177e4SLinus Torvalds } 13291da177e4SLinus Torvalds break; 13301a039891SJohan Hovold default: 13311862cdd5SIonut Nicu if ((baud <= 12000000) && (baud >= 1200)) { 1332094c2e6dSMark Adamson div_value = ftdi_2232h_baud_to_divisor(baud); 1333094c2e6dSMark Adamson } else if (baud < 1200) { 1334094c2e6dSMark Adamson div_value = ftdi_232bm_baud_to_divisor(baud); 1335094c2e6dSMark Adamson } else { 1336bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - Baud rate too high!\n", __func__); 1337094c2e6dSMark Adamson div_value = ftdi_232bm_baud_to_divisor(9600); 1338094c2e6dSMark Adamson div_okay = 0; 1339094c2e6dSMark Adamson baud = 9600; 1340094c2e6dSMark Adamson } 1341094c2e6dSMark Adamson break; 134225eb9486SJohan Hovold } 13431da177e4SLinus Torvalds 13441da177e4SLinus Torvalds if (div_okay) { 1345bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - Baud rate set to %d (divisor 0x%lX) on chip %s\n", 1346441b62c1SHarvey Harrison __func__, baud, (unsigned long)div_value, 13471da177e4SLinus Torvalds ftdi_chip_name[priv->chip_type]); 13481da177e4SLinus Torvalds } 13491da177e4SLinus Torvalds 135095da310eSAlan Cox tty_encode_baud_rate(tty, baud, baud); 1351464cbb24SAlan Cox return div_value; 13521da177e4SLinus Torvalds } 13531da177e4SLinus Torvalds 135495da310eSAlan Cox static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) 135595da310eSAlan Cox { 135695da310eSAlan Cox struct ftdi_private *priv = usb_get_serial_port_data(port); 135716410115SJohan Hovold u16 value; 135816410115SJohan Hovold u16 index; 135916410115SJohan Hovold u32 index_value; 136095da310eSAlan Cox int rv; 136195da310eSAlan Cox 136216410115SJohan Hovold index_value = get_ftdi_divisor(tty, port); 136316410115SJohan Hovold value = (u16)index_value; 136416410115SJohan Hovold index = (u16)(index_value >> 16); 1365a146cc4dSJohan Hovold if (priv->channel) 1366027bf37dSJohan Hovold index = (u16)((index << 8) | priv->channel); 136795da310eSAlan Cox 136895da310eSAlan Cox rv = usb_control_msg(port->serial->dev, 136995da310eSAlan Cox usb_sndctrlpipe(port->serial->dev, 0), 137095da310eSAlan Cox FTDI_SIO_SET_BAUDRATE_REQUEST, 137195da310eSAlan Cox FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, 137216410115SJohan Hovold value, index, 137366e47e60SJohan Hovold NULL, 0, WDR_SHORT_TIMEOUT); 137495da310eSAlan Cox return rv; 137595da310eSAlan Cox } 137695da310eSAlan Cox 1377557aaa7fSAlan Cox static int write_latency_timer(struct usb_serial_port *port) 1378557aaa7fSAlan Cox { 1379557aaa7fSAlan Cox struct ftdi_private *priv = usb_get_serial_port_data(port); 1380557aaa7fSAlan Cox struct usb_device *udev = port->serial->dev; 1381c1284d77SJohan Hovold int rv; 1382557aaa7fSAlan Cox int l = priv->latency; 138395da310eSAlan Cox 138401aeb31fSJohan Hovold if (priv->chip_type == SIO || priv->chip_type == FT232A) 13852dea7cd7SIan Abbott return -EINVAL; 13862dea7cd7SIan Abbott 1387557aaa7fSAlan Cox if (priv->flags & ASYNC_LOW_LATENCY) 1388557aaa7fSAlan Cox l = 1; 1389557aaa7fSAlan Cox 1390bfc51614SGreg Kroah-Hartman dev_dbg(&port->dev, "%s: setting latency timer = %i\n", __func__, l); 1391557aaa7fSAlan Cox 1392557aaa7fSAlan Cox rv = usb_control_msg(udev, 1393557aaa7fSAlan Cox usb_sndctrlpipe(udev, 0), 1394557aaa7fSAlan Cox FTDI_SIO_SET_LATENCY_TIMER_REQUEST, 1395557aaa7fSAlan Cox FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, 1396027bf37dSJohan Hovold l, priv->channel, 139766e47e60SJohan Hovold NULL, 0, WDR_TIMEOUT); 1398557aaa7fSAlan Cox if (rv < 0) 1399557aaa7fSAlan Cox dev_err(&port->dev, "Unable to write latency timer: %i\n", rv); 1400557aaa7fSAlan Cox return rv; 1401557aaa7fSAlan Cox } 1402557aaa7fSAlan Cox 14037e1e6cedSIan Abbott static int _read_latency_timer(struct usb_serial_port *port) 1404557aaa7fSAlan Cox { 1405557aaa7fSAlan Cox struct ftdi_private *priv = usb_get_serial_port_data(port); 1406557aaa7fSAlan Cox struct usb_device *udev = port->serial->dev; 1407a7388592SHimadri Pandya u8 buf; 1408c1284d77SJohan Hovold int rv; 1409557aaa7fSAlan Cox 1410a7388592SHimadri Pandya rv = usb_control_msg_recv(udev, 0, FTDI_SIO_GET_LATENCY_TIMER_REQUEST, 1411a7388592SHimadri Pandya FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, 0, 1412027bf37dSJohan Hovold priv->channel, &buf, 1, WDR_TIMEOUT, 1413a7388592SHimadri Pandya GFP_KERNEL); 1414a7388592SHimadri Pandya if (rv == 0) 1415a7388592SHimadri Pandya rv = buf; 141654f328d0SJohan Hovold 14178c4f99cdSJohan Hovold return rv; 1418557aaa7fSAlan Cox } 14191da177e4SLinus Torvalds 14207e1e6cedSIan Abbott static int read_latency_timer(struct usb_serial_port *port) 14217e1e6cedSIan Abbott { 14227e1e6cedSIan Abbott struct ftdi_private *priv = usb_get_serial_port_data(port); 14237e1e6cedSIan Abbott int rv; 14247e1e6cedSIan Abbott 142501aeb31fSJohan Hovold if (priv->chip_type == SIO || priv->chip_type == FT232A) 14267e1e6cedSIan Abbott return -EINVAL; 14277e1e6cedSIan Abbott 14287e1e6cedSIan Abbott rv = _read_latency_timer(port); 14297e1e6cedSIan Abbott if (rv < 0) { 14307e1e6cedSIan Abbott dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); 14317e1e6cedSIan Abbott return rv; 14327e1e6cedSIan Abbott } 14337e1e6cedSIan Abbott 14347e1e6cedSIan Abbott priv->latency = rv; 14357e1e6cedSIan Abbott 14367e1e6cedSIan Abbott return 0; 14377e1e6cedSIan Abbott } 14387e1e6cedSIan Abbott 143901fd45f6SJohan Hovold static void get_serial_info(struct tty_struct *tty, struct serial_struct *ss) 14401da177e4SLinus Torvalds { 14413ae36bedSAl Viro struct usb_serial_port *port = tty->driver_data; 14421da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 14431da177e4SLinus Torvalds 14443ae36bedSAl Viro ss->flags = priv->flags; 14453ae36bedSAl Viro ss->baud_base = priv->baud_base; 14463ae36bedSAl Viro ss->custom_divisor = priv->custom_divisor; 1447e49bbce1SJohan Hovold } 14481da177e4SLinus Torvalds 14490428bf68SJohan Hovold static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) 1450e49bbce1SJohan Hovold { 14513ae36bedSAl Viro struct usb_serial_port *port = tty->driver_data; 14521da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 14530428bf68SJohan Hovold int old_flags, old_divisor; 14541da177e4SLinus Torvalds 1455bd09a9f5SAlessio Igor Bogani mutex_lock(&priv->cfg_lock); 14561da177e4SLinus Torvalds 14571da177e4SLinus Torvalds if (!capable(CAP_SYS_ADMIN)) { 14583ae36bedSAl Viro if ((ss->flags ^ priv->flags) & ~ASYNC_USR_MASK) { 1459bd09a9f5SAlessio Igor Bogani mutex_unlock(&priv->cfg_lock); 14601da177e4SLinus Torvalds return -EPERM; 146164905b48SDan Carpenter } 14621da177e4SLinus Torvalds } 14631da177e4SLinus Torvalds 14640428bf68SJohan Hovold old_flags = priv->flags; 14650428bf68SJohan Hovold old_divisor = priv->custom_divisor; 14660428bf68SJohan Hovold 1467c12860c0SJohan Hovold priv->flags = ss->flags & ASYNC_FLAGS; 14683ae36bedSAl Viro priv->custom_divisor = ss->custom_divisor; 14691da177e4SLinus Torvalds 1470557aaa7fSAlan Cox write_latency_timer(port); 14711da177e4SLinus Torvalds 14720428bf68SJohan Hovold if ((priv->flags ^ old_flags) & ASYNC_SPD_MASK || 1473f3e8ae65SJohan Hovold ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && 14740428bf68SJohan Hovold priv->custom_divisor != old_divisor)) { 147583c9a2d1SJohan Hovold 147683c9a2d1SJohan Hovold /* warn about deprecation unless clearing */ 147783c9a2d1SJohan Hovold if (priv->flags & ASYNC_SPD_MASK) 147883c9a2d1SJohan Hovold dev_warn_ratelimited(&port->dev, "use of SPD flags is deprecated\n"); 147983c9a2d1SJohan Hovold 148095da310eSAlan Cox change_speed(tty, port); 14811da177e4SLinus Torvalds } 1482bd09a9f5SAlessio Igor Bogani mutex_unlock(&priv->cfg_lock); 148395da310eSAlan Cox return 0; 1484e49bbce1SJohan Hovold } 14851da177e4SLinus Torvalds 1486c466cd2bSGreg Kroah-Hartman static int get_lsr_info(struct usb_serial_port *port, 148759556608SJohan Hovold unsigned int __user *retinfo) 1488c466cd2bSGreg Kroah-Hartman { 1489c466cd2bSGreg Kroah-Hartman struct ftdi_private *priv = usb_get_serial_port_data(port); 1490c466cd2bSGreg Kroah-Hartman unsigned int result = 0; 1491c466cd2bSGreg Kroah-Hartman 1492c466cd2bSGreg Kroah-Hartman if (priv->transmit_empty) 1493c466cd2bSGreg Kroah-Hartman result = TIOCSER_TEMT; 1494c466cd2bSGreg Kroah-Hartman 1495c466cd2bSGreg Kroah-Hartman if (copy_to_user(retinfo, &result, sizeof(unsigned int))) 1496c466cd2bSGreg Kroah-Hartman return -EFAULT; 1497c466cd2bSGreg Kroah-Hartman return 0; 1498c466cd2bSGreg Kroah-Hartman } 1499c466cd2bSGreg Kroah-Hartman 1500f353c0d4SJohan Hovold static int ftdi_determine_type(struct usb_serial_port *port) 15018f977e42SIan Abbott { 15028f977e42SIan Abbott struct ftdi_private *priv = usb_get_serial_port_data(port); 15038f977e42SIan Abbott struct usb_serial *serial = port->serial; 15048f977e42SIan Abbott struct usb_device *udev = serial->dev; 1505f353c0d4SJohan Hovold unsigned int version, ifnum; 15068f977e42SIan Abbott 15078f977e42SIan Abbott version = le16_to_cpu(udev->descriptor.bcdDevice); 1508f353c0d4SJohan Hovold ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; 15098f977e42SIan Abbott 15104d50f4fcSJohan Hovold /* Assume Hi-Speed type */ 15114d50f4fcSJohan Hovold priv->baud_base = 120000000 / 2; 15124d50f4fcSJohan Hovold priv->channel = CHANNEL_A + ifnum; 1513094c2e6dSMark Adamson 1514f353c0d4SJohan Hovold switch (version) { 1515f353c0d4SJohan Hovold case 0x200: 151601aeb31fSJohan Hovold priv->chip_type = FT232A; 15174d50f4fcSJohan Hovold priv->baud_base = 48000000 / 2; 15184d50f4fcSJohan Hovold priv->channel = 0; 15197e1e6cedSIan Abbott /* 1520f353c0d4SJohan Hovold * FT232B devices have a bug where bcdDevice gets set to 0x200 1521f353c0d4SJohan Hovold * when iSerialNumber is 0. Assume it is an FT232B in case the 1522f353c0d4SJohan Hovold * latency timer is readable. 15237e1e6cedSIan Abbott */ 15247e1e6cedSIan Abbott if (udev->descriptor.iSerialNumber == 0 && 15257e1e6cedSIan Abbott _read_latency_timer(port) >= 0) { 152601aeb31fSJohan Hovold priv->chip_type = FT232B; 15277e1e6cedSIan Abbott } 1528f353c0d4SJohan Hovold break; 1529f353c0d4SJohan Hovold case 0x400: 153001aeb31fSJohan Hovold priv->chip_type = FT232B; 15314d50f4fcSJohan Hovold priv->baud_base = 48000000 / 2; 15324d50f4fcSJohan Hovold priv->channel = 0; 1533f353c0d4SJohan Hovold break; 1534f353c0d4SJohan Hovold case 0x500: 1535f353c0d4SJohan Hovold priv->chip_type = FT2232C; 15364d50f4fcSJohan Hovold priv->baud_base = 48000000 / 2; 1537f353c0d4SJohan Hovold break; 1538f353c0d4SJohan Hovold case 0x600: 153901aeb31fSJohan Hovold priv->chip_type = FT232R; 15404d50f4fcSJohan Hovold priv->baud_base = 48000000 / 2; 15414d50f4fcSJohan Hovold priv->channel = 0; 1542f353c0d4SJohan Hovold break; 1543f353c0d4SJohan Hovold case 0x700: 1544f353c0d4SJohan Hovold priv->chip_type = FT2232H; 1545f353c0d4SJohan Hovold break; 1546f353c0d4SJohan Hovold case 0x800: 1547f353c0d4SJohan Hovold priv->chip_type = FT4232H; 1548f353c0d4SJohan Hovold break; 1549f353c0d4SJohan Hovold case 0x900: 1550309427b6SUwe Bonnes priv->chip_type = FT232H; 1551f353c0d4SJohan Hovold break; 1552f353c0d4SJohan Hovold case 0x1000: 1553dc0827c1SJim Paris priv->chip_type = FTX; 15544d50f4fcSJohan Hovold priv->baud_base = 48000000 / 2; 1555f353c0d4SJohan Hovold break; 1556cfebcd53SAmireddy mallikarjuna reddy case 0x2800: 1557cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT2233HP; 1558cfebcd53SAmireddy mallikarjuna reddy break; 1559cfebcd53SAmireddy mallikarjuna reddy case 0x2900: 1560cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT4233HP; 1561cfebcd53SAmireddy mallikarjuna reddy break; 1562cfebcd53SAmireddy mallikarjuna reddy case 0x3000: 1563cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT2232HP; 1564cfebcd53SAmireddy mallikarjuna reddy break; 1565cfebcd53SAmireddy mallikarjuna reddy case 0x3100: 1566cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT4232HP; 1567cfebcd53SAmireddy mallikarjuna reddy break; 1568cfebcd53SAmireddy mallikarjuna reddy case 0x3200: 1569cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT233HP; 1570cfebcd53SAmireddy mallikarjuna reddy break; 1571cfebcd53SAmireddy mallikarjuna reddy case 0x3300: 1572cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT232HP; 1573cfebcd53SAmireddy mallikarjuna reddy break; 1574cfebcd53SAmireddy mallikarjuna reddy case 0x3600: 1575cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT4232HA; 1576cfebcd53SAmireddy mallikarjuna reddy break; 1577f353c0d4SJohan Hovold default: 1578f353c0d4SJohan Hovold if (version < 0x200) { 1579f353c0d4SJohan Hovold priv->chip_type = SIO; 1580f353c0d4SJohan Hovold priv->baud_base = 12000000 / 16; 15814d50f4fcSJohan Hovold priv->channel = 0; 1582f353c0d4SJohan Hovold } else { 1583f353c0d4SJohan Hovold dev_err(&port->dev, "unknown device type: 0x%02x\n", version); 1584f353c0d4SJohan Hovold return -ENODEV; 1585f353c0d4SJohan Hovold } 15868f977e42SIan Abbott } 1587dc0827c1SJim Paris 1588c197a8dbSGreg Kroah-Hartman dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); 1589f353c0d4SJohan Hovold 1590f353c0d4SJohan Hovold return 0; 15918f977e42SIan Abbott } 15928f977e42SIan Abbott 15938f977e42SIan Abbott 159447e57595SJohan Hovold /* 159547e57595SJohan Hovold * Determine the maximum packet size for the device. This depends on the chip 1596895f28baSMark Adamson * type and the USB host capabilities. The value should be obtained from the 159747e57595SJohan Hovold * device descriptor as the chip will use the appropriate values for the host. 159847e57595SJohan Hovold */ 1599895f28baSMark Adamson static void ftdi_set_max_packet_size(struct usb_serial_port *port) 1600895f28baSMark Adamson { 1601895f28baSMark Adamson struct ftdi_private *priv = usb_get_serial_port_data(port); 160247e57595SJohan Hovold struct usb_interface *interface = port->serial->interface; 1603aea1ae87SJohan Hovold struct usb_endpoint_descriptor *ep_desc; 1604895f28baSMark Adamson unsigned num_endpoints; 1605aea1ae87SJohan Hovold unsigned i; 1606895f28baSMark Adamson 1607895f28baSMark Adamson num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; 1608aea1ae87SJohan Hovold if (!num_endpoints) 1609aea1ae87SJohan Hovold return; 1610aea1ae87SJohan Hovold 161147e57595SJohan Hovold /* 161247e57595SJohan Hovold * NOTE: Some customers have programmed FT232R/FT245R devices 1613895f28baSMark Adamson * with an endpoint size of 0 - not good. In this case, we 1614895f28baSMark Adamson * want to override the endpoint descriptor setting and use a 161547e57595SJohan Hovold * value of 64 for wMaxPacketSize. 161647e57595SJohan Hovold */ 1617895f28baSMark Adamson for (i = 0; i < num_endpoints; i++) { 1618895f28baSMark Adamson ep_desc = &interface->cur_altsetting->endpoint[i].desc; 161947e57595SJohan Hovold if (!ep_desc->wMaxPacketSize) { 1620895f28baSMark Adamson ep_desc->wMaxPacketSize = cpu_to_le16(0x40); 1621a90d84adSJohan Hovold dev_warn(&port->dev, "Overriding wMaxPacketSize on endpoint %d\n", 1622a90d84adSJohan Hovold usb_endpoint_num(ep_desc)); 1623895f28baSMark Adamson } 1624895f28baSMark Adamson } 1625895f28baSMark Adamson 162647e57595SJohan Hovold /* Set max packet size based on last descriptor. */ 162729cc8897SKuninori Morimoto priv->max_packet_size = usb_endpoint_maxp(ep_desc); 1628895f28baSMark Adamson } 1629895f28baSMark Adamson 1630895f28baSMark Adamson 16311da177e4SLinus Torvalds /* 16321da177e4SLinus Torvalds * *************************************************************************** 16331da177e4SLinus Torvalds * Sysfs Attribute 16341da177e4SLinus Torvalds * *************************************************************************** 16351da177e4SLinus Torvalds */ 16361da177e4SLinus Torvalds 1637154547c4SGreg Kroah-Hartman static ssize_t latency_timer_show(struct device *dev, 1638464cbb24SAlan Cox struct device_attribute *attr, char *buf) 16391da177e4SLinus Torvalds { 16401da177e4SLinus Torvalds struct usb_serial_port *port = to_usb_serial_port(dev); 16411da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 1642557aaa7fSAlan Cox if (priv->flags & ASYNC_LOW_LATENCY) 1643557aaa7fSAlan Cox return sprintf(buf, "1\n"); 1644557aaa7fSAlan Cox else 16451b30499aSDaniels Umanovskis return sprintf(buf, "%u\n", priv->latency); 16461da177e4SLinus Torvalds } 1647557aaa7fSAlan Cox 16481da177e4SLinus Torvalds /* Write a new value of the latency timer, in units of milliseconds. */ 1649154547c4SGreg Kroah-Hartman static ssize_t latency_timer_store(struct device *dev, 1650154547c4SGreg Kroah-Hartman struct device_attribute *attr, 1651154547c4SGreg Kroah-Hartman const char *valbuf, size_t count) 16521da177e4SLinus Torvalds { 16531da177e4SLinus Torvalds struct usb_serial_port *port = to_usb_serial_port(dev); 16541da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 1655db924066SIan Abbott u8 v; 1656c1284d77SJohan Hovold int rv; 16571da177e4SLinus Torvalds 1658db924066SIan Abbott if (kstrtou8(valbuf, 10, &v)) 1659db924066SIan Abbott return -EINVAL; 1660db924066SIan Abbott 1661557aaa7fSAlan Cox priv->latency = v; 1662557aaa7fSAlan Cox rv = write_latency_timer(port); 1663557aaa7fSAlan Cox if (rv < 0) 16641da177e4SLinus Torvalds return -EIO; 16651da177e4SLinus Torvalds return count; 16661da177e4SLinus Torvalds } 1667154547c4SGreg Kroah-Hartman static DEVICE_ATTR_RW(latency_timer); 16681da177e4SLinus Torvalds 16691da177e4SLinus Torvalds /* Write an event character directly to the FTDI register. The ASCII 16701da177e4SLinus Torvalds value is in the low 8 bits, with the enable bit in the 9th bit. */ 1671ca35910aSGreg Kroah-Hartman static ssize_t event_char_store(struct device *dev, 1672464cbb24SAlan Cox struct device_attribute *attr, const char *valbuf, size_t count) 16731da177e4SLinus Torvalds { 16741da177e4SLinus Torvalds struct usb_serial_port *port = to_usb_serial_port(dev); 16751da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 167612bdbe03SJim Radford struct usb_device *udev = port->serial->dev; 1677d0559a2fSIan Abbott unsigned int v; 1678c1284d77SJohan Hovold int rv; 16791da177e4SLinus Torvalds 1680f1ce25f2SIan Abbott if (kstrtouint(valbuf, 0, &v) || v >= 0x200) 1681d0559a2fSIan Abbott return -EINVAL; 1682d0559a2fSIan Abbott 1683f1ce25f2SIan Abbott dev_dbg(&port->dev, "%s: setting event char = 0x%03x\n", __func__, v); 16841da177e4SLinus Torvalds 16851da177e4SLinus Torvalds rv = usb_control_msg(udev, 16861da177e4SLinus Torvalds usb_sndctrlpipe(udev, 0), 16871da177e4SLinus Torvalds FTDI_SIO_SET_EVENT_CHAR_REQUEST, 16881da177e4SLinus Torvalds FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, 1689027bf37dSJohan Hovold v, priv->channel, 169066e47e60SJohan Hovold NULL, 0, WDR_TIMEOUT); 16911da177e4SLinus Torvalds if (rv < 0) { 1692bfc51614SGreg Kroah-Hartman dev_dbg(&port->dev, "Unable to write event character: %i\n", rv); 16931da177e4SLinus Torvalds return -EIO; 16941da177e4SLinus Torvalds } 16951da177e4SLinus Torvalds 16961da177e4SLinus Torvalds return count; 16971da177e4SLinus Torvalds } 1698ca35910aSGreg Kroah-Hartman static DEVICE_ATTR_WO(event_char); 16991da177e4SLinus Torvalds 17000f6632e2SJiasheng Jiang static struct attribute *ftdi_attrs[] = { 17010f6632e2SJiasheng Jiang &dev_attr_event_char.attr, 17020f6632e2SJiasheng Jiang &dev_attr_latency_timer.attr, 17030f6632e2SJiasheng Jiang NULL 17040f6632e2SJiasheng Jiang }; 17050f6632e2SJiasheng Jiang 17060f6632e2SJiasheng Jiang static umode_t ftdi_is_visible(struct kobject *kobj, struct attribute *attr, int idx) 17071da177e4SLinus Torvalds { 17080f6632e2SJiasheng Jiang struct device *dev = kobj_to_dev(kobj); 17090f6632e2SJiasheng Jiang struct usb_serial_port *port = to_usb_serial_port(dev); 171012bdbe03SJim Radford struct ftdi_private *priv = usb_get_serial_port_data(port); 17114d045b98SJohan Hovold enum ftdi_chip_type type = priv->chip_type; 17121da177e4SLinus Torvalds 1713c142bdc5SJohan Hovold if (attr == &dev_attr_event_char.attr) { 1714c142bdc5SJohan Hovold if (type == SIO) 17150f6632e2SJiasheng Jiang return 0; 17161da177e4SLinus Torvalds } 17171da177e4SLinus Torvalds 1718c142bdc5SJohan Hovold if (attr == &dev_attr_latency_timer.attr) { 1719c142bdc5SJohan Hovold if (type == SIO || type == FT232A) 1720c142bdc5SJohan Hovold return 0; 1721c142bdc5SJohan Hovold } 1722c142bdc5SJohan Hovold 1723c142bdc5SJohan Hovold return attr->mode; 1724c142bdc5SJohan Hovold } 1725c142bdc5SJohan Hovold 17260f6632e2SJiasheng Jiang static const struct attribute_group ftdi_group = { 17270f6632e2SJiasheng Jiang .attrs = ftdi_attrs, 17280f6632e2SJiasheng Jiang .is_visible = ftdi_is_visible, 17290f6632e2SJiasheng Jiang }; 17300f6632e2SJiasheng Jiang 17310f6632e2SJiasheng Jiang static const struct attribute_group *ftdi_groups[] = { 17320f6632e2SJiasheng Jiang &ftdi_group, 17330f6632e2SJiasheng Jiang NULL 17340f6632e2SJiasheng Jiang }; 17350f6632e2SJiasheng Jiang 1736ba93cc7dSKaroly Pados #ifdef CONFIG_GPIOLIB 1737ba93cc7dSKaroly Pados 1738ba93cc7dSKaroly Pados static int ftdi_set_bitmode(struct usb_serial_port *port, u8 mode) 1739ba93cc7dSKaroly Pados { 1740ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1741ba93cc7dSKaroly Pados struct usb_serial *serial = port->serial; 1742ba93cc7dSKaroly Pados int result; 1743ba93cc7dSKaroly Pados u16 val; 1744ba93cc7dSKaroly Pados 1745a8eda9faSKaroly Pados result = usb_autopm_get_interface(serial->interface); 1746a8eda9faSKaroly Pados if (result) 1747a8eda9faSKaroly Pados return result; 1748a8eda9faSKaroly Pados 1749ba93cc7dSKaroly Pados val = (mode << 8) | (priv->gpio_output << 4) | priv->gpio_value; 1750ba93cc7dSKaroly Pados result = usb_control_msg(serial->dev, 1751ba93cc7dSKaroly Pados usb_sndctrlpipe(serial->dev, 0), 1752ba93cc7dSKaroly Pados FTDI_SIO_SET_BITMODE_REQUEST, 1753ba93cc7dSKaroly Pados FTDI_SIO_SET_BITMODE_REQUEST_TYPE, val, 1754027bf37dSJohan Hovold priv->channel, NULL, 0, WDR_TIMEOUT); 1755ba93cc7dSKaroly Pados if (result < 0) { 1756ba93cc7dSKaroly Pados dev_err(&serial->interface->dev, 1757ba93cc7dSKaroly Pados "bitmode request failed for value 0x%04x: %d\n", 1758ba93cc7dSKaroly Pados val, result); 1759ba93cc7dSKaroly Pados } 1760ba93cc7dSKaroly Pados 1761a8eda9faSKaroly Pados usb_autopm_put_interface(serial->interface); 1762a8eda9faSKaroly Pados 1763ba93cc7dSKaroly Pados return result; 1764ba93cc7dSKaroly Pados } 1765ba93cc7dSKaroly Pados 1766ba93cc7dSKaroly Pados static int ftdi_set_cbus_pins(struct usb_serial_port *port) 1767ba93cc7dSKaroly Pados { 1768ba93cc7dSKaroly Pados return ftdi_set_bitmode(port, FTDI_SIO_BITMODE_CBUS); 1769ba93cc7dSKaroly Pados } 1770ba93cc7dSKaroly Pados 1771ba93cc7dSKaroly Pados static int ftdi_exit_cbus_mode(struct usb_serial_port *port) 1772ba93cc7dSKaroly Pados { 1773ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1774ba93cc7dSKaroly Pados 1775ba93cc7dSKaroly Pados priv->gpio_output = 0; 1776ba93cc7dSKaroly Pados priv->gpio_value = 0; 1777ba93cc7dSKaroly Pados return ftdi_set_bitmode(port, FTDI_SIO_BITMODE_RESET); 1778ba93cc7dSKaroly Pados } 1779ba93cc7dSKaroly Pados 1780ba93cc7dSKaroly Pados static int ftdi_gpio_request(struct gpio_chip *gc, unsigned int offset) 1781ba93cc7dSKaroly Pados { 1782ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1783ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1784ba93cc7dSKaroly Pados int result; 1785ba93cc7dSKaroly Pados 1786ba93cc7dSKaroly Pados mutex_lock(&priv->gpio_lock); 1787ba93cc7dSKaroly Pados if (!priv->gpio_used) { 1788ba93cc7dSKaroly Pados /* Set default pin states, as we cannot get them from device */ 1789ba93cc7dSKaroly Pados priv->gpio_output = 0x00; 1790ba93cc7dSKaroly Pados priv->gpio_value = 0x00; 1791ba93cc7dSKaroly Pados result = ftdi_set_cbus_pins(port); 1792ba93cc7dSKaroly Pados if (result) { 1793ba93cc7dSKaroly Pados mutex_unlock(&priv->gpio_lock); 1794ba93cc7dSKaroly Pados return result; 1795ba93cc7dSKaroly Pados } 1796ba93cc7dSKaroly Pados 1797ba93cc7dSKaroly Pados priv->gpio_used = true; 1798ba93cc7dSKaroly Pados } 1799ba93cc7dSKaroly Pados mutex_unlock(&priv->gpio_lock); 1800ba93cc7dSKaroly Pados 1801ba93cc7dSKaroly Pados return 0; 1802ba93cc7dSKaroly Pados } 1803ba93cc7dSKaroly Pados 1804ba93cc7dSKaroly Pados static int ftdi_read_cbus_pins(struct usb_serial_port *port) 1805ba93cc7dSKaroly Pados { 1806ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1807ba93cc7dSKaroly Pados struct usb_serial *serial = port->serial; 1808a7388592SHimadri Pandya u8 buf; 1809ba93cc7dSKaroly Pados int result; 1810ba93cc7dSKaroly Pados 1811a8eda9faSKaroly Pados result = usb_autopm_get_interface(serial->interface); 1812a8eda9faSKaroly Pados if (result) 1813a8eda9faSKaroly Pados return result; 1814a8eda9faSKaroly Pados 1815a7388592SHimadri Pandya result = usb_control_msg_recv(serial->dev, 0, 1816ba93cc7dSKaroly Pados FTDI_SIO_READ_PINS_REQUEST, 1817ba93cc7dSKaroly Pados FTDI_SIO_READ_PINS_REQUEST_TYPE, 0, 1818027bf37dSJohan Hovold priv->channel, &buf, 1, WDR_TIMEOUT, 1819a7388592SHimadri Pandya GFP_KERNEL); 1820a7388592SHimadri Pandya if (result == 0) 1821a7388592SHimadri Pandya result = buf; 1822ba93cc7dSKaroly Pados 1823a8eda9faSKaroly Pados usb_autopm_put_interface(serial->interface); 1824ba93cc7dSKaroly Pados 1825ba93cc7dSKaroly Pados return result; 1826ba93cc7dSKaroly Pados } 1827ba93cc7dSKaroly Pados 1828ba93cc7dSKaroly Pados static int ftdi_gpio_get(struct gpio_chip *gc, unsigned int gpio) 1829ba93cc7dSKaroly Pados { 1830ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1831ba93cc7dSKaroly Pados int result; 1832ba93cc7dSKaroly Pados 1833ba93cc7dSKaroly Pados result = ftdi_read_cbus_pins(port); 1834ba93cc7dSKaroly Pados if (result < 0) 1835ba93cc7dSKaroly Pados return result; 1836ba93cc7dSKaroly Pados 1837ba93cc7dSKaroly Pados return !!(result & BIT(gpio)); 1838ba93cc7dSKaroly Pados } 1839ba93cc7dSKaroly Pados 1840ba93cc7dSKaroly Pados static void ftdi_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value) 1841ba93cc7dSKaroly Pados { 1842ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1843ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1844ba93cc7dSKaroly Pados 1845ba93cc7dSKaroly Pados mutex_lock(&priv->gpio_lock); 1846ba93cc7dSKaroly Pados 1847ba93cc7dSKaroly Pados if (value) 1848ba93cc7dSKaroly Pados priv->gpio_value |= BIT(gpio); 1849ba93cc7dSKaroly Pados else 1850ba93cc7dSKaroly Pados priv->gpio_value &= ~BIT(gpio); 1851ba93cc7dSKaroly Pados 1852ba93cc7dSKaroly Pados ftdi_set_cbus_pins(port); 1853ba93cc7dSKaroly Pados 1854ba93cc7dSKaroly Pados mutex_unlock(&priv->gpio_lock); 1855ba93cc7dSKaroly Pados } 1856ba93cc7dSKaroly Pados 1857ba93cc7dSKaroly Pados static int ftdi_gpio_get_multiple(struct gpio_chip *gc, unsigned long *mask, 1858ba93cc7dSKaroly Pados unsigned long *bits) 1859ba93cc7dSKaroly Pados { 1860ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1861ba93cc7dSKaroly Pados int result; 1862ba93cc7dSKaroly Pados 1863ba93cc7dSKaroly Pados result = ftdi_read_cbus_pins(port); 1864ba93cc7dSKaroly Pados if (result < 0) 1865ba93cc7dSKaroly Pados return result; 1866ba93cc7dSKaroly Pados 1867ba93cc7dSKaroly Pados *bits = result & *mask; 1868ba93cc7dSKaroly Pados 1869ba93cc7dSKaroly Pados return 0; 1870ba93cc7dSKaroly Pados } 1871ba93cc7dSKaroly Pados 1872ba93cc7dSKaroly Pados static void ftdi_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, 1873ba93cc7dSKaroly Pados unsigned long *bits) 1874ba93cc7dSKaroly Pados { 1875ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1876ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1877ba93cc7dSKaroly Pados 1878ba93cc7dSKaroly Pados mutex_lock(&priv->gpio_lock); 1879ba93cc7dSKaroly Pados 1880ba93cc7dSKaroly Pados priv->gpio_value &= ~(*mask); 1881ba93cc7dSKaroly Pados priv->gpio_value |= *bits & *mask; 1882ba93cc7dSKaroly Pados ftdi_set_cbus_pins(port); 1883ba93cc7dSKaroly Pados 1884ba93cc7dSKaroly Pados mutex_unlock(&priv->gpio_lock); 1885ba93cc7dSKaroly Pados } 1886ba93cc7dSKaroly Pados 1887ba93cc7dSKaroly Pados static int ftdi_gpio_direction_get(struct gpio_chip *gc, unsigned int gpio) 1888ba93cc7dSKaroly Pados { 1889ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1890ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1891ba93cc7dSKaroly Pados 1892ba93cc7dSKaroly Pados return !(priv->gpio_output & BIT(gpio)); 1893ba93cc7dSKaroly Pados } 1894ba93cc7dSKaroly Pados 1895ba93cc7dSKaroly Pados static int ftdi_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio) 1896ba93cc7dSKaroly Pados { 1897ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1898ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1899ba93cc7dSKaroly Pados int result; 1900ba93cc7dSKaroly Pados 1901ba93cc7dSKaroly Pados mutex_lock(&priv->gpio_lock); 1902ba93cc7dSKaroly Pados 1903ba93cc7dSKaroly Pados priv->gpio_output &= ~BIT(gpio); 1904ba93cc7dSKaroly Pados result = ftdi_set_cbus_pins(port); 1905ba93cc7dSKaroly Pados 1906ba93cc7dSKaroly Pados mutex_unlock(&priv->gpio_lock); 1907ba93cc7dSKaroly Pados 1908ba93cc7dSKaroly Pados return result; 1909ba93cc7dSKaroly Pados } 1910ba93cc7dSKaroly Pados 1911ba93cc7dSKaroly Pados static int ftdi_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio, 1912ba93cc7dSKaroly Pados int value) 1913ba93cc7dSKaroly Pados { 1914ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1915ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1916ba93cc7dSKaroly Pados int result; 1917ba93cc7dSKaroly Pados 1918ba93cc7dSKaroly Pados mutex_lock(&priv->gpio_lock); 1919ba93cc7dSKaroly Pados 1920ba93cc7dSKaroly Pados priv->gpio_output |= BIT(gpio); 1921ba93cc7dSKaroly Pados if (value) 1922ba93cc7dSKaroly Pados priv->gpio_value |= BIT(gpio); 1923ba93cc7dSKaroly Pados else 1924ba93cc7dSKaroly Pados priv->gpio_value &= ~BIT(gpio); 1925ba93cc7dSKaroly Pados 1926ba93cc7dSKaroly Pados result = ftdi_set_cbus_pins(port); 1927ba93cc7dSKaroly Pados 1928ba93cc7dSKaroly Pados mutex_unlock(&priv->gpio_lock); 1929ba93cc7dSKaroly Pados 1930ba93cc7dSKaroly Pados return result; 1931ba93cc7dSKaroly Pados } 1932ba93cc7dSKaroly Pados 193311fb08cfSMarc Zyngier static int ftdi_gpio_init_valid_mask(struct gpio_chip *gc, 193411fb08cfSMarc Zyngier unsigned long *valid_mask, 193511fb08cfSMarc Zyngier unsigned int ngpios) 193611fb08cfSMarc Zyngier { 193711fb08cfSMarc Zyngier struct usb_serial_port *port = gpiochip_get_data(gc); 193811fb08cfSMarc Zyngier struct ftdi_private *priv = usb_get_serial_port_data(port); 193911fb08cfSMarc Zyngier unsigned long map = priv->gpio_altfunc; 194011fb08cfSMarc Zyngier 194111fb08cfSMarc Zyngier bitmap_complement(valid_mask, &map, ngpios); 194211fb08cfSMarc Zyngier 1943fddd408aSMarc Zyngier if (bitmap_empty(valid_mask, ngpios)) 1944fddd408aSMarc Zyngier dev_dbg(&port->dev, "no CBUS pin configured for GPIO\n"); 1945fddd408aSMarc Zyngier else 1946fddd408aSMarc Zyngier dev_dbg(&port->dev, "CBUS%*pbl configured for GPIO\n", ngpios, 1947fddd408aSMarc Zyngier valid_mask); 1948fddd408aSMarc Zyngier 194911fb08cfSMarc Zyngier return 0; 195011fb08cfSMarc Zyngier } 195111fb08cfSMarc Zyngier 1952ba93cc7dSKaroly Pados static int ftdi_read_eeprom(struct usb_serial *serial, void *dst, u16 addr, 1953ba93cc7dSKaroly Pados u16 nbytes) 1954ba93cc7dSKaroly Pados { 1955ba93cc7dSKaroly Pados int read = 0; 1956ba93cc7dSKaroly Pados 1957ba93cc7dSKaroly Pados if (addr % 2 != 0) 1958ba93cc7dSKaroly Pados return -EINVAL; 1959ba93cc7dSKaroly Pados if (nbytes % 2 != 0) 1960ba93cc7dSKaroly Pados return -EINVAL; 1961ba93cc7dSKaroly Pados 1962ba93cc7dSKaroly Pados /* Read EEPROM two bytes at a time */ 1963ba93cc7dSKaroly Pados while (read < nbytes) { 1964ba93cc7dSKaroly Pados int rv; 1965ba93cc7dSKaroly Pados 1966ba93cc7dSKaroly Pados rv = usb_control_msg(serial->dev, 1967ba93cc7dSKaroly Pados usb_rcvctrlpipe(serial->dev, 0), 1968ba93cc7dSKaroly Pados FTDI_SIO_READ_EEPROM_REQUEST, 1969ba93cc7dSKaroly Pados FTDI_SIO_READ_EEPROM_REQUEST_TYPE, 1970ba93cc7dSKaroly Pados 0, (addr + read) / 2, dst + read, 2, 1971ba93cc7dSKaroly Pados WDR_TIMEOUT); 1972ba93cc7dSKaroly Pados if (rv < 2) { 1973ba93cc7dSKaroly Pados if (rv >= 0) 1974ba93cc7dSKaroly Pados return -EIO; 1975ba93cc7dSKaroly Pados else 1976ba93cc7dSKaroly Pados return rv; 1977ba93cc7dSKaroly Pados } 1978ba93cc7dSKaroly Pados 1979ba93cc7dSKaroly Pados read += rv; 1980ba93cc7dSKaroly Pados } 1981ba93cc7dSKaroly Pados 1982ba93cc7dSKaroly Pados return 0; 1983ba93cc7dSKaroly Pados } 1984ba93cc7dSKaroly Pados 19857a786b84SMatthew Michilot static int ftdi_gpio_init_ft232h(struct usb_serial_port *port) 19867a786b84SMatthew Michilot { 19877a786b84SMatthew Michilot struct ftdi_private *priv = usb_get_serial_port_data(port); 19887a786b84SMatthew Michilot u16 cbus_config; 19897a786b84SMatthew Michilot u8 *buf; 19907a786b84SMatthew Michilot int ret; 19917a786b84SMatthew Michilot int i; 19927a786b84SMatthew Michilot 19937a786b84SMatthew Michilot buf = kmalloc(4, GFP_KERNEL); 19947a786b84SMatthew Michilot if (!buf) 19957a786b84SMatthew Michilot return -ENOMEM; 19967a786b84SMatthew Michilot 19977a786b84SMatthew Michilot ret = ftdi_read_eeprom(port->serial, buf, 0x1a, 4); 19987a786b84SMatthew Michilot if (ret < 0) 19997a786b84SMatthew Michilot goto out_free; 20007a786b84SMatthew Michilot 20017a786b84SMatthew Michilot /* 20027a786b84SMatthew Michilot * FT232H CBUS Memory Map 20037a786b84SMatthew Michilot * 20047a786b84SMatthew Michilot * 0x1a: X- (upper nibble -> AC5) 20057a786b84SMatthew Michilot * 0x1b: -X (lower nibble -> AC6) 20067a786b84SMatthew Michilot * 0x1c: XX (upper nibble -> AC9 | lower nibble -> AC8) 20077a786b84SMatthew Michilot */ 20087a786b84SMatthew Michilot cbus_config = buf[2] << 8 | (buf[1] & 0xf) << 4 | (buf[0] & 0xf0) >> 4; 20097a786b84SMatthew Michilot 20107a786b84SMatthew Michilot priv->gc.ngpio = 4; 20117a786b84SMatthew Michilot priv->gpio_altfunc = 0xff; 20127a786b84SMatthew Michilot 20137a786b84SMatthew Michilot for (i = 0; i < priv->gc.ngpio; ++i) { 20147a786b84SMatthew Michilot if ((cbus_config & 0xf) == FTDI_FTX_CBUS_MUX_GPIO) 20157a786b84SMatthew Michilot priv->gpio_altfunc &= ~BIT(i); 20167a786b84SMatthew Michilot cbus_config >>= 4; 20177a786b84SMatthew Michilot } 20187a786b84SMatthew Michilot 20197a786b84SMatthew Michilot out_free: 20207a786b84SMatthew Michilot kfree(buf); 20217a786b84SMatthew Michilot 20227a786b84SMatthew Michilot return ret; 20237a786b84SMatthew Michilot } 20247a786b84SMatthew Michilot 2025ff32d97eSJohan Hovold static int ftdi_gpio_init_ft232r(struct usb_serial_port *port) 2026ff32d97eSJohan Hovold { 2027ff32d97eSJohan Hovold struct ftdi_private *priv = usb_get_serial_port_data(port); 2028ff32d97eSJohan Hovold u16 cbus_config; 2029ff32d97eSJohan Hovold u8 *buf; 2030ff32d97eSJohan Hovold int ret; 2031ff32d97eSJohan Hovold int i; 2032ff32d97eSJohan Hovold 2033ff32d97eSJohan Hovold buf = kmalloc(2, GFP_KERNEL); 2034ff32d97eSJohan Hovold if (!buf) 2035ff32d97eSJohan Hovold return -ENOMEM; 2036ff32d97eSJohan Hovold 2037ff32d97eSJohan Hovold ret = ftdi_read_eeprom(port->serial, buf, 0x14, 2); 2038ff32d97eSJohan Hovold if (ret < 0) 2039ff32d97eSJohan Hovold goto out_free; 2040ff32d97eSJohan Hovold 2041ff32d97eSJohan Hovold cbus_config = le16_to_cpup((__le16 *)buf); 2042ff32d97eSJohan Hovold dev_dbg(&port->dev, "cbus_config = 0x%04x\n", cbus_config); 2043ff32d97eSJohan Hovold 2044ff32d97eSJohan Hovold priv->gc.ngpio = 4; 2045ff32d97eSJohan Hovold 2046ff32d97eSJohan Hovold priv->gpio_altfunc = 0xff; 2047ff32d97eSJohan Hovold for (i = 0; i < priv->gc.ngpio; ++i) { 2048ff32d97eSJohan Hovold if ((cbus_config & 0xf) == FTDI_FT232R_CBUS_MUX_GPIO) 2049ff32d97eSJohan Hovold priv->gpio_altfunc &= ~BIT(i); 2050ff32d97eSJohan Hovold cbus_config >>= 4; 2051ff32d97eSJohan Hovold } 2052ff32d97eSJohan Hovold out_free: 2053ff32d97eSJohan Hovold kfree(buf); 2054ff32d97eSJohan Hovold 2055ff32d97eSJohan Hovold return ret; 2056ff32d97eSJohan Hovold } 2057ff32d97eSJohan Hovold 2058ff32d97eSJohan Hovold static int ftdi_gpio_init_ftx(struct usb_serial_port *port) 2059ba93cc7dSKaroly Pados { 2060ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 2061ba93cc7dSKaroly Pados struct usb_serial *serial = port->serial; 2062ba93cc7dSKaroly Pados const u16 cbus_cfg_addr = 0x1a; 2063ba93cc7dSKaroly Pados const u16 cbus_cfg_size = 4; 2064ba93cc7dSKaroly Pados u8 *cbus_cfg_buf; 2065ba93cc7dSKaroly Pados int result; 2066ba93cc7dSKaroly Pados u8 i; 2067ba93cc7dSKaroly Pados 2068ba93cc7dSKaroly Pados cbus_cfg_buf = kmalloc(cbus_cfg_size, GFP_KERNEL); 2069ba93cc7dSKaroly Pados if (!cbus_cfg_buf) 2070ba93cc7dSKaroly Pados return -ENOMEM; 2071ba93cc7dSKaroly Pados 2072ba93cc7dSKaroly Pados result = ftdi_read_eeprom(serial, cbus_cfg_buf, 2073ba93cc7dSKaroly Pados cbus_cfg_addr, cbus_cfg_size); 2074ba93cc7dSKaroly Pados if (result < 0) 2075ba93cc7dSKaroly Pados goto out_free; 2076ba93cc7dSKaroly Pados 2077ba93cc7dSKaroly Pados /* FIXME: FT234XD alone has 1 GPIO, but how to recognize this IC? */ 2078ba93cc7dSKaroly Pados priv->gc.ngpio = 4; 2079ba93cc7dSKaroly Pados 2080ba93cc7dSKaroly Pados /* Determine which pins are configured for CBUS bitbanging */ 2081ba93cc7dSKaroly Pados priv->gpio_altfunc = 0xff; 2082ba93cc7dSKaroly Pados for (i = 0; i < priv->gc.ngpio; ++i) { 2083ba93cc7dSKaroly Pados if (cbus_cfg_buf[i] == FTDI_FTX_CBUS_MUX_GPIO) 2084ba93cc7dSKaroly Pados priv->gpio_altfunc &= ~BIT(i); 2085ba93cc7dSKaroly Pados } 2086ba93cc7dSKaroly Pados 2087ba93cc7dSKaroly Pados out_free: 2088ba93cc7dSKaroly Pados kfree(cbus_cfg_buf); 2089ba93cc7dSKaroly Pados 2090ba93cc7dSKaroly Pados return result; 2091ba93cc7dSKaroly Pados } 2092ba93cc7dSKaroly Pados 2093ba93cc7dSKaroly Pados static int ftdi_gpio_init(struct usb_serial_port *port) 2094ba93cc7dSKaroly Pados { 2095ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 2096ba93cc7dSKaroly Pados struct usb_serial *serial = port->serial; 2097ba93cc7dSKaroly Pados int result; 2098ba93cc7dSKaroly Pados 2099ba93cc7dSKaroly Pados switch (priv->chip_type) { 21007a786b84SMatthew Michilot case FT232H: 21017a786b84SMatthew Michilot result = ftdi_gpio_init_ft232h(port); 21027a786b84SMatthew Michilot break; 210301aeb31fSJohan Hovold case FT232R: 2104ff32d97eSJohan Hovold result = ftdi_gpio_init_ft232r(port); 2105ff32d97eSJohan Hovold break; 2106ba93cc7dSKaroly Pados case FTX: 2107ff32d97eSJohan Hovold result = ftdi_gpio_init_ftx(port); 2108ba93cc7dSKaroly Pados break; 2109ba93cc7dSKaroly Pados default: 2110ba93cc7dSKaroly Pados return 0; 2111ba93cc7dSKaroly Pados } 2112ba93cc7dSKaroly Pados 2113ba93cc7dSKaroly Pados if (result < 0) 2114ba93cc7dSKaroly Pados return result; 2115ba93cc7dSKaroly Pados 2116ba93cc7dSKaroly Pados mutex_init(&priv->gpio_lock); 2117ba93cc7dSKaroly Pados 2118ba93cc7dSKaroly Pados priv->gc.label = "ftdi-cbus"; 2119ba93cc7dSKaroly Pados priv->gc.request = ftdi_gpio_request; 2120ba93cc7dSKaroly Pados priv->gc.get_direction = ftdi_gpio_direction_get; 2121ba93cc7dSKaroly Pados priv->gc.direction_input = ftdi_gpio_direction_input; 2122ba93cc7dSKaroly Pados priv->gc.direction_output = ftdi_gpio_direction_output; 212311fb08cfSMarc Zyngier priv->gc.init_valid_mask = ftdi_gpio_init_valid_mask; 2124ba93cc7dSKaroly Pados priv->gc.get = ftdi_gpio_get; 2125ba93cc7dSKaroly Pados priv->gc.set = ftdi_gpio_set; 2126ba93cc7dSKaroly Pados priv->gc.get_multiple = ftdi_gpio_get_multiple; 2127ba93cc7dSKaroly Pados priv->gc.set_multiple = ftdi_gpio_set_multiple; 2128ba93cc7dSKaroly Pados priv->gc.owner = THIS_MODULE; 2129ba93cc7dSKaroly Pados priv->gc.parent = &serial->interface->dev; 2130ba93cc7dSKaroly Pados priv->gc.base = -1; 2131ba93cc7dSKaroly Pados priv->gc.can_sleep = true; 2132ba93cc7dSKaroly Pados 2133ba93cc7dSKaroly Pados result = gpiochip_add_data(&priv->gc, port); 2134ba93cc7dSKaroly Pados if (!result) 2135ba93cc7dSKaroly Pados priv->gpio_registered = true; 2136ba93cc7dSKaroly Pados 2137ba93cc7dSKaroly Pados return result; 2138ba93cc7dSKaroly Pados } 2139ba93cc7dSKaroly Pados 2140ba93cc7dSKaroly Pados static void ftdi_gpio_remove(struct usb_serial_port *port) 2141ba93cc7dSKaroly Pados { 2142ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 2143ba93cc7dSKaroly Pados 2144ba93cc7dSKaroly Pados if (priv->gpio_registered) { 2145ba93cc7dSKaroly Pados gpiochip_remove(&priv->gc); 2146ba93cc7dSKaroly Pados priv->gpio_registered = false; 2147ba93cc7dSKaroly Pados } 2148ba93cc7dSKaroly Pados 2149ba93cc7dSKaroly Pados if (priv->gpio_used) { 2150ba93cc7dSKaroly Pados /* Exiting CBUS-mode does not reset pin states. */ 2151ba93cc7dSKaroly Pados ftdi_exit_cbus_mode(port); 2152ba93cc7dSKaroly Pados priv->gpio_used = false; 2153ba93cc7dSKaroly Pados } 2154ba93cc7dSKaroly Pados } 2155ba93cc7dSKaroly Pados 2156ba93cc7dSKaroly Pados #else 2157ba93cc7dSKaroly Pados 2158ba93cc7dSKaroly Pados static int ftdi_gpio_init(struct usb_serial_port *port) 2159ba93cc7dSKaroly Pados { 2160ba93cc7dSKaroly Pados return 0; 2161ba93cc7dSKaroly Pados } 2162ba93cc7dSKaroly Pados 2163ba93cc7dSKaroly Pados static void ftdi_gpio_remove(struct usb_serial_port *port) { } 2164ba93cc7dSKaroly Pados 2165ba93cc7dSKaroly Pados #endif /* CONFIG_GPIOLIB */ 2166ba93cc7dSKaroly Pados 21671da177e4SLinus Torvalds /* 21681da177e4SLinus Torvalds * *************************************************************************** 21691da177e4SLinus Torvalds * FTDI driver specific functions 21701da177e4SLinus Torvalds * *************************************************************************** 21711da177e4SLinus Torvalds */ 21721da177e4SLinus Torvalds 21738f977e42SIan Abbott /* Probe function to check for special devices */ 2174464cbb24SAlan Cox static int ftdi_sio_probe(struct usb_serial *serial, 2175464cbb24SAlan Cox const struct usb_device_id *id) 21768f977e42SIan Abbott { 21773c77f7c9SJulia Lawall const struct ftdi_sio_quirk *quirk = 2178464cbb24SAlan Cox (struct ftdi_sio_quirk *)id->driver_info; 2179fa91d43bSTony Lindgren 2180fa91d43bSTony Lindgren if (quirk && quirk->probe) { 2181fa91d43bSTony Lindgren int ret = quirk->probe(serial); 2182fa91d43bSTony Lindgren if (ret != 0) 2183fa91d43bSTony Lindgren return ret; 2184fa91d43bSTony Lindgren } 2185fa91d43bSTony Lindgren 21868f977e42SIan Abbott usb_set_serial_data(serial, (void *)id->driver_info); 21878f977e42SIan Abbott 2188fa91d43bSTony Lindgren return 0; 21898f977e42SIan Abbott } 21908f977e42SIan Abbott 219112bdbe03SJim Radford static int ftdi_sio_port_probe(struct usb_serial_port *port) 21921da177e4SLinus Torvalds { 21931da177e4SLinus Torvalds struct ftdi_private *priv; 21943c77f7c9SJulia Lawall const struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial); 2195ba93cc7dSKaroly Pados int result; 21961da177e4SLinus Torvalds 219780b6ca48SEric Sesterhenn priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); 219810c642d0SJohan Hovold if (!priv) 21991da177e4SLinus Torvalds return -ENOMEM; 22001da177e4SLinus Torvalds 2201bd09a9f5SAlessio Igor Bogani mutex_init(&priv->cfg_lock); 22020076b4beSJohan Hovold 22030ffbbe25SOliver Neukum if (quirk && quirk->port_probe) 22040ffbbe25SOliver Neukum quirk->port_probe(priv); 22050ffbbe25SOliver Neukum 220612bdbe03SJim Radford usb_set_serial_port_data(port, priv); 22071da177e4SLinus Torvalds 2208f353c0d4SJohan Hovold result = ftdi_determine_type(port); 2209f353c0d4SJohan Hovold if (result) 2210f353c0d4SJohan Hovold goto err_free; 2211f353c0d4SJohan Hovold 2212895f28baSMark Adamson ftdi_set_max_packet_size(port); 22138c4f99cdSJohan Hovold if (read_latency_timer(port) < 0) 22148c4f99cdSJohan Hovold priv->latency = 16; 2215c19db4c9SJohan Hovold write_latency_timer(port); 2216ba93cc7dSKaroly Pados 2217ba93cc7dSKaroly Pados result = ftdi_gpio_init(port); 2218ba93cc7dSKaroly Pados if (result < 0) { 2219ba93cc7dSKaroly Pados dev_err(&port->serial->interface->dev, 2220ba93cc7dSKaroly Pados "GPIO initialisation failed: %d\n", 2221ba93cc7dSKaroly Pados result); 2222ba93cc7dSKaroly Pados } 2223ba93cc7dSKaroly Pados 222412bdbe03SJim Radford return 0; 2225f353c0d4SJohan Hovold 2226f353c0d4SJohan Hovold err_free: 2227f353c0d4SJohan Hovold kfree(priv); 2228f353c0d4SJohan Hovold 2229f353c0d4SJohan Hovold return result; 22301da177e4SLinus Torvalds } 22311da177e4SLinus Torvalds 22328f977e42SIan Abbott /* Setup for the USB-UIRT device, which requires hardwired 22338f977e42SIan Abbott * baudrate (38400 gets mapped to 312500) */ 22341da177e4SLinus Torvalds /* Called from usbserial:serial_probe */ 22350ffbbe25SOliver Neukum static void ftdi_USB_UIRT_setup(struct ftdi_private *priv) 22361da177e4SLinus Torvalds { 22371da177e4SLinus Torvalds priv->flags |= ASYNC_SPD_CUST; 22381da177e4SLinus Torvalds priv->custom_divisor = 77; 2239669a6db1SAlan Cox priv->force_baud = 38400; 2240e49bbce1SJohan Hovold } 22411da177e4SLinus Torvalds 22428f977e42SIan Abbott /* Setup for the HE-TIRA1 device, which requires hardwired 22438f977e42SIan Abbott * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ 2244464cbb24SAlan Cox 22450ffbbe25SOliver Neukum static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) 22468f977e42SIan Abbott { 22471da177e4SLinus Torvalds priv->flags |= ASYNC_SPD_CUST; 22481da177e4SLinus Torvalds priv->custom_divisor = 240; 2249669a6db1SAlan Cox priv->force_baud = 38400; 22501da177e4SLinus Torvalds priv->force_rtscts = 1; 2251e49bbce1SJohan Hovold } 22521da177e4SLinus Torvalds 2253fa91d43bSTony Lindgren /* 2254b760dac2SMartin Geleynse * Module parameter to control latency timer for NDI FTDI-based USB devices. 2255970e2486SLucas De Marchi * If this value is not set in /etc/modprobe.d/ its value will be set 2256970e2486SLucas De Marchi * to 1ms. 2257b760dac2SMartin Geleynse */ 2258b760dac2SMartin Geleynse static int ndi_latency_timer = 1; 2259b760dac2SMartin Geleynse 2260b760dac2SMartin Geleynse /* Setup for the NDI FTDI-based USB devices, which requires hardwired 2261b760dac2SMartin Geleynse * baudrate (19200 gets mapped to 1200000). 2262b760dac2SMartin Geleynse * 2263b760dac2SMartin Geleynse * Called from usbserial:serial_probe. 2264b760dac2SMartin Geleynse */ 2265b760dac2SMartin Geleynse static int ftdi_NDI_device_setup(struct usb_serial *serial) 2266b760dac2SMartin Geleynse { 2267b760dac2SMartin Geleynse struct usb_device *udev = serial->dev; 2268b760dac2SMartin Geleynse int latency = ndi_latency_timer; 2269b760dac2SMartin Geleynse 2270b760dac2SMartin Geleynse if (latency == 0) 2271b760dac2SMartin Geleynse latency = 1; 2272b760dac2SMartin Geleynse if (latency > 99) 2273b760dac2SMartin Geleynse latency = 99; 2274b760dac2SMartin Geleynse 2275bfc51614SGreg Kroah-Hartman dev_dbg(&udev->dev, "%s setting NDI device latency to %d\n", __func__, latency); 2276bfc51614SGreg Kroah-Hartman dev_info(&udev->dev, "NDI device with a latency value of %d\n", latency); 2277b760dac2SMartin Geleynse 2278c1284d77SJohan Hovold /* FIXME: errors are not returned */ 2279c1284d77SJohan Hovold usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 2280b760dac2SMartin Geleynse FTDI_SIO_SET_LATENCY_TIMER_REQUEST, 2281b760dac2SMartin Geleynse FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, 228266e47e60SJohan Hovold latency, 0, NULL, 0, WDR_TIMEOUT); 2283b760dac2SMartin Geleynse return 0; 2284b760dac2SMartin Geleynse } 2285b760dac2SMartin Geleynse 2286b760dac2SMartin Geleynse /* 228720734345SHarald Welte * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko 228820734345SHarald Welte * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from 228920734345SHarald Welte * userspace using openocd. 2290fa91d43bSTony Lindgren */ 229120734345SHarald Welte static int ftdi_jtag_probe(struct usb_serial *serial) 2292fa91d43bSTony Lindgren { 229375240ac4SJohan Hovold struct usb_interface *intf = serial->interface; 229475240ac4SJohan Hovold int ifnum = intf->cur_altsetting->desc.bInterfaceNumber; 2295fa91d43bSTony Lindgren 229675240ac4SJohan Hovold if (ifnum == 0) { 229775240ac4SJohan Hovold dev_info(&intf->dev, "Ignoring interface reserved for JTAG\n"); 2298fa91d43bSTony Lindgren return -ENODEV; 2299fa91d43bSTony Lindgren } 2300fa91d43bSTony Lindgren 2301fa91d43bSTony Lindgren return 0; 2302fa91d43bSTony Lindgren } 23031da177e4SLinus Torvalds 2304c96fbdd0SJean-Christophe PLAGNIOL-VILLARD static int ftdi_8u2232c_probe(struct usb_serial *serial) 2305c96fbdd0SJean-Christophe PLAGNIOL-VILLARD { 2306c96fbdd0SJean-Christophe PLAGNIOL-VILLARD struct usb_device *udev = serial->dev; 2307c96fbdd0SJean-Christophe PLAGNIOL-VILLARD 2308b229a0f8SDoug Goldstein if (udev->manufacturer && !strcmp(udev->manufacturer, "CALAO Systems")) 2309b229a0f8SDoug Goldstein return ftdi_jtag_probe(serial); 2310b229a0f8SDoug Goldstein 2311b229a0f8SDoug Goldstein if (udev->product && 2312470b5d6fSVasyl Vavrychuk (!strcmp(udev->product, "Arrow USB Blaster") || 2313470b5d6fSVasyl Vavrychuk !strcmp(udev->product, "BeagleBone/XDS100V2") || 2314b229a0f8SDoug Goldstein !strcmp(udev->product, "SNAP Connect E10"))) 2315c96fbdd0SJean-Christophe PLAGNIOL-VILLARD return ftdi_jtag_probe(serial); 2316c96fbdd0SJean-Christophe PLAGNIOL-VILLARD 2317c96fbdd0SJean-Christophe PLAGNIOL-VILLARD return 0; 2318c96fbdd0SJean-Christophe PLAGNIOL-VILLARD } 2319c96fbdd0SJean-Christophe PLAGNIOL-VILLARD 2320546d7eecSKevin Vance /* 232171d9a2b9SAdrian Thomasset * First two ports on JTAG adaptors using an FT4232 such as STMicroelectronics's 232271d9a2b9SAdrian Thomasset * ST Micro Connect Lite are reserved for JTAG or other non-UART interfaces and 232371d9a2b9SAdrian Thomasset * can be accessed from userspace. 232471d9a2b9SAdrian Thomasset * The next two ports are enabled as UARTs by default, where port 2 is 232571d9a2b9SAdrian Thomasset * a conventional RS-232 UART. 23266ec2f46cSJean-Christophe PLAGNIOL-VILLARD */ 23276ec2f46cSJean-Christophe PLAGNIOL-VILLARD static int ftdi_stmclite_probe(struct usb_serial *serial) 23286ec2f46cSJean-Christophe PLAGNIOL-VILLARD { 232975240ac4SJohan Hovold struct usb_interface *intf = serial->interface; 233075240ac4SJohan Hovold int ifnum = intf->cur_altsetting->desc.bInterfaceNumber; 23316ec2f46cSJean-Christophe PLAGNIOL-VILLARD 233275240ac4SJohan Hovold if (ifnum < 2) { 233375240ac4SJohan Hovold dev_info(&intf->dev, "Ignoring interface reserved for JTAG\n"); 23346ec2f46cSJean-Christophe PLAGNIOL-VILLARD return -ENODEV; 23356ec2f46cSJean-Christophe PLAGNIOL-VILLARD } 23366ec2f46cSJean-Christophe PLAGNIOL-VILLARD 233771d9a2b9SAdrian Thomasset return 0; 233871d9a2b9SAdrian Thomasset } 233971d9a2b9SAdrian Thomasset 2340c5d1448fSUwe Kleine-König static void ftdi_sio_port_remove(struct usb_serial_port *port) 234112bdbe03SJim Radford { 23421da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 23431da177e4SLinus Torvalds 2344ba93cc7dSKaroly Pados ftdi_gpio_remove(port); 2345ba93cc7dSKaroly Pados 23464cba98ffSJohan Hovold kfree(priv); 234712bdbe03SJim Radford } 23481da177e4SLinus Torvalds 2349a509a7e4SAlan Cox static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) 2350e49bbce1SJohan Hovold { 23511da177e4SLinus Torvalds struct usb_device *dev = port->serial->dev; 23521da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 23531da177e4SLinus Torvalds 23541da177e4SLinus Torvalds /* No error checking for this (will get errors later anyway) */ 23551da177e4SLinus Torvalds /* See ftdi_sio.h for description of what is reset */ 23561da177e4SLinus Torvalds usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 23571da177e4SLinus Torvalds FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, 23581da177e4SLinus Torvalds FTDI_SIO_RESET_SIO, 2359027bf37dSJohan Hovold priv->channel, NULL, 0, WDR_TIMEOUT); 23601da177e4SLinus Torvalds 23611da177e4SLinus Torvalds /* Termios defaults are set by usb_serial_init. We don't change 2362c4f01240SNick Andrew port->tty->termios - this would lose speed settings, etc. 23631da177e4SLinus Torvalds This is same behaviour as serial.c/rs_open() - Kuba */ 23641da177e4SLinus Torvalds 23651da177e4SLinus Torvalds /* ftdi_set_termios will send usb control messages */ 2366be0278ccSJohan Hovold if (tty) 2367be0278ccSJohan Hovold ftdi_set_termios(tty, port, NULL); 23681da177e4SLinus Torvalds 23694cba98ffSJohan Hovold return usb_serial_generic_open(tty, port); 2370e49bbce1SJohan Hovold } 23711da177e4SLinus Torvalds 2372335f8514SAlan Cox static void ftdi_dtr_rts(struct usb_serial_port *port, int on) 2373335f8514SAlan Cox { 2374335f8514SAlan Cox struct ftdi_private *priv = usb_get_serial_port_data(port); 2375335f8514SAlan Cox 2376335f8514SAlan Cox /* Disable flow control */ 2377b2ca6990SJohan Hovold if (!on) { 2378b2ca6990SJohan Hovold if (usb_control_msg(port->serial->dev, 2379335f8514SAlan Cox usb_sndctrlpipe(port->serial->dev, 0), 2380335f8514SAlan Cox FTDI_SIO_SET_FLOW_CTRL_REQUEST, 2381335f8514SAlan Cox FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 2382027bf37dSJohan Hovold 0, priv->channel, NULL, 0, 2383335f8514SAlan Cox WDR_TIMEOUT) < 0) { 2384335f8514SAlan Cox dev_err(&port->dev, "error from flowcontrol urb\n"); 2385335f8514SAlan Cox } 2386b2ca6990SJohan Hovold } 2387335f8514SAlan Cox /* drop RTS and DTR */ 2388335f8514SAlan Cox if (on) 2389335f8514SAlan Cox set_mctrl(port, TIOCM_DTR | TIOCM_RTS); 2390335f8514SAlan Cox else 2391335f8514SAlan Cox clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); 2392335f8514SAlan Cox } 23931da177e4SLinus Torvalds 23941da177e4SLinus Torvalds /* The SIO requires the first byte to have: 23951da177e4SLinus Torvalds * B0 1 23961da177e4SLinus Torvalds * B1 0 23971da177e4SLinus Torvalds * B2..7 length of message excluding byte 0 23981da177e4SLinus Torvalds * 23991da177e4SLinus Torvalds * The new devices do not require this byte 24001da177e4SLinus Torvalds */ 2401d3901a06SJohan Hovold static int ftdi_prepare_write_buffer(struct usb_serial_port *port, 2402c23e5fc1SJohan Hovold void *dest, size_t size) 2403e49bbce1SJohan Hovold { 2404d3901a06SJohan Hovold struct ftdi_private *priv; 2405c23e5fc1SJohan Hovold int count; 2406c23e5fc1SJohan Hovold unsigned long flags; 24071da177e4SLinus Torvalds 2408d3901a06SJohan Hovold priv = usb_get_serial_port_data(port); 24091da177e4SLinus Torvalds 2410e8770484SJohan Hovold if (priv->chip_type == SIO) { 2411c23e5fc1SJohan Hovold unsigned char *buffer = dest; 2412c23e5fc1SJohan Hovold int i, len, c; 24131da177e4SLinus Torvalds 2414c23e5fc1SJohan Hovold count = 0; 2415c23e5fc1SJohan Hovold spin_lock_irqsave(&port->lock, flags); 2416c23e5fc1SJohan Hovold for (i = 0; i < size - 1; i += priv->max_packet_size) { 2417c23e5fc1SJohan Hovold len = min_t(int, size - i, priv->max_packet_size) - 1; 2418c23e5fc1SJohan Hovold c = kfifo_out(&port->write_fifo, &buffer[i + 1], len); 2419c23e5fc1SJohan Hovold if (!c) 2420c23e5fc1SJohan Hovold break; 2421cb1676a6SJohan Hovold port->icount.tx += c; 2422c1aa075aSJohan Hovold buffer[i] = (c << 2) + 1; 2423c23e5fc1SJohan Hovold count += c + 1; 24241da177e4SLinus Torvalds } 2425c23e5fc1SJohan Hovold spin_unlock_irqrestore(&port->lock, flags); 24261da177e4SLinus Torvalds } else { 2427c23e5fc1SJohan Hovold count = kfifo_out_locked(&port->write_fifo, dest, size, 2428c23e5fc1SJohan Hovold &port->lock); 2429cb1676a6SJohan Hovold port->icount.tx += count; 24301da177e4SLinus Torvalds } 24311da177e4SLinus Torvalds 24321da177e4SLinus Torvalds return count; 243395da310eSAlan Cox } 24341da177e4SLinus Torvalds 2435166ceb69SJohan Hovold #define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE) 2436166ceb69SJohan Hovold 243792a19f9cSJiri Slaby static int ftdi_process_packet(struct usb_serial_port *port, 2438ab4cc4efSJohan Hovold struct ftdi_private *priv, unsigned char *buf, int len) 243995da310eSAlan Cox { 2440ab4cc4efSJohan Hovold unsigned char status; 2441733fff67SJohan Hovold bool brkint = false; 24421da177e4SLinus Torvalds int i; 2443cc01f17dSJohan Hovold char flag; 24441da177e4SLinus Torvalds 2445cc01f17dSJohan Hovold if (len < 2) { 2446bfc51614SGreg Kroah-Hartman dev_dbg(&port->dev, "malformed packet\n"); 2447cc01f17dSJohan Hovold return 0; 24481da177e4SLinus Torvalds } 24491da177e4SLinus Torvalds 2450464cbb24SAlan Cox /* Compare new line status to the old one, signal if different/ 2451464cbb24SAlan Cox N.B. packet may be processed more than once, but differences 2452464cbb24SAlan Cox are only processed once. */ 2453ab4cc4efSJohan Hovold status = buf[0] & FTDI_STATUS_B0_MASK; 2454cc01f17dSJohan Hovold if (status != priv->prev_status) { 2455fca5430dSSimon Arlott char diff_status = status ^ priv->prev_status; 2456fca5430dSSimon Arlott 2457fca5430dSSimon Arlott if (diff_status & FTDI_RS0_CTS) 2458cb1676a6SJohan Hovold port->icount.cts++; 2459fca5430dSSimon Arlott if (diff_status & FTDI_RS0_DSR) 2460cb1676a6SJohan Hovold port->icount.dsr++; 2461fca5430dSSimon Arlott if (diff_status & FTDI_RS0_RI) 2462cb1676a6SJohan Hovold port->icount.rng++; 2463d14654dfSPaul Chavent if (diff_status & FTDI_RS0_RLSD) { 2464d14654dfSPaul Chavent struct tty_struct *tty; 2465d14654dfSPaul Chavent 2466cb1676a6SJohan Hovold port->icount.dcd++; 2467d14654dfSPaul Chavent tty = tty_port_tty_get(&port->port); 2468d14654dfSPaul Chavent if (tty) 2469d14654dfSPaul Chavent usb_serial_handle_dcd_change(port, tty, 2470d14654dfSPaul Chavent status & FTDI_RS0_RLSD); 2471d14654dfSPaul Chavent tty_kref_put(tty); 2472d14654dfSPaul Chavent } 2473fca5430dSSimon Arlott 2474f307e5cdSJohan Hovold wake_up_interruptible(&port->port.delta_msr_wait); 2475cc01f17dSJohan Hovold priv->prev_status = status; 24761da177e4SLinus Torvalds } 24771da177e4SLinus Torvalds 2478a6bb1e17SJohan Hovold /* save if the transmitter is empty or not */ 2479ab4cc4efSJohan Hovold if (buf[1] & FTDI_RS_TEMT) 2480a6bb1e17SJohan Hovold priv->transmit_empty = 1; 2481a6bb1e17SJohan Hovold else 2482a6bb1e17SJohan Hovold priv->transmit_empty = 0; 2483a6bb1e17SJohan Hovold 2484ce054039SJohan Hovold if (len == 2) 2485a6bb1e17SJohan Hovold return 0; /* status only */ 2486a6bb1e17SJohan Hovold 2487a6bb1e17SJohan Hovold /* 2488a6bb1e17SJohan Hovold * Break and error status must only be processed for packets with 2489a6bb1e17SJohan Hovold * data payload to avoid over-reporting. 2490a6bb1e17SJohan Hovold */ 2491cc01f17dSJohan Hovold flag = TTY_NORMAL; 2492ab4cc4efSJohan Hovold if (buf[1] & FTDI_RS_ERR_MASK) { 2493733fff67SJohan Hovold /* 2494733fff67SJohan Hovold * Break takes precedence over parity, which takes precedence 2495733fff67SJohan Hovold * over framing errors. Note that break is only associated 2496733fff67SJohan Hovold * with the last character in the buffer and only when it's a 2497733fff67SJohan Hovold * NUL. 2498733fff67SJohan Hovold */ 2499733fff67SJohan Hovold if (buf[1] & FTDI_RS_BI && buf[len - 1] == '\0') { 2500cb1676a6SJohan Hovold port->icount.brk++; 2501733fff67SJohan Hovold brkint = true; 2502733fff67SJohan Hovold } 2503733fff67SJohan Hovold if (buf[1] & FTDI_RS_PE) { 2504cc01f17dSJohan Hovold flag = TTY_PARITY; 2505cb1676a6SJohan Hovold port->icount.parity++; 2506ab4cc4efSJohan Hovold } else if (buf[1] & FTDI_RS_FE) { 2507cc01f17dSJohan Hovold flag = TTY_FRAME; 2508cb1676a6SJohan Hovold port->icount.frame++; 2509166ceb69SJohan Hovold } 2510166ceb69SJohan Hovold /* Overrun is special, not associated with a char */ 2511ab4cc4efSJohan Hovold if (buf[1] & FTDI_RS_OE) { 2512cb1676a6SJohan Hovold port->icount.overrun++; 251392a19f9cSJiri Slaby tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); 25141da177e4SLinus Torvalds } 2515005b3cdeSUwe Bonnes } 25161da177e4SLinus Torvalds 2517ce054039SJohan Hovold port->icount.rx += len - 2; 2518cc01f17dSJohan Hovold 251937ae2315SJohan Hovold if (brkint || port->sysrq) { 2520ce054039SJohan Hovold for (i = 2; i < len; i++) { 2521733fff67SJohan Hovold if (brkint && i == len - 1) { 2522733fff67SJohan Hovold if (usb_serial_handle_break(port)) 2523733fff67SJohan Hovold return len - 3; 2524733fff67SJohan Hovold flag = TTY_BREAK; 2525733fff67SJohan Hovold } 2526ce054039SJohan Hovold if (usb_serial_handle_sysrq_char(port, buf[i])) 2527ce054039SJohan Hovold continue; 2528ce054039SJohan Hovold tty_insert_flip_char(&port->port, buf[i], flag); 2529cc01f17dSJohan Hovold } 253049b2597aSJohan Hovold } else { 2531ce054039SJohan Hovold tty_insert_flip_string_fixed_flag(&port->port, buf + 2, flag, 2532ce054039SJohan Hovold len - 2); 2533cc01f17dSJohan Hovold } 253449b2597aSJohan Hovold 2535ce054039SJohan Hovold return len - 2; 2536cc01f17dSJohan Hovold } 2537cc01f17dSJohan Hovold 25381b551015SJohan Hovold static void ftdi_process_read_urb(struct urb *urb) 2539cc01f17dSJohan Hovold { 25401b551015SJohan Hovold struct usb_serial_port *port = urb->context; 2541cc01f17dSJohan Hovold struct ftdi_private *priv = usb_get_serial_port_data(port); 2542eb0c68eaSJohan Hovold char *data = urb->transfer_buffer; 2543cc01f17dSJohan Hovold int i; 2544cc01f17dSJohan Hovold int len; 2545cc01f17dSJohan Hovold int count = 0; 2546cc01f17dSJohan Hovold 2547cc01f17dSJohan Hovold for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { 2548cc01f17dSJohan Hovold len = min_t(int, urb->actual_length - i, priv->max_packet_size); 254992a19f9cSJiri Slaby count += ftdi_process_packet(port, priv, &data[i], len); 2550cc01f17dSJohan Hovold } 2551cc01f17dSJohan Hovold 2552cc01f17dSJohan Hovold if (count) 25532e124b4aSJiri Slaby tty_flip_buffer_push(&port->port); 2554cc01f17dSJohan Hovold } 25551da177e4SLinus Torvalds 255695da310eSAlan Cox static void ftdi_break_ctl(struct tty_struct *tty, int break_state) 25571da177e4SLinus Torvalds { 255895da310eSAlan Cox struct usb_serial_port *port = tty->driver_data; 25591da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 256016410115SJohan Hovold u16 value; 25611da177e4SLinus Torvalds 25621da177e4SLinus Torvalds /* break_state = -1 to turn on break, and 0 to turn off break */ 25631da177e4SLinus Torvalds /* see drivers/char/tty_io.c to see it used */ 256416410115SJohan Hovold /* last_set_data_value NEVER has the break bit set in it */ 25651da177e4SLinus Torvalds 2566464cbb24SAlan Cox if (break_state) 256716410115SJohan Hovold value = priv->last_set_data_value | FTDI_SIO_SET_BREAK; 2568464cbb24SAlan Cox else 256916410115SJohan Hovold value = priv->last_set_data_value; 25701da177e4SLinus Torvalds 2571464cbb24SAlan Cox if (usb_control_msg(port->serial->dev, 2572464cbb24SAlan Cox usb_sndctrlpipe(port->serial->dev, 0), 25731da177e4SLinus Torvalds FTDI_SIO_SET_DATA_REQUEST, 25741da177e4SLinus Torvalds FTDI_SIO_SET_DATA_REQUEST_TYPE, 2575027bf37dSJohan Hovold value, priv->channel, 257666e47e60SJohan Hovold NULL, 0, WDR_TIMEOUT) < 0) { 2577bfc51614SGreg Kroah-Hartman dev_err(&port->dev, "%s FAILED to enable/disable break state (state was %d)\n", 2578bfc51614SGreg Kroah-Hartman __func__, break_state); 25791da177e4SLinus Torvalds } 25801da177e4SLinus Torvalds 2581bfc51614SGreg Kroah-Hartman dev_dbg(&port->dev, "%s break state is %d - urb is %d\n", __func__, 258216410115SJohan Hovold break_state, value); 25831da177e4SLinus Torvalds 25841da177e4SLinus Torvalds } 25851da177e4SLinus Torvalds 2586a37025b5SJohan Hovold static bool ftdi_tx_empty(struct usb_serial_port *port) 25876f602912SJarkko Huijts { 25885fb0432eSJohan Hovold unsigned char buf[2]; 25896f602912SJarkko Huijts int ret; 25906f602912SJarkko Huijts 2591c4133648SJohan Hovold ret = ftdi_get_modem_status(port, buf); 25925fb0432eSJohan Hovold if (ret == 2) { 25936f602912SJarkko Huijts if (!(buf[1] & FTDI_RS_TEMT)) 2594a37025b5SJohan Hovold return false; 25955fb0432eSJohan Hovold } 25966f602912SJarkko Huijts 2597a37025b5SJohan Hovold return true; 25986f602912SJarkko Huijts } 25996f602912SJarkko Huijts 26001da177e4SLinus Torvalds /* old_termios contains the original termios settings and tty->termios contains 26011da177e4SLinus Torvalds * the new setting to be used 26021da177e4SLinus Torvalds * WARNING: set_termios calls this with old_termios in kernel space 26031da177e4SLinus Torvalds */ 260495da310eSAlan Cox static void ftdi_set_termios(struct tty_struct *tty, 260595da310eSAlan Cox struct usb_serial_port *port, struct ktermios *old_termios) 2606e49bbce1SJohan Hovold { 26071da177e4SLinus Torvalds struct usb_device *dev = port->serial->dev; 2608bfc51614SGreg Kroah-Hartman struct device *ddev = &port->dev; 26091da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 2610adc8d746SAlan Cox struct ktermios *termios = &tty->termios; 2611669a6db1SAlan Cox unsigned int cflag = termios->c_cflag; 2612df1cd63dSJohan Hovold u16 value, index; 2613df1cd63dSJohan Hovold int ret; 26141da177e4SLinus Torvalds 2615464cbb24SAlan Cox /* Force baud rate if this device requires it, unless it is set to 2616464cbb24SAlan Cox B0. */ 2617669a6db1SAlan Cox if (priv->force_baud && ((termios->c_cflag & CBAUD) != B0)) { 2618bfc51614SGreg Kroah-Hartman dev_dbg(ddev, "%s: forcing baud rate for this device\n", __func__); 261995da310eSAlan Cox tty_encode_baud_rate(tty, priv->force_baud, 2620bd5e47ccSAndrew Morton priv->force_baud); 26211da177e4SLinus Torvalds } 26221da177e4SLinus Torvalds 26231da177e4SLinus Torvalds /* Force RTS-CTS if this device requires it. */ 26241da177e4SLinus Torvalds if (priv->force_rtscts) { 2625bfc51614SGreg Kroah-Hartman dev_dbg(ddev, "%s: forcing rtscts for this device\n", __func__); 2626669a6db1SAlan Cox termios->c_cflag |= CRTSCTS; 26271da177e4SLinus Torvalds } 26281da177e4SLinus Torvalds 26298704211fSColin Leitner /* 2630c1f15196SColin Leitner * All FTDI UART chips are limited to CS7/8. We shouldn't pretend to 26318704211fSColin Leitner * support CS5/6 and revert the CSIZE setting instead. 2632c1f15196SColin Leitner * 2633c1f15196SColin Leitner * CS5 however is used to control some smartcard readers which abuse 2634c1f15196SColin Leitner * this limitation to switch modes. Original FTDI chips fall back to 2635c1f15196SColin Leitner * eight data bits. 2636c1f15196SColin Leitner * 2637c1f15196SColin Leitner * TODO: Implement a quirk to only allow this with mentioned 2638c1f15196SColin Leitner * readers. One I know of (Argolis Smartreader V1) 2639c1f15196SColin Leitner * returns "USB smartcard server" as iInterface string. 2640c1f15196SColin Leitner * The vendor didn't bother with a custom VID/PID of 2641c1f15196SColin Leitner * course. 26428704211fSColin Leitner */ 2643c1f15196SColin Leitner if (C_CSIZE(tty) == CS6) { 26448704211fSColin Leitner dev_warn(ddev, "requested CSIZE setting not supported\n"); 26458704211fSColin Leitner 26468704211fSColin Leitner termios->c_cflag &= ~CSIZE; 26478704211fSColin Leitner if (old_termios) 26488704211fSColin Leitner termios->c_cflag |= old_termios->c_cflag & CSIZE; 26498704211fSColin Leitner else 26508704211fSColin Leitner termios->c_cflag |= CS8; 26518704211fSColin Leitner } 26528704211fSColin Leitner 2653669a6db1SAlan Cox cflag = termios->c_cflag; 26541da177e4SLinus Torvalds 2655a816e311SYing Xue if (!old_termios) 2656c515598eSAndrew Worsley goto no_skip; 2657c515598eSAndrew Worsley 2658b1ffb4c8SAndrew Worsley if (old_termios->c_cflag == termios->c_cflag 2659b1ffb4c8SAndrew Worsley && old_termios->c_ispeed == termios->c_ispeed 2660b1ffb4c8SAndrew Worsley && old_termios->c_ospeed == termios->c_ospeed) 2661b1ffb4c8SAndrew Worsley goto no_c_cflag_changes; 2662b1ffb4c8SAndrew Worsley 26631da177e4SLinus Torvalds /* NOTE These routines can get interrupted by 2664464cbb24SAlan Cox ftdi_sio_read_bulk_callback - need to examine what this means - 2665464cbb24SAlan Cox don't see any problems yet */ 26661da177e4SLinus Torvalds 2667b1ffb4c8SAndrew Worsley if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) == 2668b1ffb4c8SAndrew Worsley (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB))) 2669b1ffb4c8SAndrew Worsley goto no_data_parity_stop_changes; 2670b1ffb4c8SAndrew Worsley 2671c515598eSAndrew Worsley no_skip: 26721da177e4SLinus Torvalds /* Set number of data bits, parity, stop bits */ 26731da177e4SLinus Torvalds 267416410115SJohan Hovold value = 0; 267516410115SJohan Hovold value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : 26761da177e4SLinus Torvalds FTDI_SIO_SET_DATA_STOP_BITS_1); 267738fcb830SRoland Koebler if (cflag & PARENB) { 267838fcb830SRoland Koebler if (cflag & CMSPAR) 267916410115SJohan Hovold value |= cflag & PARODD ? 268038fcb830SRoland Koebler FTDI_SIO_SET_DATA_PARITY_MARK : 268138fcb830SRoland Koebler FTDI_SIO_SET_DATA_PARITY_SPACE; 268238fcb830SRoland Koebler else 268316410115SJohan Hovold value |= cflag & PARODD ? 268438fcb830SRoland Koebler FTDI_SIO_SET_DATA_PARITY_ODD : 268538fcb830SRoland Koebler FTDI_SIO_SET_DATA_PARITY_EVEN; 268638fcb830SRoland Koebler } else { 268716410115SJohan Hovold value |= FTDI_SIO_SET_DATA_PARITY_NONE; 268838fcb830SRoland Koebler } 26891da177e4SLinus Torvalds switch (cflag & CSIZE) { 2690c1f15196SColin Leitner case CS5: 2691c1f15196SColin Leitner dev_dbg(ddev, "Setting CS5 quirk\n"); 2692c1f15196SColin Leitner break; 2693bfc51614SGreg Kroah-Hartman case CS7: 269416410115SJohan Hovold value |= 7; 2695bfc51614SGreg Kroah-Hartman dev_dbg(ddev, "Setting CS7\n"); 2696bfc51614SGreg Kroah-Hartman break; 26978704211fSColin Leitner default: 2698bfc51614SGreg Kroah-Hartman case CS8: 269916410115SJohan Hovold value |= 8; 2700bfc51614SGreg Kroah-Hartman dev_dbg(ddev, "Setting CS8\n"); 2701bfc51614SGreg Kroah-Hartman break; 27021da177e4SLinus Torvalds } 27031da177e4SLinus Torvalds 2704464cbb24SAlan Cox /* This is needed by the break command since it uses the same command 2705464cbb24SAlan Cox - but is or'ed with this value */ 270616410115SJohan Hovold priv->last_set_data_value = value; 27071da177e4SLinus Torvalds 27081da177e4SLinus Torvalds if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 27091da177e4SLinus Torvalds FTDI_SIO_SET_DATA_REQUEST, 27101da177e4SLinus Torvalds FTDI_SIO_SET_DATA_REQUEST_TYPE, 2711027bf37dSJohan Hovold value, priv->channel, 271266e47e60SJohan Hovold NULL, 0, WDR_SHORT_TIMEOUT) < 0) { 2713bfc51614SGreg Kroah-Hartman dev_err(ddev, "%s FAILED to set databits/stopbits/parity\n", 2714bfc51614SGreg Kroah-Hartman __func__); 27151da177e4SLinus Torvalds } 27161da177e4SLinus Torvalds 27171da177e4SLinus Torvalds /* Now do the baudrate */ 2718b1ffb4c8SAndrew Worsley no_data_parity_stop_changes: 27191da177e4SLinus Torvalds if ((cflag & CBAUD) == B0) { 27201da177e4SLinus Torvalds /* Disable flow control */ 27211da177e4SLinus Torvalds if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 27221da177e4SLinus Torvalds FTDI_SIO_SET_FLOW_CTRL_REQUEST, 27231da177e4SLinus Torvalds FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 2724027bf37dSJohan Hovold 0, priv->channel, 272566e47e60SJohan Hovold NULL, 0, WDR_TIMEOUT) < 0) { 2726bfc51614SGreg Kroah-Hartman dev_err(ddev, "%s error from disable flowcontrol urb\n", 2727194343d9SGreg Kroah-Hartman __func__); 27281da177e4SLinus Torvalds } 27291da177e4SLinus Torvalds /* Drop RTS and DTR */ 273074ede0ffSIan Abbott clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); 27311da177e4SLinus Torvalds } else { 27321da177e4SLinus Torvalds /* set the baudrate determined before */ 27339c67d28eSAlessio Igor Bogani mutex_lock(&priv->cfg_lock); 2734464cbb24SAlan Cox if (change_speed(tty, port)) 2735bfc51614SGreg Kroah-Hartman dev_err(ddev, "%s urb failed to set baudrate\n", __func__); 27369c67d28eSAlessio Igor Bogani mutex_unlock(&priv->cfg_lock); 273772a755fcSPeter Favrholdt /* Ensure RTS and DTR are raised when baudrate changed from 0 */ 27383177130fSJohan Hovold if (old_termios && (old_termios->c_cflag & CBAUD) == B0) 273974ede0ffSIan Abbott set_mctrl(port, TIOCM_DTR | TIOCM_RTS); 27401da177e4SLinus Torvalds } 27411da177e4SLinus Torvalds 2742b1ffb4c8SAndrew Worsley no_c_cflag_changes: 2743df1cd63dSJohan Hovold /* Set hardware-assisted flow control */ 2744df1cd63dSJohan Hovold value = 0; 27451da177e4SLinus Torvalds 2746df1cd63dSJohan Hovold if (C_CRTSCTS(tty)) { 2747df1cd63dSJohan Hovold dev_dbg(&port->dev, "enabling rts/cts flow control\n"); 2748df1cd63dSJohan Hovold index = FTDI_SIO_RTS_CTS_HS; 2749df1cd63dSJohan Hovold } else if (I_IXON(tty)) { 2750df1cd63dSJohan Hovold dev_dbg(&port->dev, "enabling xon/xoff flow control\n"); 2751df1cd63dSJohan Hovold index = FTDI_SIO_XON_XOFF_HS; 2752df1cd63dSJohan Hovold value = STOP_CHAR(tty) << 8 | START_CHAR(tty); 27531da177e4SLinus Torvalds } else { 2754df1cd63dSJohan Hovold dev_dbg(&port->dev, "disabling flow control\n"); 2755df1cd63dSJohan Hovold index = FTDI_SIO_DISABLE_FLOW_CTRL; 2756df1cd63dSJohan Hovold } 2757df1cd63dSJohan Hovold 2758027bf37dSJohan Hovold index |= priv->channel; 2759df1cd63dSJohan Hovold 2760df1cd63dSJohan Hovold ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 27611da177e4SLinus Torvalds FTDI_SIO_SET_FLOW_CTRL_REQUEST, 27621da177e4SLinus Torvalds FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 2763df1cd63dSJohan Hovold value, index, NULL, 0, WDR_TIMEOUT); 2764df1cd63dSJohan Hovold if (ret < 0) 2765df1cd63dSJohan Hovold dev_err(&port->dev, "failed to set flow control: %d\n", ret); 276695da310eSAlan Cox } 27671da177e4SLinus Torvalds 2768a4afff6bSJohan Hovold /* 2769a4afff6bSJohan Hovold * Get modem-control status. 2770a4afff6bSJohan Hovold * 2771a4afff6bSJohan Hovold * Returns the number of status bytes retrieved (device dependant), or 2772a4afff6bSJohan Hovold * negative error code. 2773a4afff6bSJohan Hovold */ 2774c4133648SJohan Hovold static int ftdi_get_modem_status(struct usb_serial_port *port, 2775a4afff6bSJohan Hovold unsigned char status[2]) 27761da177e4SLinus Torvalds { 27771da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 277866e47e60SJohan Hovold unsigned char *buf; 2779a3f8168bSJohan Hovold int len; 27801da177e4SLinus Torvalds int ret; 27811da177e4SLinus Torvalds 278266e47e60SJohan Hovold buf = kmalloc(2, GFP_KERNEL); 278366e47e60SJohan Hovold if (!buf) 278466e47e60SJohan Hovold return -ENOMEM; 2785a3f8168bSJohan Hovold /* 27866fbd9142SJohan Hovold * The device returns a two byte value (the SIO a 1 byte value) in the 27876fbd9142SJohan Hovold * same format as the data returned from the IN endpoint. 2788a3f8168bSJohan Hovold */ 27896fbd9142SJohan Hovold if (priv->chip_type == SIO) 2790a3f8168bSJohan Hovold len = 1; 27916fbd9142SJohan Hovold else 2792a3f8168bSJohan Hovold len = 2; 27931da177e4SLinus Torvalds 2794a3f8168bSJohan Hovold ret = usb_control_msg(port->serial->dev, 2795a3f8168bSJohan Hovold usb_rcvctrlpipe(port->serial->dev, 0), 2796a3f8168bSJohan Hovold FTDI_SIO_GET_MODEM_STATUS_REQUEST, 2797a3f8168bSJohan Hovold FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, 2798027bf37dSJohan Hovold 0, priv->channel, 2799a3f8168bSJohan Hovold buf, len, WDR_TIMEOUT); 2800427c3a95SJohan Hovold 2801427c3a95SJohan Hovold /* NOTE: We allow short responses and handle that below. */ 2802427c3a95SJohan Hovold if (ret < 1) { 2803a4afff6bSJohan Hovold dev_err(&port->dev, "failed to get modem status: %d\n", ret); 2804427c3a95SJohan Hovold if (ret >= 0) 2805427c3a95SJohan Hovold ret = -EIO; 28062c2ee545SJohan Hovold ret = usb_translate_errors(ret); 2807a3f8168bSJohan Hovold goto out; 28082c2ee545SJohan Hovold } 2809a3f8168bSJohan Hovold 2810a4afff6bSJohan Hovold status[0] = buf[0]; 2811a4afff6bSJohan Hovold if (ret > 1) 2812a4afff6bSJohan Hovold status[1] = buf[1]; 2813a4afff6bSJohan Hovold else 2814a4afff6bSJohan Hovold status[1] = 0; 2815a4afff6bSJohan Hovold 2816a4afff6bSJohan Hovold dev_dbg(&port->dev, "%s - 0x%02x%02x\n", __func__, status[0], 2817a4afff6bSJohan Hovold status[1]); 2818a4afff6bSJohan Hovold out: 2819a4afff6bSJohan Hovold kfree(buf); 2820a4afff6bSJohan Hovold 2821a4afff6bSJohan Hovold return ret; 2822a4afff6bSJohan Hovold } 2823a4afff6bSJohan Hovold 2824a4afff6bSJohan Hovold static int ftdi_tiocmget(struct tty_struct *tty) 2825a4afff6bSJohan Hovold { 2826a4afff6bSJohan Hovold struct usb_serial_port *port = tty->driver_data; 2827a4afff6bSJohan Hovold struct ftdi_private *priv = usb_get_serial_port_data(port); 2828a4afff6bSJohan Hovold unsigned char buf[2]; 2829a4afff6bSJohan Hovold int ret; 2830a4afff6bSJohan Hovold 2831c4133648SJohan Hovold ret = ftdi_get_modem_status(port, buf); 2832a4afff6bSJohan Hovold if (ret < 0) 2833a4afff6bSJohan Hovold return ret; 2834a4afff6bSJohan Hovold 283566e47e60SJohan Hovold ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | 28361da177e4SLinus Torvalds (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | 28371da177e4SLinus Torvalds (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | 28381da177e4SLinus Torvalds (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | 28391da177e4SLinus Torvalds priv->last_dtr_rts; 2840a4afff6bSJohan Hovold 284166e47e60SJohan Hovold return ret; 28421da177e4SLinus Torvalds } 28431da177e4SLinus Torvalds 284420b9d177SAlan Cox static int ftdi_tiocmset(struct tty_struct *tty, 284595da310eSAlan Cox unsigned int set, unsigned int clear) 28461da177e4SLinus Torvalds { 284795da310eSAlan Cox struct usb_serial_port *port = tty->driver_data; 2848a09aa7ddSGreg Kroah-Hartman 284974ede0ffSIan Abbott return update_mctrl(port, set, clear); 28501da177e4SLinus Torvalds } 28511da177e4SLinus Torvalds 285200a0d0d6SAlan Cox static int ftdi_ioctl(struct tty_struct *tty, 2853464cbb24SAlan Cox unsigned int cmd, unsigned long arg) 28541da177e4SLinus Torvalds { 285595da310eSAlan Cox struct usb_serial_port *port = tty->driver_data; 285659556608SJohan Hovold void __user *argp = (void __user *)arg; 28571da177e4SLinus Torvalds 28581da177e4SLinus Torvalds switch (cmd) { 2859c466cd2bSGreg Kroah-Hartman case TIOCSERGETLSR: 286059556608SJohan Hovold return get_lsr_info(port, argp); 28611da177e4SLinus Torvalds default: 28621da177e4SLinus Torvalds break; 28631da177e4SLinus Torvalds } 28644d5147ecSJohan Hovold 286595da310eSAlan Cox return -ENOIOCTLCMD; 286695da310eSAlan Cox } 28671da177e4SLinus Torvalds 2868*a8619505SJohan Hovold static struct usb_serial_driver ftdi_sio_device = { 2869*a8619505SJohan Hovold .driver = { 2870*a8619505SJohan Hovold .owner = THIS_MODULE, 2871*a8619505SJohan Hovold .name = "ftdi_sio", 2872*a8619505SJohan Hovold .dev_groups = ftdi_groups, 2873*a8619505SJohan Hovold }, 2874*a8619505SJohan Hovold .description = "FTDI USB Serial Device", 2875*a8619505SJohan Hovold .id_table = id_table_combined, 2876*a8619505SJohan Hovold .num_ports = 1, 2877*a8619505SJohan Hovold .bulk_in_size = 512, 2878*a8619505SJohan Hovold .bulk_out_size = 256, 2879*a8619505SJohan Hovold .probe = ftdi_sio_probe, 2880*a8619505SJohan Hovold .port_probe = ftdi_sio_port_probe, 2881*a8619505SJohan Hovold .port_remove = ftdi_sio_port_remove, 2882*a8619505SJohan Hovold .open = ftdi_open, 2883*a8619505SJohan Hovold .dtr_rts = ftdi_dtr_rts, 2884*a8619505SJohan Hovold .throttle = usb_serial_generic_throttle, 2885*a8619505SJohan Hovold .unthrottle = usb_serial_generic_unthrottle, 2886*a8619505SJohan Hovold .process_read_urb = ftdi_process_read_urb, 2887*a8619505SJohan Hovold .prepare_write_buffer = ftdi_prepare_write_buffer, 2888*a8619505SJohan Hovold .tiocmget = ftdi_tiocmget, 2889*a8619505SJohan Hovold .tiocmset = ftdi_tiocmset, 2890*a8619505SJohan Hovold .tiocmiwait = usb_serial_generic_tiocmiwait, 2891*a8619505SJohan Hovold .get_icount = usb_serial_generic_get_icount, 2892*a8619505SJohan Hovold .ioctl = ftdi_ioctl, 2893*a8619505SJohan Hovold .get_serial = get_serial_info, 2894*a8619505SJohan Hovold .set_serial = set_serial_info, 2895*a8619505SJohan Hovold .set_termios = ftdi_set_termios, 2896*a8619505SJohan Hovold .break_ctl = ftdi_break_ctl, 2897*a8619505SJohan Hovold .tx_empty = ftdi_tx_empty, 2898*a8619505SJohan Hovold }; 2899*a8619505SJohan Hovold 2900*a8619505SJohan Hovold static struct usb_serial_driver * const serial_drivers[] = { 2901*a8619505SJohan Hovold &ftdi_sio_device, NULL 2902*a8619505SJohan Hovold }; 2903e17c1aa2SJohan Hovold module_usb_serial_driver(serial_drivers, id_table_combined); 29041da177e4SLinus Torvalds 29051da177e4SLinus Torvalds MODULE_AUTHOR(DRIVER_AUTHOR); 29061da177e4SLinus Torvalds MODULE_DESCRIPTION(DRIVER_DESC); 29071da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 29081da177e4SLinus Torvalds 2909a65ab973SUtkarsh Verma module_param(ndi_latency_timer, int, 0644); 2910b760dac2SMartin Geleynse MODULE_PARM_DESC(ndi_latency_timer, "NDI device latency timer override"); 2911