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 11111da177e4SLinus Torvalds /* function prototypes for a FTDI serial converter */ 1112464cbb24SAlan Cox static int ftdi_sio_probe(struct usb_serial *serial, 1113464cbb24SAlan Cox const struct usb_device_id *id); 111412bdbe03SJim Radford static int ftdi_sio_port_probe(struct usb_serial_port *port); 1115c5d1448fSUwe Kleine-König static void ftdi_sio_port_remove(struct usb_serial_port *port); 1116a509a7e4SAlan Cox static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port); 1117335f8514SAlan Cox static void ftdi_dtr_rts(struct usb_serial_port *port, int on); 11181b551015SJohan Hovold static void ftdi_process_read_urb(struct urb *urb); 1119d3901a06SJohan Hovold static int ftdi_prepare_write_buffer(struct usb_serial_port *port, 1120c23e5fc1SJohan Hovold void *dest, size_t size); 1121464cbb24SAlan Cox static void ftdi_set_termios(struct tty_struct *tty, 1122464cbb24SAlan Cox struct usb_serial_port *port, struct ktermios *old); 112360b33c13SAlan Cox static int ftdi_tiocmget(struct tty_struct *tty); 112420b9d177SAlan Cox static int ftdi_tiocmset(struct tty_struct *tty, 1125464cbb24SAlan Cox unsigned int set, unsigned int clear); 112600a0d0d6SAlan Cox static int ftdi_ioctl(struct tty_struct *tty, 1127464cbb24SAlan Cox unsigned int cmd, unsigned long arg); 112801fd45f6SJohan Hovold static void get_serial_info(struct tty_struct *tty, struct serial_struct *ss); 11293ae36bedSAl Viro static int set_serial_info(struct tty_struct *tty, 11303ae36bedSAl Viro struct serial_struct *ss); 113195da310eSAlan Cox static void ftdi_break_ctl(struct tty_struct *tty, int break_state); 1132a37025b5SJohan Hovold static bool ftdi_tx_empty(struct usb_serial_port *port); 1133c4133648SJohan Hovold static int ftdi_get_modem_status(struct usb_serial_port *port, 11345fb0432eSJohan Hovold unsigned char status[2]); 11351da177e4SLinus Torvalds 11361da177e4SLinus Torvalds static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base); 11371da177e4SLinus Torvalds static unsigned short int ftdi_232am_baud_to_divisor(int baud); 1138fd54a99aSJohan Hovold static u32 ftdi_232bm_baud_base_to_divisor(int baud, int base); 1139fd54a99aSJohan Hovold static u32 ftdi_232bm_baud_to_divisor(int baud); 1140fd54a99aSJohan Hovold static u32 ftdi_2232h_baud_base_to_divisor(int baud, int base); 1141fd54a99aSJohan Hovold static u32 ftdi_2232h_baud_to_divisor(int baud); 11421da177e4SLinus Torvalds 1143*0f6632e2SJiasheng Jiang static const struct attribute_group *ftdi_groups[]; 1144*0f6632e2SJiasheng Jiang 1145ea65370dSGreg Kroah-Hartman static struct usb_serial_driver ftdi_sio_device = { 114618fcac35SGreg Kroah-Hartman .driver = { 11471da177e4SLinus Torvalds .owner = THIS_MODULE, 1148269bda1cSGreg Kroah-Hartman .name = "ftdi_sio", 1149*0f6632e2SJiasheng Jiang .dev_groups = ftdi_groups, 115018fcac35SGreg Kroah-Hartman }, 1151269bda1cSGreg Kroah-Hartman .description = "FTDI USB Serial Device", 11528f977e42SIan Abbott .id_table = id_table_combined, 11531da177e4SLinus Torvalds .num_ports = 1, 1154bbcb2b90SJohan Hovold .bulk_in_size = 512, 1155c23e5fc1SJohan Hovold .bulk_out_size = 256, 11568f977e42SIan Abbott .probe = ftdi_sio_probe, 115712bdbe03SJim Radford .port_probe = ftdi_sio_port_probe, 115812bdbe03SJim Radford .port_remove = ftdi_sio_port_remove, 11591da177e4SLinus Torvalds .open = ftdi_open, 1160335f8514SAlan Cox .dtr_rts = ftdi_dtr_rts, 11611b551015SJohan Hovold .throttle = usb_serial_generic_throttle, 11621b551015SJohan Hovold .unthrottle = usb_serial_generic_unthrottle, 11631b551015SJohan Hovold .process_read_urb = ftdi_process_read_urb, 1164d3901a06SJohan Hovold .prepare_write_buffer = ftdi_prepare_write_buffer, 11651da177e4SLinus Torvalds .tiocmget = ftdi_tiocmget, 11661da177e4SLinus Torvalds .tiocmset = ftdi_tiocmset, 1167f307e5cdSJohan Hovold .tiocmiwait = usb_serial_generic_tiocmiwait, 11686f86fec9SJohan Hovold .get_icount = usb_serial_generic_get_icount, 11691da177e4SLinus Torvalds .ioctl = ftdi_ioctl, 11703ae36bedSAl Viro .get_serial = get_serial_info, 11713ae36bedSAl Viro .set_serial = set_serial_info, 11721da177e4SLinus Torvalds .set_termios = ftdi_set_termios, 11731da177e4SLinus Torvalds .break_ctl = ftdi_break_ctl, 1174a37025b5SJohan Hovold .tx_empty = ftdi_tx_empty, 11751da177e4SLinus Torvalds }; 11761da177e4SLinus Torvalds 117797b6b6d2SAlan Stern static struct usb_serial_driver * const serial_drivers[] = { 117897b6b6d2SAlan Stern &ftdi_sio_device, NULL 117997b6b6d2SAlan Stern }; 118097b6b6d2SAlan Stern 11811da177e4SLinus Torvalds 11821da177e4SLinus Torvalds #define WDR_TIMEOUT 5000 /* default urb timeout */ 1183279e1545SIan Abbott #define WDR_SHORT_TIMEOUT 1000 /* shorter urb timeout */ 11841da177e4SLinus Torvalds 11851da177e4SLinus Torvalds /* 11861da177e4SLinus Torvalds * *************************************************************************** 1187fa91d43bSTony Lindgren * Utility functions 11881da177e4SLinus Torvalds * *************************************************************************** 11891da177e4SLinus Torvalds */ 11901da177e4SLinus Torvalds 11911da177e4SLinus Torvalds static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base) 11921da177e4SLinus Torvalds { 11931da177e4SLinus Torvalds unsigned short int divisor; 1194464cbb24SAlan Cox /* divisor shifted 3 bits to the left */ 11956abd8371SNikolaj Fogh int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud); 1196464cbb24SAlan Cox if ((divisor3 & 0x7) == 7) 1197464cbb24SAlan Cox divisor3++; /* round x.7/8 up to x+1 */ 11981da177e4SLinus Torvalds divisor = divisor3 >> 3; 11991da177e4SLinus Torvalds divisor3 &= 0x7; 1200464cbb24SAlan Cox if (divisor3 == 1) 12011ef26803SJohan Hovold divisor |= 0xc000; /* +0.125 */ 1202464cbb24SAlan Cox else if (divisor3 >= 4) 12031ef26803SJohan Hovold divisor |= 0x4000; /* +0.5 */ 1204464cbb24SAlan Cox else if (divisor3 != 0) 12051ef26803SJohan Hovold divisor |= 0x8000; /* +0.25 */ 1206464cbb24SAlan Cox else if (divisor == 1) 1207464cbb24SAlan Cox divisor = 0; /* special case for maximum baud rate */ 12081da177e4SLinus Torvalds return divisor; 12091da177e4SLinus Torvalds } 12101da177e4SLinus Torvalds 12111da177e4SLinus Torvalds static unsigned short int ftdi_232am_baud_to_divisor(int baud) 12121da177e4SLinus Torvalds { 1213464cbb24SAlan Cox return ftdi_232am_baud_base_to_divisor(baud, 48000000); 12141da177e4SLinus Torvalds } 12151da177e4SLinus Torvalds 1216fd54a99aSJohan Hovold static u32 ftdi_232bm_baud_base_to_divisor(int baud, int base) 12171da177e4SLinus Torvalds { 12181da177e4SLinus Torvalds static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; 1219fd54a99aSJohan Hovold u32 divisor; 1220464cbb24SAlan Cox /* divisor shifted 3 bits to the left */ 12216abd8371SNikolaj Fogh int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud); 12221da177e4SLinus Torvalds divisor = divisor3 >> 3; 1223fd54a99aSJohan Hovold divisor |= (u32)divfrac[divisor3 & 0x7] << 14; 12241da177e4SLinus Torvalds /* Deal with special cases for highest baud rates. */ 12251ef26803SJohan Hovold if (divisor == 1) /* 1.0 */ 1226464cbb24SAlan Cox divisor = 0; 12271ef26803SJohan Hovold else if (divisor == 0x4001) /* 1.5 */ 1228464cbb24SAlan Cox divisor = 1; 12291da177e4SLinus Torvalds return divisor; 12301da177e4SLinus Torvalds } 12311da177e4SLinus Torvalds 1232fd54a99aSJohan Hovold static u32 ftdi_232bm_baud_to_divisor(int baud) 12331da177e4SLinus Torvalds { 1234464cbb24SAlan Cox return ftdi_232bm_baud_base_to_divisor(baud, 48000000); 12351da177e4SLinus Torvalds } 12361da177e4SLinus Torvalds 1237fd54a99aSJohan Hovold static u32 ftdi_2232h_baud_base_to_divisor(int baud, int base) 1238094c2e6dSMark Adamson { 1239094c2e6dSMark Adamson static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; 1240fd54a99aSJohan Hovold u32 divisor; 1241094c2e6dSMark Adamson int divisor3; 1242094c2e6dSMark Adamson 1243094c2e6dSMark Adamson /* hi-speed baud rate is 10-bit sampling instead of 16-bit */ 12446abd8371SNikolaj Fogh divisor3 = DIV_ROUND_CLOSEST(8 * base, 10 * baud); 1245094c2e6dSMark Adamson 1246094c2e6dSMark Adamson divisor = divisor3 >> 3; 1247fd54a99aSJohan Hovold divisor |= (u32)divfrac[divisor3 & 0x7] << 14; 1248094c2e6dSMark Adamson /* Deal with special cases for highest baud rates. */ 12491ef26803SJohan Hovold if (divisor == 1) /* 1.0 */ 1250094c2e6dSMark Adamson divisor = 0; 12511ef26803SJohan Hovold else if (divisor == 0x4001) /* 1.5 */ 1252094c2e6dSMark Adamson divisor = 1; 1253094c2e6dSMark Adamson /* 1254094c2e6dSMark Adamson * Set this bit to turn off a divide by 2.5 on baud rate generator 1255094c2e6dSMark Adamson * This enables baud rates up to 12Mbaud but cannot reach below 1200 1256094c2e6dSMark Adamson * baud with this bit set 1257094c2e6dSMark Adamson */ 1258094c2e6dSMark Adamson divisor |= 0x00020000; 1259094c2e6dSMark Adamson return divisor; 1260094c2e6dSMark Adamson } 1261094c2e6dSMark Adamson 1262fd54a99aSJohan Hovold static u32 ftdi_2232h_baud_to_divisor(int baud) 1263094c2e6dSMark Adamson { 1264094c2e6dSMark Adamson return ftdi_2232h_baud_base_to_divisor(baud, 120000000); 1265094c2e6dSMark Adamson } 1266094c2e6dSMark Adamson 126774ede0ffSIan Abbott #define set_mctrl(port, set) update_mctrl((port), (set), 0) 126874ede0ffSIan Abbott #define clear_mctrl(port, clear) update_mctrl((port), 0, (clear)) 126974ede0ffSIan Abbott 1270464cbb24SAlan Cox static int update_mctrl(struct usb_serial_port *port, unsigned int set, 1271464cbb24SAlan Cox unsigned int clear) 12721da177e4SLinus Torvalds { 12731da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 1274bfc51614SGreg Kroah-Hartman struct device *dev = &port->dev; 127516410115SJohan Hovold unsigned value; 12761da177e4SLinus Torvalds int rv; 12771da177e4SLinus Torvalds 127874ede0ffSIan Abbott if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) { 1279bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - DTR|RTS not being set|cleared\n", __func__); 128074ede0ffSIan Abbott return 0; /* no change */ 12811da177e4SLinus Torvalds } 128274ede0ffSIan Abbott 128374ede0ffSIan Abbott clear &= ~set; /* 'set' takes precedence over 'clear' */ 128416410115SJohan Hovold value = 0; 128574ede0ffSIan Abbott if (clear & TIOCM_DTR) 128616410115SJohan Hovold value |= FTDI_SIO_SET_DTR_LOW; 128774ede0ffSIan Abbott if (clear & TIOCM_RTS) 128816410115SJohan Hovold value |= FTDI_SIO_SET_RTS_LOW; 128974ede0ffSIan Abbott if (set & TIOCM_DTR) 129016410115SJohan Hovold value |= FTDI_SIO_SET_DTR_HIGH; 129174ede0ffSIan Abbott if (set & TIOCM_RTS) 129216410115SJohan Hovold value |= FTDI_SIO_SET_RTS_HIGH; 12931da177e4SLinus Torvalds rv = usb_control_msg(port->serial->dev, 12941da177e4SLinus Torvalds usb_sndctrlpipe(port->serial->dev, 0), 12951da177e4SLinus Torvalds FTDI_SIO_SET_MODEM_CTRL_REQUEST, 12961da177e4SLinus Torvalds FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, 1297027bf37dSJohan Hovold value, priv->channel, 129866e47e60SJohan Hovold NULL, 0, WDR_TIMEOUT); 129974ede0ffSIan Abbott if (rv < 0) { 1300bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s Error from MODEM_CTRL urb: DTR %s, RTS %s\n", 1301441b62c1SHarvey Harrison __func__, 1302bfc51614SGreg Kroah-Hartman (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged", 1303bfc51614SGreg Kroah-Hartman (set & TIOCM_RTS) ? "HIGH" : (clear & TIOCM_RTS) ? "LOW" : "unchanged"); 13042c2ee545SJohan Hovold rv = usb_translate_errors(rv); 13051da177e4SLinus Torvalds } else { 1306bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - DTR %s, RTS %s\n", __func__, 1307bfc51614SGreg Kroah-Hartman (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged", 1308bfc51614SGreg Kroah-Hartman (set & TIOCM_RTS) ? "HIGH" : (clear & TIOCM_RTS) ? "LOW" : "unchanged"); 13099b0f2582SAlan Cox /* FIXME: locking on last_dtr_rts */ 131074ede0ffSIan Abbott priv->last_dtr_rts = (priv->last_dtr_rts & ~clear) | set; 13111da177e4SLinus Torvalds } 13121da177e4SLinus Torvalds return rv; 13131da177e4SLinus Torvalds } 13141da177e4SLinus Torvalds 13151da177e4SLinus Torvalds 1316fd54a99aSJohan Hovold static u32 get_ftdi_divisor(struct tty_struct *tty, 1317464cbb24SAlan Cox struct usb_serial_port *port) 1318e49bbce1SJohan Hovold { 13191da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 1320bfc51614SGreg Kroah-Hartman struct device *dev = &port->dev; 1321fd54a99aSJohan Hovold u32 div_value = 0; 13221da177e4SLinus Torvalds int div_okay = 1; 13231da177e4SLinus Torvalds int baud; 13241da177e4SLinus Torvalds 132595da310eSAlan Cox baud = tty_get_baud_rate(tty); 1326bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - tty_get_baud_rate reports speed %d\n", __func__, baud); 13271da177e4SLinus Torvalds 132883c9a2d1SJohan Hovold /* 132983c9a2d1SJohan Hovold * Observe deprecated async-compatible custom_divisor hack, update 133083c9a2d1SJohan Hovold * baudrate if needed. 133183c9a2d1SJohan Hovold */ 13321da177e4SLinus Torvalds if (baud == 38400 && 13331da177e4SLinus Torvalds ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && 13341da177e4SLinus Torvalds (priv->custom_divisor)) { 13351da177e4SLinus Torvalds baud = priv->baud_base / priv->custom_divisor; 1336bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - custom divisor %d sets baud rate to %d\n", 1337464cbb24SAlan Cox __func__, priv->custom_divisor, baud); 13381da177e4SLinus Torvalds } 13391da177e4SLinus Torvalds 1340464cbb24SAlan Cox if (!baud) 1341464cbb24SAlan Cox baud = 9600; 13421da177e4SLinus Torvalds switch (priv->chip_type) { 134325eb9486SJohan Hovold case SIO: 13441da177e4SLinus Torvalds switch (baud) { 13451da177e4SLinus Torvalds case 300: div_value = ftdi_sio_b300; break; 13461da177e4SLinus Torvalds case 600: div_value = ftdi_sio_b600; break; 13471da177e4SLinus Torvalds case 1200: div_value = ftdi_sio_b1200; break; 13481da177e4SLinus Torvalds case 2400: div_value = ftdi_sio_b2400; break; 13491da177e4SLinus Torvalds case 4800: div_value = ftdi_sio_b4800; break; 13501da177e4SLinus Torvalds case 9600: div_value = ftdi_sio_b9600; break; 13511da177e4SLinus Torvalds case 19200: div_value = ftdi_sio_b19200; break; 13521da177e4SLinus Torvalds case 38400: div_value = ftdi_sio_b38400; break; 13531da177e4SLinus Torvalds case 57600: div_value = ftdi_sio_b57600; break; 13541da177e4SLinus Torvalds case 115200: div_value = ftdi_sio_b115200; break; 13557bd7ad3cSJohan Hovold default: 1356bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - Baudrate (%d) requested is not supported\n", 1357464cbb24SAlan Cox __func__, baud); 13581da177e4SLinus Torvalds div_value = ftdi_sio_b9600; 1359669a6db1SAlan Cox baud = 9600; 13601da177e4SLinus Torvalds div_okay = 0; 13611da177e4SLinus Torvalds } 13621da177e4SLinus Torvalds break; 136301aeb31fSJohan Hovold case FT232A: 13641da177e4SLinus Torvalds if (baud <= 3000000) { 13651da177e4SLinus Torvalds div_value = ftdi_232am_baud_to_divisor(baud); 13661da177e4SLinus Torvalds } else { 1367bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - Baud rate too high!\n", __func__); 1368669a6db1SAlan Cox baud = 9600; 13691da177e4SLinus Torvalds div_value = ftdi_232am_baud_to_divisor(9600); 13701da177e4SLinus Torvalds div_okay = 0; 13711da177e4SLinus Torvalds } 13721da177e4SLinus Torvalds break; 137301aeb31fSJohan Hovold case FT232B: 137425eb9486SJohan Hovold case FT2232C: 137501aeb31fSJohan Hovold case FT232R: 137625eb9486SJohan Hovold case FTX: 13771da177e4SLinus Torvalds if (baud <= 3000000) { 1378fd54a99aSJohan Hovold u16 product_id = le16_to_cpu( 1379b760dac2SMartin Geleynse port->serial->dev->descriptor.idProduct); 1380fb571101SMathieu OTHACEHE if (((product_id == FTDI_NDI_HUC_PID) || 1381fb571101SMathieu OTHACEHE (product_id == FTDI_NDI_SPECTRA_SCU_PID) || 1382fb571101SMathieu OTHACEHE (product_id == FTDI_NDI_FUTURE_2_PID) || 1383fb571101SMathieu OTHACEHE (product_id == FTDI_NDI_FUTURE_3_PID) || 1384fb571101SMathieu OTHACEHE (product_id == FTDI_NDI_AURORA_SCU_PID)) && 1385b760dac2SMartin Geleynse (baud == 19200)) { 1386b760dac2SMartin Geleynse baud = 1200000; 1387b760dac2SMartin Geleynse } 13881da177e4SLinus Torvalds div_value = ftdi_232bm_baud_to_divisor(baud); 13891da177e4SLinus Torvalds } else { 1390bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - Baud rate too high!\n", __func__); 13911da177e4SLinus Torvalds div_value = ftdi_232bm_baud_to_divisor(9600); 13921da177e4SLinus Torvalds div_okay = 0; 1393669a6db1SAlan Cox baud = 9600; 13941da177e4SLinus Torvalds } 13951da177e4SLinus Torvalds break; 13961a039891SJohan Hovold default: 13971862cdd5SIonut Nicu if ((baud <= 12000000) && (baud >= 1200)) { 1398094c2e6dSMark Adamson div_value = ftdi_2232h_baud_to_divisor(baud); 1399094c2e6dSMark Adamson } else if (baud < 1200) { 1400094c2e6dSMark Adamson div_value = ftdi_232bm_baud_to_divisor(baud); 1401094c2e6dSMark Adamson } else { 1402bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - Baud rate too high!\n", __func__); 1403094c2e6dSMark Adamson div_value = ftdi_232bm_baud_to_divisor(9600); 1404094c2e6dSMark Adamson div_okay = 0; 1405094c2e6dSMark Adamson baud = 9600; 1406094c2e6dSMark Adamson } 1407094c2e6dSMark Adamson break; 140825eb9486SJohan Hovold } 14091da177e4SLinus Torvalds 14101da177e4SLinus Torvalds if (div_okay) { 1411bfc51614SGreg Kroah-Hartman dev_dbg(dev, "%s - Baud rate set to %d (divisor 0x%lX) on chip %s\n", 1412441b62c1SHarvey Harrison __func__, baud, (unsigned long)div_value, 14131da177e4SLinus Torvalds ftdi_chip_name[priv->chip_type]); 14141da177e4SLinus Torvalds } 14151da177e4SLinus Torvalds 141695da310eSAlan Cox tty_encode_baud_rate(tty, baud, baud); 1417464cbb24SAlan Cox return div_value; 14181da177e4SLinus Torvalds } 14191da177e4SLinus Torvalds 142095da310eSAlan Cox static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) 142195da310eSAlan Cox { 142295da310eSAlan Cox struct ftdi_private *priv = usb_get_serial_port_data(port); 142316410115SJohan Hovold u16 value; 142416410115SJohan Hovold u16 index; 142516410115SJohan Hovold u32 index_value; 142695da310eSAlan Cox int rv; 142795da310eSAlan Cox 142816410115SJohan Hovold index_value = get_ftdi_divisor(tty, port); 142916410115SJohan Hovold value = (u16)index_value; 143016410115SJohan Hovold index = (u16)(index_value >> 16); 1431a146cc4dSJohan Hovold if (priv->channel) 1432027bf37dSJohan Hovold index = (u16)((index << 8) | priv->channel); 143395da310eSAlan Cox 143495da310eSAlan Cox rv = usb_control_msg(port->serial->dev, 143595da310eSAlan Cox usb_sndctrlpipe(port->serial->dev, 0), 143695da310eSAlan Cox FTDI_SIO_SET_BAUDRATE_REQUEST, 143795da310eSAlan Cox FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, 143816410115SJohan Hovold value, index, 143966e47e60SJohan Hovold NULL, 0, WDR_SHORT_TIMEOUT); 144095da310eSAlan Cox return rv; 144195da310eSAlan Cox } 144295da310eSAlan Cox 1443557aaa7fSAlan Cox static int write_latency_timer(struct usb_serial_port *port) 1444557aaa7fSAlan Cox { 1445557aaa7fSAlan Cox struct ftdi_private *priv = usb_get_serial_port_data(port); 1446557aaa7fSAlan Cox struct usb_device *udev = port->serial->dev; 1447c1284d77SJohan Hovold int rv; 1448557aaa7fSAlan Cox int l = priv->latency; 144995da310eSAlan Cox 145001aeb31fSJohan Hovold if (priv->chip_type == SIO || priv->chip_type == FT232A) 14512dea7cd7SIan Abbott return -EINVAL; 14522dea7cd7SIan Abbott 1453557aaa7fSAlan Cox if (priv->flags & ASYNC_LOW_LATENCY) 1454557aaa7fSAlan Cox l = 1; 1455557aaa7fSAlan Cox 1456bfc51614SGreg Kroah-Hartman dev_dbg(&port->dev, "%s: setting latency timer = %i\n", __func__, l); 1457557aaa7fSAlan Cox 1458557aaa7fSAlan Cox rv = usb_control_msg(udev, 1459557aaa7fSAlan Cox usb_sndctrlpipe(udev, 0), 1460557aaa7fSAlan Cox FTDI_SIO_SET_LATENCY_TIMER_REQUEST, 1461557aaa7fSAlan Cox FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, 1462027bf37dSJohan Hovold l, priv->channel, 146366e47e60SJohan Hovold NULL, 0, WDR_TIMEOUT); 1464557aaa7fSAlan Cox if (rv < 0) 1465557aaa7fSAlan Cox dev_err(&port->dev, "Unable to write latency timer: %i\n", rv); 1466557aaa7fSAlan Cox return rv; 1467557aaa7fSAlan Cox } 1468557aaa7fSAlan Cox 14697e1e6cedSIan Abbott static int _read_latency_timer(struct usb_serial_port *port) 1470557aaa7fSAlan Cox { 1471557aaa7fSAlan Cox struct ftdi_private *priv = usb_get_serial_port_data(port); 1472557aaa7fSAlan Cox struct usb_device *udev = port->serial->dev; 1473a7388592SHimadri Pandya u8 buf; 1474c1284d77SJohan Hovold int rv; 1475557aaa7fSAlan Cox 1476a7388592SHimadri Pandya rv = usb_control_msg_recv(udev, 0, FTDI_SIO_GET_LATENCY_TIMER_REQUEST, 1477a7388592SHimadri Pandya FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, 0, 1478027bf37dSJohan Hovold priv->channel, &buf, 1, WDR_TIMEOUT, 1479a7388592SHimadri Pandya GFP_KERNEL); 1480a7388592SHimadri Pandya if (rv == 0) 1481a7388592SHimadri Pandya rv = buf; 148254f328d0SJohan Hovold 14838c4f99cdSJohan Hovold return rv; 1484557aaa7fSAlan Cox } 14851da177e4SLinus Torvalds 14867e1e6cedSIan Abbott static int read_latency_timer(struct usb_serial_port *port) 14877e1e6cedSIan Abbott { 14887e1e6cedSIan Abbott struct ftdi_private *priv = usb_get_serial_port_data(port); 14897e1e6cedSIan Abbott int rv; 14907e1e6cedSIan Abbott 149101aeb31fSJohan Hovold if (priv->chip_type == SIO || priv->chip_type == FT232A) 14927e1e6cedSIan Abbott return -EINVAL; 14937e1e6cedSIan Abbott 14947e1e6cedSIan Abbott rv = _read_latency_timer(port); 14957e1e6cedSIan Abbott if (rv < 0) { 14967e1e6cedSIan Abbott dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); 14977e1e6cedSIan Abbott return rv; 14987e1e6cedSIan Abbott } 14997e1e6cedSIan Abbott 15007e1e6cedSIan Abbott priv->latency = rv; 15017e1e6cedSIan Abbott 15027e1e6cedSIan Abbott return 0; 15037e1e6cedSIan Abbott } 15047e1e6cedSIan Abbott 150501fd45f6SJohan Hovold static void get_serial_info(struct tty_struct *tty, struct serial_struct *ss) 15061da177e4SLinus Torvalds { 15073ae36bedSAl Viro struct usb_serial_port *port = tty->driver_data; 15081da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 15091da177e4SLinus Torvalds 15103ae36bedSAl Viro ss->flags = priv->flags; 15113ae36bedSAl Viro ss->baud_base = priv->baud_base; 15123ae36bedSAl Viro ss->custom_divisor = priv->custom_divisor; 1513e49bbce1SJohan Hovold } 15141da177e4SLinus Torvalds 15150428bf68SJohan Hovold static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) 1516e49bbce1SJohan Hovold { 15173ae36bedSAl Viro struct usb_serial_port *port = tty->driver_data; 15181da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 15190428bf68SJohan Hovold int old_flags, old_divisor; 15201da177e4SLinus Torvalds 1521bd09a9f5SAlessio Igor Bogani mutex_lock(&priv->cfg_lock); 15221da177e4SLinus Torvalds 15231da177e4SLinus Torvalds if (!capable(CAP_SYS_ADMIN)) { 15243ae36bedSAl Viro if ((ss->flags ^ priv->flags) & ~ASYNC_USR_MASK) { 1525bd09a9f5SAlessio Igor Bogani mutex_unlock(&priv->cfg_lock); 15261da177e4SLinus Torvalds return -EPERM; 152764905b48SDan Carpenter } 15281da177e4SLinus Torvalds } 15291da177e4SLinus Torvalds 15300428bf68SJohan Hovold old_flags = priv->flags; 15310428bf68SJohan Hovold old_divisor = priv->custom_divisor; 15320428bf68SJohan Hovold 1533c12860c0SJohan Hovold priv->flags = ss->flags & ASYNC_FLAGS; 15343ae36bedSAl Viro priv->custom_divisor = ss->custom_divisor; 15351da177e4SLinus Torvalds 1536557aaa7fSAlan Cox write_latency_timer(port); 15371da177e4SLinus Torvalds 15380428bf68SJohan Hovold if ((priv->flags ^ old_flags) & ASYNC_SPD_MASK || 1539f3e8ae65SJohan Hovold ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && 15400428bf68SJohan Hovold priv->custom_divisor != old_divisor)) { 154183c9a2d1SJohan Hovold 154283c9a2d1SJohan Hovold /* warn about deprecation unless clearing */ 154383c9a2d1SJohan Hovold if (priv->flags & ASYNC_SPD_MASK) 154483c9a2d1SJohan Hovold dev_warn_ratelimited(&port->dev, "use of SPD flags is deprecated\n"); 154583c9a2d1SJohan Hovold 154695da310eSAlan Cox change_speed(tty, port); 15471da177e4SLinus Torvalds } 1548bd09a9f5SAlessio Igor Bogani mutex_unlock(&priv->cfg_lock); 154995da310eSAlan Cox return 0; 1550e49bbce1SJohan Hovold } 15511da177e4SLinus Torvalds 1552c466cd2bSGreg Kroah-Hartman static int get_lsr_info(struct usb_serial_port *port, 155359556608SJohan Hovold unsigned int __user *retinfo) 1554c466cd2bSGreg Kroah-Hartman { 1555c466cd2bSGreg Kroah-Hartman struct ftdi_private *priv = usb_get_serial_port_data(port); 1556c466cd2bSGreg Kroah-Hartman unsigned int result = 0; 1557c466cd2bSGreg Kroah-Hartman 1558c466cd2bSGreg Kroah-Hartman if (priv->transmit_empty) 1559c466cd2bSGreg Kroah-Hartman result = TIOCSER_TEMT; 1560c466cd2bSGreg Kroah-Hartman 1561c466cd2bSGreg Kroah-Hartman if (copy_to_user(retinfo, &result, sizeof(unsigned int))) 1562c466cd2bSGreg Kroah-Hartman return -EFAULT; 1563c466cd2bSGreg Kroah-Hartman return 0; 1564c466cd2bSGreg Kroah-Hartman } 1565c466cd2bSGreg Kroah-Hartman 1566f353c0d4SJohan Hovold static int ftdi_determine_type(struct usb_serial_port *port) 15678f977e42SIan Abbott { 15688f977e42SIan Abbott struct ftdi_private *priv = usb_get_serial_port_data(port); 15698f977e42SIan Abbott struct usb_serial *serial = port->serial; 15708f977e42SIan Abbott struct usb_device *udev = serial->dev; 1571f353c0d4SJohan Hovold unsigned int version, ifnum; 15728f977e42SIan Abbott 15738f977e42SIan Abbott version = le16_to_cpu(udev->descriptor.bcdDevice); 1574f353c0d4SJohan Hovold ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; 15758f977e42SIan Abbott 15764d50f4fcSJohan Hovold /* Assume Hi-Speed type */ 15774d50f4fcSJohan Hovold priv->baud_base = 120000000 / 2; 15784d50f4fcSJohan Hovold priv->channel = CHANNEL_A + ifnum; 1579094c2e6dSMark Adamson 1580f353c0d4SJohan Hovold switch (version) { 1581f353c0d4SJohan Hovold case 0x200: 158201aeb31fSJohan Hovold priv->chip_type = FT232A; 15834d50f4fcSJohan Hovold priv->baud_base = 48000000 / 2; 15844d50f4fcSJohan Hovold priv->channel = 0; 15857e1e6cedSIan Abbott /* 1586f353c0d4SJohan Hovold * FT232B devices have a bug where bcdDevice gets set to 0x200 1587f353c0d4SJohan Hovold * when iSerialNumber is 0. Assume it is an FT232B in case the 1588f353c0d4SJohan Hovold * latency timer is readable. 15897e1e6cedSIan Abbott */ 15907e1e6cedSIan Abbott if (udev->descriptor.iSerialNumber == 0 && 15917e1e6cedSIan Abbott _read_latency_timer(port) >= 0) { 159201aeb31fSJohan Hovold priv->chip_type = FT232B; 15937e1e6cedSIan Abbott } 1594f353c0d4SJohan Hovold break; 1595f353c0d4SJohan Hovold case 0x400: 159601aeb31fSJohan Hovold priv->chip_type = FT232B; 15974d50f4fcSJohan Hovold priv->baud_base = 48000000 / 2; 15984d50f4fcSJohan Hovold priv->channel = 0; 1599f353c0d4SJohan Hovold break; 1600f353c0d4SJohan Hovold case 0x500: 1601f353c0d4SJohan Hovold priv->chip_type = FT2232C; 16024d50f4fcSJohan Hovold priv->baud_base = 48000000 / 2; 1603f353c0d4SJohan Hovold break; 1604f353c0d4SJohan Hovold case 0x600: 160501aeb31fSJohan Hovold priv->chip_type = FT232R; 16064d50f4fcSJohan Hovold priv->baud_base = 48000000 / 2; 16074d50f4fcSJohan Hovold priv->channel = 0; 1608f353c0d4SJohan Hovold break; 1609f353c0d4SJohan Hovold case 0x700: 1610f353c0d4SJohan Hovold priv->chip_type = FT2232H; 1611f353c0d4SJohan Hovold break; 1612f353c0d4SJohan Hovold case 0x800: 1613f353c0d4SJohan Hovold priv->chip_type = FT4232H; 1614f353c0d4SJohan Hovold break; 1615f353c0d4SJohan Hovold case 0x900: 1616309427b6SUwe Bonnes priv->chip_type = FT232H; 1617f353c0d4SJohan Hovold break; 1618f353c0d4SJohan Hovold case 0x1000: 1619dc0827c1SJim Paris priv->chip_type = FTX; 16204d50f4fcSJohan Hovold priv->baud_base = 48000000 / 2; 1621f353c0d4SJohan Hovold break; 1622cfebcd53SAmireddy mallikarjuna reddy case 0x2800: 1623cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT2233HP; 1624cfebcd53SAmireddy mallikarjuna reddy break; 1625cfebcd53SAmireddy mallikarjuna reddy case 0x2900: 1626cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT4233HP; 1627cfebcd53SAmireddy mallikarjuna reddy break; 1628cfebcd53SAmireddy mallikarjuna reddy case 0x3000: 1629cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT2232HP; 1630cfebcd53SAmireddy mallikarjuna reddy break; 1631cfebcd53SAmireddy mallikarjuna reddy case 0x3100: 1632cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT4232HP; 1633cfebcd53SAmireddy mallikarjuna reddy break; 1634cfebcd53SAmireddy mallikarjuna reddy case 0x3200: 1635cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT233HP; 1636cfebcd53SAmireddy mallikarjuna reddy break; 1637cfebcd53SAmireddy mallikarjuna reddy case 0x3300: 1638cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT232HP; 1639cfebcd53SAmireddy mallikarjuna reddy break; 1640cfebcd53SAmireddy mallikarjuna reddy case 0x3600: 1641cfebcd53SAmireddy mallikarjuna reddy priv->chip_type = FT4232HA; 1642cfebcd53SAmireddy mallikarjuna reddy break; 1643f353c0d4SJohan Hovold default: 1644f353c0d4SJohan Hovold if (version < 0x200) { 1645f353c0d4SJohan Hovold priv->chip_type = SIO; 1646f353c0d4SJohan Hovold priv->baud_base = 12000000 / 16; 16474d50f4fcSJohan Hovold priv->channel = 0; 1648f353c0d4SJohan Hovold } else { 1649f353c0d4SJohan Hovold dev_err(&port->dev, "unknown device type: 0x%02x\n", version); 1650f353c0d4SJohan Hovold return -ENODEV; 1651f353c0d4SJohan Hovold } 16528f977e42SIan Abbott } 1653dc0827c1SJim Paris 1654c197a8dbSGreg Kroah-Hartman dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); 1655f353c0d4SJohan Hovold 1656f353c0d4SJohan Hovold return 0; 16578f977e42SIan Abbott } 16588f977e42SIan Abbott 16598f977e42SIan Abbott 166047e57595SJohan Hovold /* 166147e57595SJohan Hovold * Determine the maximum packet size for the device. This depends on the chip 1662895f28baSMark Adamson * type and the USB host capabilities. The value should be obtained from the 166347e57595SJohan Hovold * device descriptor as the chip will use the appropriate values for the host. 166447e57595SJohan Hovold */ 1665895f28baSMark Adamson static void ftdi_set_max_packet_size(struct usb_serial_port *port) 1666895f28baSMark Adamson { 1667895f28baSMark Adamson struct ftdi_private *priv = usb_get_serial_port_data(port); 166847e57595SJohan Hovold struct usb_interface *interface = port->serial->interface; 1669aea1ae87SJohan Hovold struct usb_endpoint_descriptor *ep_desc; 1670895f28baSMark Adamson unsigned num_endpoints; 1671aea1ae87SJohan Hovold unsigned i; 1672895f28baSMark Adamson 1673895f28baSMark Adamson num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; 1674aea1ae87SJohan Hovold if (!num_endpoints) 1675aea1ae87SJohan Hovold return; 1676aea1ae87SJohan Hovold 167747e57595SJohan Hovold /* 167847e57595SJohan Hovold * NOTE: Some customers have programmed FT232R/FT245R devices 1679895f28baSMark Adamson * with an endpoint size of 0 - not good. In this case, we 1680895f28baSMark Adamson * want to override the endpoint descriptor setting and use a 168147e57595SJohan Hovold * value of 64 for wMaxPacketSize. 168247e57595SJohan Hovold */ 1683895f28baSMark Adamson for (i = 0; i < num_endpoints; i++) { 1684895f28baSMark Adamson ep_desc = &interface->cur_altsetting->endpoint[i].desc; 168547e57595SJohan Hovold if (!ep_desc->wMaxPacketSize) { 1686895f28baSMark Adamson ep_desc->wMaxPacketSize = cpu_to_le16(0x40); 1687a90d84adSJohan Hovold dev_warn(&port->dev, "Overriding wMaxPacketSize on endpoint %d\n", 1688a90d84adSJohan Hovold usb_endpoint_num(ep_desc)); 1689895f28baSMark Adamson } 1690895f28baSMark Adamson } 1691895f28baSMark Adamson 169247e57595SJohan Hovold /* Set max packet size based on last descriptor. */ 169329cc8897SKuninori Morimoto priv->max_packet_size = usb_endpoint_maxp(ep_desc); 1694895f28baSMark Adamson } 1695895f28baSMark Adamson 1696895f28baSMark Adamson 16971da177e4SLinus Torvalds /* 16981da177e4SLinus Torvalds * *************************************************************************** 16991da177e4SLinus Torvalds * Sysfs Attribute 17001da177e4SLinus Torvalds * *************************************************************************** 17011da177e4SLinus Torvalds */ 17021da177e4SLinus Torvalds 1703154547c4SGreg Kroah-Hartman static ssize_t latency_timer_show(struct device *dev, 1704464cbb24SAlan Cox struct device_attribute *attr, char *buf) 17051da177e4SLinus Torvalds { 17061da177e4SLinus Torvalds struct usb_serial_port *port = to_usb_serial_port(dev); 17071da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 1708557aaa7fSAlan Cox if (priv->flags & ASYNC_LOW_LATENCY) 1709557aaa7fSAlan Cox return sprintf(buf, "1\n"); 1710557aaa7fSAlan Cox else 17111b30499aSDaniels Umanovskis return sprintf(buf, "%u\n", priv->latency); 17121da177e4SLinus Torvalds } 1713557aaa7fSAlan Cox 17141da177e4SLinus Torvalds /* Write a new value of the latency timer, in units of milliseconds. */ 1715154547c4SGreg Kroah-Hartman static ssize_t latency_timer_store(struct device *dev, 1716154547c4SGreg Kroah-Hartman struct device_attribute *attr, 1717154547c4SGreg Kroah-Hartman const char *valbuf, size_t count) 17181da177e4SLinus Torvalds { 17191da177e4SLinus Torvalds struct usb_serial_port *port = to_usb_serial_port(dev); 17201da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 1721db924066SIan Abbott u8 v; 1722c1284d77SJohan Hovold int rv; 17231da177e4SLinus Torvalds 1724db924066SIan Abbott if (kstrtou8(valbuf, 10, &v)) 1725db924066SIan Abbott return -EINVAL; 1726db924066SIan Abbott 1727557aaa7fSAlan Cox priv->latency = v; 1728557aaa7fSAlan Cox rv = write_latency_timer(port); 1729557aaa7fSAlan Cox if (rv < 0) 17301da177e4SLinus Torvalds return -EIO; 17311da177e4SLinus Torvalds return count; 17321da177e4SLinus Torvalds } 1733154547c4SGreg Kroah-Hartman static DEVICE_ATTR_RW(latency_timer); 17341da177e4SLinus Torvalds 17351da177e4SLinus Torvalds /* Write an event character directly to the FTDI register. The ASCII 17361da177e4SLinus Torvalds value is in the low 8 bits, with the enable bit in the 9th bit. */ 1737ca35910aSGreg Kroah-Hartman static ssize_t event_char_store(struct device *dev, 1738464cbb24SAlan Cox struct device_attribute *attr, const char *valbuf, size_t count) 17391da177e4SLinus Torvalds { 17401da177e4SLinus Torvalds struct usb_serial_port *port = to_usb_serial_port(dev); 17411da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 174212bdbe03SJim Radford struct usb_device *udev = port->serial->dev; 1743d0559a2fSIan Abbott unsigned int v; 1744c1284d77SJohan Hovold int rv; 17451da177e4SLinus Torvalds 1746f1ce25f2SIan Abbott if (kstrtouint(valbuf, 0, &v) || v >= 0x200) 1747d0559a2fSIan Abbott return -EINVAL; 1748d0559a2fSIan Abbott 1749f1ce25f2SIan Abbott dev_dbg(&port->dev, "%s: setting event char = 0x%03x\n", __func__, v); 17501da177e4SLinus Torvalds 17511da177e4SLinus Torvalds rv = usb_control_msg(udev, 17521da177e4SLinus Torvalds usb_sndctrlpipe(udev, 0), 17531da177e4SLinus Torvalds FTDI_SIO_SET_EVENT_CHAR_REQUEST, 17541da177e4SLinus Torvalds FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, 1755027bf37dSJohan Hovold v, priv->channel, 175666e47e60SJohan Hovold NULL, 0, WDR_TIMEOUT); 17571da177e4SLinus Torvalds if (rv < 0) { 1758bfc51614SGreg Kroah-Hartman dev_dbg(&port->dev, "Unable to write event character: %i\n", rv); 17591da177e4SLinus Torvalds return -EIO; 17601da177e4SLinus Torvalds } 17611da177e4SLinus Torvalds 17621da177e4SLinus Torvalds return count; 17631da177e4SLinus Torvalds } 1764ca35910aSGreg Kroah-Hartman static DEVICE_ATTR_WO(event_char); 17651da177e4SLinus Torvalds 1766*0f6632e2SJiasheng Jiang static struct attribute *ftdi_attrs[] = { 1767*0f6632e2SJiasheng Jiang &dev_attr_event_char.attr, 1768*0f6632e2SJiasheng Jiang &dev_attr_latency_timer.attr, 1769*0f6632e2SJiasheng Jiang NULL 1770*0f6632e2SJiasheng Jiang }; 1771*0f6632e2SJiasheng Jiang 1772*0f6632e2SJiasheng Jiang static umode_t ftdi_is_visible(struct kobject *kobj, struct attribute *attr, int idx) 17731da177e4SLinus Torvalds { 1774*0f6632e2SJiasheng Jiang struct device *dev = kobj_to_dev(kobj); 1775*0f6632e2SJiasheng Jiang struct usb_serial_port *port = to_usb_serial_port(dev); 177612bdbe03SJim Radford struct ftdi_private *priv = usb_get_serial_port_data(port); 17774d045b98SJohan Hovold enum ftdi_chip_type type = priv->chip_type; 1778*0f6632e2SJiasheng Jiang umode_t mode = attr->mode; 17791da177e4SLinus Torvalds 17804d045b98SJohan Hovold if (type != SIO) { 1781*0f6632e2SJiasheng Jiang if (attr == &dev_attr_event_char.attr) 1782*0f6632e2SJiasheng Jiang return mode; 17831da177e4SLinus Torvalds } 17844d045b98SJohan Hovold 1785*0f6632e2SJiasheng Jiang if (type != SIO && type != FT232A) { 1786*0f6632e2SJiasheng Jiang if (attr == &dev_attr_latency_timer.attr) 1787*0f6632e2SJiasheng Jiang return mode; 17881da177e4SLinus Torvalds } 17891da177e4SLinus Torvalds 1790*0f6632e2SJiasheng Jiang return 0; 17911da177e4SLinus Torvalds } 17921da177e4SLinus Torvalds 1793*0f6632e2SJiasheng Jiang static const struct attribute_group ftdi_group = { 1794*0f6632e2SJiasheng Jiang .attrs = ftdi_attrs, 1795*0f6632e2SJiasheng Jiang .is_visible = ftdi_is_visible, 1796*0f6632e2SJiasheng Jiang }; 1797*0f6632e2SJiasheng Jiang 1798*0f6632e2SJiasheng Jiang static const struct attribute_group *ftdi_groups[] = { 1799*0f6632e2SJiasheng Jiang &ftdi_group, 1800*0f6632e2SJiasheng Jiang NULL 1801*0f6632e2SJiasheng Jiang }; 1802*0f6632e2SJiasheng Jiang 1803ba93cc7dSKaroly Pados #ifdef CONFIG_GPIOLIB 1804ba93cc7dSKaroly Pados 1805ba93cc7dSKaroly Pados static int ftdi_set_bitmode(struct usb_serial_port *port, u8 mode) 1806ba93cc7dSKaroly Pados { 1807ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1808ba93cc7dSKaroly Pados struct usb_serial *serial = port->serial; 1809ba93cc7dSKaroly Pados int result; 1810ba93cc7dSKaroly Pados u16 val; 1811ba93cc7dSKaroly Pados 1812a8eda9faSKaroly Pados result = usb_autopm_get_interface(serial->interface); 1813a8eda9faSKaroly Pados if (result) 1814a8eda9faSKaroly Pados return result; 1815a8eda9faSKaroly Pados 1816ba93cc7dSKaroly Pados val = (mode << 8) | (priv->gpio_output << 4) | priv->gpio_value; 1817ba93cc7dSKaroly Pados result = usb_control_msg(serial->dev, 1818ba93cc7dSKaroly Pados usb_sndctrlpipe(serial->dev, 0), 1819ba93cc7dSKaroly Pados FTDI_SIO_SET_BITMODE_REQUEST, 1820ba93cc7dSKaroly Pados FTDI_SIO_SET_BITMODE_REQUEST_TYPE, val, 1821027bf37dSJohan Hovold priv->channel, NULL, 0, WDR_TIMEOUT); 1822ba93cc7dSKaroly Pados if (result < 0) { 1823ba93cc7dSKaroly Pados dev_err(&serial->interface->dev, 1824ba93cc7dSKaroly Pados "bitmode request failed for value 0x%04x: %d\n", 1825ba93cc7dSKaroly Pados val, result); 1826ba93cc7dSKaroly Pados } 1827ba93cc7dSKaroly Pados 1828a8eda9faSKaroly Pados usb_autopm_put_interface(serial->interface); 1829a8eda9faSKaroly Pados 1830ba93cc7dSKaroly Pados return result; 1831ba93cc7dSKaroly Pados } 1832ba93cc7dSKaroly Pados 1833ba93cc7dSKaroly Pados static int ftdi_set_cbus_pins(struct usb_serial_port *port) 1834ba93cc7dSKaroly Pados { 1835ba93cc7dSKaroly Pados return ftdi_set_bitmode(port, FTDI_SIO_BITMODE_CBUS); 1836ba93cc7dSKaroly Pados } 1837ba93cc7dSKaroly Pados 1838ba93cc7dSKaroly Pados static int ftdi_exit_cbus_mode(struct usb_serial_port *port) 1839ba93cc7dSKaroly Pados { 1840ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1841ba93cc7dSKaroly Pados 1842ba93cc7dSKaroly Pados priv->gpio_output = 0; 1843ba93cc7dSKaroly Pados priv->gpio_value = 0; 1844ba93cc7dSKaroly Pados return ftdi_set_bitmode(port, FTDI_SIO_BITMODE_RESET); 1845ba93cc7dSKaroly Pados } 1846ba93cc7dSKaroly Pados 1847ba93cc7dSKaroly Pados static int ftdi_gpio_request(struct gpio_chip *gc, unsigned int offset) 1848ba93cc7dSKaroly Pados { 1849ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1850ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1851ba93cc7dSKaroly Pados int result; 1852ba93cc7dSKaroly Pados 1853ba93cc7dSKaroly Pados mutex_lock(&priv->gpio_lock); 1854ba93cc7dSKaroly Pados if (!priv->gpio_used) { 1855ba93cc7dSKaroly Pados /* Set default pin states, as we cannot get them from device */ 1856ba93cc7dSKaroly Pados priv->gpio_output = 0x00; 1857ba93cc7dSKaroly Pados priv->gpio_value = 0x00; 1858ba93cc7dSKaroly Pados result = ftdi_set_cbus_pins(port); 1859ba93cc7dSKaroly Pados if (result) { 1860ba93cc7dSKaroly Pados mutex_unlock(&priv->gpio_lock); 1861ba93cc7dSKaroly Pados return result; 1862ba93cc7dSKaroly Pados } 1863ba93cc7dSKaroly Pados 1864ba93cc7dSKaroly Pados priv->gpio_used = true; 1865ba93cc7dSKaroly Pados } 1866ba93cc7dSKaroly Pados mutex_unlock(&priv->gpio_lock); 1867ba93cc7dSKaroly Pados 1868ba93cc7dSKaroly Pados return 0; 1869ba93cc7dSKaroly Pados } 1870ba93cc7dSKaroly Pados 1871ba93cc7dSKaroly Pados static int ftdi_read_cbus_pins(struct usb_serial_port *port) 1872ba93cc7dSKaroly Pados { 1873ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1874ba93cc7dSKaroly Pados struct usb_serial *serial = port->serial; 1875a7388592SHimadri Pandya u8 buf; 1876ba93cc7dSKaroly Pados int result; 1877ba93cc7dSKaroly Pados 1878a8eda9faSKaroly Pados result = usb_autopm_get_interface(serial->interface); 1879a8eda9faSKaroly Pados if (result) 1880a8eda9faSKaroly Pados return result; 1881a8eda9faSKaroly Pados 1882a7388592SHimadri Pandya result = usb_control_msg_recv(serial->dev, 0, 1883ba93cc7dSKaroly Pados FTDI_SIO_READ_PINS_REQUEST, 1884ba93cc7dSKaroly Pados FTDI_SIO_READ_PINS_REQUEST_TYPE, 0, 1885027bf37dSJohan Hovold priv->channel, &buf, 1, WDR_TIMEOUT, 1886a7388592SHimadri Pandya GFP_KERNEL); 1887a7388592SHimadri Pandya if (result == 0) 1888a7388592SHimadri Pandya result = buf; 1889ba93cc7dSKaroly Pados 1890a8eda9faSKaroly Pados usb_autopm_put_interface(serial->interface); 1891ba93cc7dSKaroly Pados 1892ba93cc7dSKaroly Pados return result; 1893ba93cc7dSKaroly Pados } 1894ba93cc7dSKaroly Pados 1895ba93cc7dSKaroly Pados static int ftdi_gpio_get(struct gpio_chip *gc, unsigned int gpio) 1896ba93cc7dSKaroly Pados { 1897ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1898ba93cc7dSKaroly Pados int result; 1899ba93cc7dSKaroly Pados 1900ba93cc7dSKaroly Pados result = ftdi_read_cbus_pins(port); 1901ba93cc7dSKaroly Pados if (result < 0) 1902ba93cc7dSKaroly Pados return result; 1903ba93cc7dSKaroly Pados 1904ba93cc7dSKaroly Pados return !!(result & BIT(gpio)); 1905ba93cc7dSKaroly Pados } 1906ba93cc7dSKaroly Pados 1907ba93cc7dSKaroly Pados static void ftdi_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value) 1908ba93cc7dSKaroly Pados { 1909ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1910ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1911ba93cc7dSKaroly Pados 1912ba93cc7dSKaroly Pados mutex_lock(&priv->gpio_lock); 1913ba93cc7dSKaroly Pados 1914ba93cc7dSKaroly Pados if (value) 1915ba93cc7dSKaroly Pados priv->gpio_value |= BIT(gpio); 1916ba93cc7dSKaroly Pados else 1917ba93cc7dSKaroly Pados priv->gpio_value &= ~BIT(gpio); 1918ba93cc7dSKaroly Pados 1919ba93cc7dSKaroly Pados ftdi_set_cbus_pins(port); 1920ba93cc7dSKaroly Pados 1921ba93cc7dSKaroly Pados mutex_unlock(&priv->gpio_lock); 1922ba93cc7dSKaroly Pados } 1923ba93cc7dSKaroly Pados 1924ba93cc7dSKaroly Pados static int ftdi_gpio_get_multiple(struct gpio_chip *gc, unsigned long *mask, 1925ba93cc7dSKaroly Pados unsigned long *bits) 1926ba93cc7dSKaroly Pados { 1927ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1928ba93cc7dSKaroly Pados int result; 1929ba93cc7dSKaroly Pados 1930ba93cc7dSKaroly Pados result = ftdi_read_cbus_pins(port); 1931ba93cc7dSKaroly Pados if (result < 0) 1932ba93cc7dSKaroly Pados return result; 1933ba93cc7dSKaroly Pados 1934ba93cc7dSKaroly Pados *bits = result & *mask; 1935ba93cc7dSKaroly Pados 1936ba93cc7dSKaroly Pados return 0; 1937ba93cc7dSKaroly Pados } 1938ba93cc7dSKaroly Pados 1939ba93cc7dSKaroly Pados static void ftdi_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, 1940ba93cc7dSKaroly Pados unsigned long *bits) 1941ba93cc7dSKaroly Pados { 1942ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1943ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1944ba93cc7dSKaroly Pados 1945ba93cc7dSKaroly Pados mutex_lock(&priv->gpio_lock); 1946ba93cc7dSKaroly Pados 1947ba93cc7dSKaroly Pados priv->gpio_value &= ~(*mask); 1948ba93cc7dSKaroly Pados priv->gpio_value |= *bits & *mask; 1949ba93cc7dSKaroly Pados ftdi_set_cbus_pins(port); 1950ba93cc7dSKaroly Pados 1951ba93cc7dSKaroly Pados mutex_unlock(&priv->gpio_lock); 1952ba93cc7dSKaroly Pados } 1953ba93cc7dSKaroly Pados 1954ba93cc7dSKaroly Pados static int ftdi_gpio_direction_get(struct gpio_chip *gc, unsigned int gpio) 1955ba93cc7dSKaroly Pados { 1956ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1957ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1958ba93cc7dSKaroly Pados 1959ba93cc7dSKaroly Pados return !(priv->gpio_output & BIT(gpio)); 1960ba93cc7dSKaroly Pados } 1961ba93cc7dSKaroly Pados 1962ba93cc7dSKaroly Pados static int ftdi_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio) 1963ba93cc7dSKaroly Pados { 1964ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1965ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1966ba93cc7dSKaroly Pados int result; 1967ba93cc7dSKaroly Pados 1968ba93cc7dSKaroly Pados mutex_lock(&priv->gpio_lock); 1969ba93cc7dSKaroly Pados 1970ba93cc7dSKaroly Pados priv->gpio_output &= ~BIT(gpio); 1971ba93cc7dSKaroly Pados result = ftdi_set_cbus_pins(port); 1972ba93cc7dSKaroly Pados 1973ba93cc7dSKaroly Pados mutex_unlock(&priv->gpio_lock); 1974ba93cc7dSKaroly Pados 1975ba93cc7dSKaroly Pados return result; 1976ba93cc7dSKaroly Pados } 1977ba93cc7dSKaroly Pados 1978ba93cc7dSKaroly Pados static int ftdi_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio, 1979ba93cc7dSKaroly Pados int value) 1980ba93cc7dSKaroly Pados { 1981ba93cc7dSKaroly Pados struct usb_serial_port *port = gpiochip_get_data(gc); 1982ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 1983ba93cc7dSKaroly Pados int result; 1984ba93cc7dSKaroly Pados 1985ba93cc7dSKaroly Pados mutex_lock(&priv->gpio_lock); 1986ba93cc7dSKaroly Pados 1987ba93cc7dSKaroly Pados priv->gpio_output |= BIT(gpio); 1988ba93cc7dSKaroly Pados if (value) 1989ba93cc7dSKaroly Pados priv->gpio_value |= BIT(gpio); 1990ba93cc7dSKaroly Pados else 1991ba93cc7dSKaroly Pados priv->gpio_value &= ~BIT(gpio); 1992ba93cc7dSKaroly Pados 1993ba93cc7dSKaroly Pados result = ftdi_set_cbus_pins(port); 1994ba93cc7dSKaroly Pados 1995ba93cc7dSKaroly Pados mutex_unlock(&priv->gpio_lock); 1996ba93cc7dSKaroly Pados 1997ba93cc7dSKaroly Pados return result; 1998ba93cc7dSKaroly Pados } 1999ba93cc7dSKaroly Pados 200011fb08cfSMarc Zyngier static int ftdi_gpio_init_valid_mask(struct gpio_chip *gc, 200111fb08cfSMarc Zyngier unsigned long *valid_mask, 200211fb08cfSMarc Zyngier unsigned int ngpios) 200311fb08cfSMarc Zyngier { 200411fb08cfSMarc Zyngier struct usb_serial_port *port = gpiochip_get_data(gc); 200511fb08cfSMarc Zyngier struct ftdi_private *priv = usb_get_serial_port_data(port); 200611fb08cfSMarc Zyngier unsigned long map = priv->gpio_altfunc; 200711fb08cfSMarc Zyngier 200811fb08cfSMarc Zyngier bitmap_complement(valid_mask, &map, ngpios); 200911fb08cfSMarc Zyngier 2010fddd408aSMarc Zyngier if (bitmap_empty(valid_mask, ngpios)) 2011fddd408aSMarc Zyngier dev_dbg(&port->dev, "no CBUS pin configured for GPIO\n"); 2012fddd408aSMarc Zyngier else 2013fddd408aSMarc Zyngier dev_dbg(&port->dev, "CBUS%*pbl configured for GPIO\n", ngpios, 2014fddd408aSMarc Zyngier valid_mask); 2015fddd408aSMarc Zyngier 201611fb08cfSMarc Zyngier return 0; 201711fb08cfSMarc Zyngier } 201811fb08cfSMarc Zyngier 2019ba93cc7dSKaroly Pados static int ftdi_read_eeprom(struct usb_serial *serial, void *dst, u16 addr, 2020ba93cc7dSKaroly Pados u16 nbytes) 2021ba93cc7dSKaroly Pados { 2022ba93cc7dSKaroly Pados int read = 0; 2023ba93cc7dSKaroly Pados 2024ba93cc7dSKaroly Pados if (addr % 2 != 0) 2025ba93cc7dSKaroly Pados return -EINVAL; 2026ba93cc7dSKaroly Pados if (nbytes % 2 != 0) 2027ba93cc7dSKaroly Pados return -EINVAL; 2028ba93cc7dSKaroly Pados 2029ba93cc7dSKaroly Pados /* Read EEPROM two bytes at a time */ 2030ba93cc7dSKaroly Pados while (read < nbytes) { 2031ba93cc7dSKaroly Pados int rv; 2032ba93cc7dSKaroly Pados 2033ba93cc7dSKaroly Pados rv = usb_control_msg(serial->dev, 2034ba93cc7dSKaroly Pados usb_rcvctrlpipe(serial->dev, 0), 2035ba93cc7dSKaroly Pados FTDI_SIO_READ_EEPROM_REQUEST, 2036ba93cc7dSKaroly Pados FTDI_SIO_READ_EEPROM_REQUEST_TYPE, 2037ba93cc7dSKaroly Pados 0, (addr + read) / 2, dst + read, 2, 2038ba93cc7dSKaroly Pados WDR_TIMEOUT); 2039ba93cc7dSKaroly Pados if (rv < 2) { 2040ba93cc7dSKaroly Pados if (rv >= 0) 2041ba93cc7dSKaroly Pados return -EIO; 2042ba93cc7dSKaroly Pados else 2043ba93cc7dSKaroly Pados return rv; 2044ba93cc7dSKaroly Pados } 2045ba93cc7dSKaroly Pados 2046ba93cc7dSKaroly Pados read += rv; 2047ba93cc7dSKaroly Pados } 2048ba93cc7dSKaroly Pados 2049ba93cc7dSKaroly Pados return 0; 2050ba93cc7dSKaroly Pados } 2051ba93cc7dSKaroly Pados 20527a786b84SMatthew Michilot static int ftdi_gpio_init_ft232h(struct usb_serial_port *port) 20537a786b84SMatthew Michilot { 20547a786b84SMatthew Michilot struct ftdi_private *priv = usb_get_serial_port_data(port); 20557a786b84SMatthew Michilot u16 cbus_config; 20567a786b84SMatthew Michilot u8 *buf; 20577a786b84SMatthew Michilot int ret; 20587a786b84SMatthew Michilot int i; 20597a786b84SMatthew Michilot 20607a786b84SMatthew Michilot buf = kmalloc(4, GFP_KERNEL); 20617a786b84SMatthew Michilot if (!buf) 20627a786b84SMatthew Michilot return -ENOMEM; 20637a786b84SMatthew Michilot 20647a786b84SMatthew Michilot ret = ftdi_read_eeprom(port->serial, buf, 0x1a, 4); 20657a786b84SMatthew Michilot if (ret < 0) 20667a786b84SMatthew Michilot goto out_free; 20677a786b84SMatthew Michilot 20687a786b84SMatthew Michilot /* 20697a786b84SMatthew Michilot * FT232H CBUS Memory Map 20707a786b84SMatthew Michilot * 20717a786b84SMatthew Michilot * 0x1a: X- (upper nibble -> AC5) 20727a786b84SMatthew Michilot * 0x1b: -X (lower nibble -> AC6) 20737a786b84SMatthew Michilot * 0x1c: XX (upper nibble -> AC9 | lower nibble -> AC8) 20747a786b84SMatthew Michilot */ 20757a786b84SMatthew Michilot cbus_config = buf[2] << 8 | (buf[1] & 0xf) << 4 | (buf[0] & 0xf0) >> 4; 20767a786b84SMatthew Michilot 20777a786b84SMatthew Michilot priv->gc.ngpio = 4; 20787a786b84SMatthew Michilot priv->gpio_altfunc = 0xff; 20797a786b84SMatthew Michilot 20807a786b84SMatthew Michilot for (i = 0; i < priv->gc.ngpio; ++i) { 20817a786b84SMatthew Michilot if ((cbus_config & 0xf) == FTDI_FTX_CBUS_MUX_GPIO) 20827a786b84SMatthew Michilot priv->gpio_altfunc &= ~BIT(i); 20837a786b84SMatthew Michilot cbus_config >>= 4; 20847a786b84SMatthew Michilot } 20857a786b84SMatthew Michilot 20867a786b84SMatthew Michilot out_free: 20877a786b84SMatthew Michilot kfree(buf); 20887a786b84SMatthew Michilot 20897a786b84SMatthew Michilot return ret; 20907a786b84SMatthew Michilot } 20917a786b84SMatthew Michilot 2092ff32d97eSJohan Hovold static int ftdi_gpio_init_ft232r(struct usb_serial_port *port) 2093ff32d97eSJohan Hovold { 2094ff32d97eSJohan Hovold struct ftdi_private *priv = usb_get_serial_port_data(port); 2095ff32d97eSJohan Hovold u16 cbus_config; 2096ff32d97eSJohan Hovold u8 *buf; 2097ff32d97eSJohan Hovold int ret; 2098ff32d97eSJohan Hovold int i; 2099ff32d97eSJohan Hovold 2100ff32d97eSJohan Hovold buf = kmalloc(2, GFP_KERNEL); 2101ff32d97eSJohan Hovold if (!buf) 2102ff32d97eSJohan Hovold return -ENOMEM; 2103ff32d97eSJohan Hovold 2104ff32d97eSJohan Hovold ret = ftdi_read_eeprom(port->serial, buf, 0x14, 2); 2105ff32d97eSJohan Hovold if (ret < 0) 2106ff32d97eSJohan Hovold goto out_free; 2107ff32d97eSJohan Hovold 2108ff32d97eSJohan Hovold cbus_config = le16_to_cpup((__le16 *)buf); 2109ff32d97eSJohan Hovold dev_dbg(&port->dev, "cbus_config = 0x%04x\n", cbus_config); 2110ff32d97eSJohan Hovold 2111ff32d97eSJohan Hovold priv->gc.ngpio = 4; 2112ff32d97eSJohan Hovold 2113ff32d97eSJohan Hovold priv->gpio_altfunc = 0xff; 2114ff32d97eSJohan Hovold for (i = 0; i < priv->gc.ngpio; ++i) { 2115ff32d97eSJohan Hovold if ((cbus_config & 0xf) == FTDI_FT232R_CBUS_MUX_GPIO) 2116ff32d97eSJohan Hovold priv->gpio_altfunc &= ~BIT(i); 2117ff32d97eSJohan Hovold cbus_config >>= 4; 2118ff32d97eSJohan Hovold } 2119ff32d97eSJohan Hovold out_free: 2120ff32d97eSJohan Hovold kfree(buf); 2121ff32d97eSJohan Hovold 2122ff32d97eSJohan Hovold return ret; 2123ff32d97eSJohan Hovold } 2124ff32d97eSJohan Hovold 2125ff32d97eSJohan Hovold static int ftdi_gpio_init_ftx(struct usb_serial_port *port) 2126ba93cc7dSKaroly Pados { 2127ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 2128ba93cc7dSKaroly Pados struct usb_serial *serial = port->serial; 2129ba93cc7dSKaroly Pados const u16 cbus_cfg_addr = 0x1a; 2130ba93cc7dSKaroly Pados const u16 cbus_cfg_size = 4; 2131ba93cc7dSKaroly Pados u8 *cbus_cfg_buf; 2132ba93cc7dSKaroly Pados int result; 2133ba93cc7dSKaroly Pados u8 i; 2134ba93cc7dSKaroly Pados 2135ba93cc7dSKaroly Pados cbus_cfg_buf = kmalloc(cbus_cfg_size, GFP_KERNEL); 2136ba93cc7dSKaroly Pados if (!cbus_cfg_buf) 2137ba93cc7dSKaroly Pados return -ENOMEM; 2138ba93cc7dSKaroly Pados 2139ba93cc7dSKaroly Pados result = ftdi_read_eeprom(serial, cbus_cfg_buf, 2140ba93cc7dSKaroly Pados cbus_cfg_addr, cbus_cfg_size); 2141ba93cc7dSKaroly Pados if (result < 0) 2142ba93cc7dSKaroly Pados goto out_free; 2143ba93cc7dSKaroly Pados 2144ba93cc7dSKaroly Pados /* FIXME: FT234XD alone has 1 GPIO, but how to recognize this IC? */ 2145ba93cc7dSKaroly Pados priv->gc.ngpio = 4; 2146ba93cc7dSKaroly Pados 2147ba93cc7dSKaroly Pados /* Determine which pins are configured for CBUS bitbanging */ 2148ba93cc7dSKaroly Pados priv->gpio_altfunc = 0xff; 2149ba93cc7dSKaroly Pados for (i = 0; i < priv->gc.ngpio; ++i) { 2150ba93cc7dSKaroly Pados if (cbus_cfg_buf[i] == FTDI_FTX_CBUS_MUX_GPIO) 2151ba93cc7dSKaroly Pados priv->gpio_altfunc &= ~BIT(i); 2152ba93cc7dSKaroly Pados } 2153ba93cc7dSKaroly Pados 2154ba93cc7dSKaroly Pados out_free: 2155ba93cc7dSKaroly Pados kfree(cbus_cfg_buf); 2156ba93cc7dSKaroly Pados 2157ba93cc7dSKaroly Pados return result; 2158ba93cc7dSKaroly Pados } 2159ba93cc7dSKaroly Pados 2160ba93cc7dSKaroly Pados static int ftdi_gpio_init(struct usb_serial_port *port) 2161ba93cc7dSKaroly Pados { 2162ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 2163ba93cc7dSKaroly Pados struct usb_serial *serial = port->serial; 2164ba93cc7dSKaroly Pados int result; 2165ba93cc7dSKaroly Pados 2166ba93cc7dSKaroly Pados switch (priv->chip_type) { 21677a786b84SMatthew Michilot case FT232H: 21687a786b84SMatthew Michilot result = ftdi_gpio_init_ft232h(port); 21697a786b84SMatthew Michilot break; 217001aeb31fSJohan Hovold case FT232R: 2171ff32d97eSJohan Hovold result = ftdi_gpio_init_ft232r(port); 2172ff32d97eSJohan Hovold break; 2173ba93cc7dSKaroly Pados case FTX: 2174ff32d97eSJohan Hovold result = ftdi_gpio_init_ftx(port); 2175ba93cc7dSKaroly Pados break; 2176ba93cc7dSKaroly Pados default: 2177ba93cc7dSKaroly Pados return 0; 2178ba93cc7dSKaroly Pados } 2179ba93cc7dSKaroly Pados 2180ba93cc7dSKaroly Pados if (result < 0) 2181ba93cc7dSKaroly Pados return result; 2182ba93cc7dSKaroly Pados 2183ba93cc7dSKaroly Pados mutex_init(&priv->gpio_lock); 2184ba93cc7dSKaroly Pados 2185ba93cc7dSKaroly Pados priv->gc.label = "ftdi-cbus"; 2186ba93cc7dSKaroly Pados priv->gc.request = ftdi_gpio_request; 2187ba93cc7dSKaroly Pados priv->gc.get_direction = ftdi_gpio_direction_get; 2188ba93cc7dSKaroly Pados priv->gc.direction_input = ftdi_gpio_direction_input; 2189ba93cc7dSKaroly Pados priv->gc.direction_output = ftdi_gpio_direction_output; 219011fb08cfSMarc Zyngier priv->gc.init_valid_mask = ftdi_gpio_init_valid_mask; 2191ba93cc7dSKaroly Pados priv->gc.get = ftdi_gpio_get; 2192ba93cc7dSKaroly Pados priv->gc.set = ftdi_gpio_set; 2193ba93cc7dSKaroly Pados priv->gc.get_multiple = ftdi_gpio_get_multiple; 2194ba93cc7dSKaroly Pados priv->gc.set_multiple = ftdi_gpio_set_multiple; 2195ba93cc7dSKaroly Pados priv->gc.owner = THIS_MODULE; 2196ba93cc7dSKaroly Pados priv->gc.parent = &serial->interface->dev; 2197ba93cc7dSKaroly Pados priv->gc.base = -1; 2198ba93cc7dSKaroly Pados priv->gc.can_sleep = true; 2199ba93cc7dSKaroly Pados 2200ba93cc7dSKaroly Pados result = gpiochip_add_data(&priv->gc, port); 2201ba93cc7dSKaroly Pados if (!result) 2202ba93cc7dSKaroly Pados priv->gpio_registered = true; 2203ba93cc7dSKaroly Pados 2204ba93cc7dSKaroly Pados return result; 2205ba93cc7dSKaroly Pados } 2206ba93cc7dSKaroly Pados 2207ba93cc7dSKaroly Pados static void ftdi_gpio_remove(struct usb_serial_port *port) 2208ba93cc7dSKaroly Pados { 2209ba93cc7dSKaroly Pados struct ftdi_private *priv = usb_get_serial_port_data(port); 2210ba93cc7dSKaroly Pados 2211ba93cc7dSKaroly Pados if (priv->gpio_registered) { 2212ba93cc7dSKaroly Pados gpiochip_remove(&priv->gc); 2213ba93cc7dSKaroly Pados priv->gpio_registered = false; 2214ba93cc7dSKaroly Pados } 2215ba93cc7dSKaroly Pados 2216ba93cc7dSKaroly Pados if (priv->gpio_used) { 2217ba93cc7dSKaroly Pados /* Exiting CBUS-mode does not reset pin states. */ 2218ba93cc7dSKaroly Pados ftdi_exit_cbus_mode(port); 2219ba93cc7dSKaroly Pados priv->gpio_used = false; 2220ba93cc7dSKaroly Pados } 2221ba93cc7dSKaroly Pados } 2222ba93cc7dSKaroly Pados 2223ba93cc7dSKaroly Pados #else 2224ba93cc7dSKaroly Pados 2225ba93cc7dSKaroly Pados static int ftdi_gpio_init(struct usb_serial_port *port) 2226ba93cc7dSKaroly Pados { 2227ba93cc7dSKaroly Pados return 0; 2228ba93cc7dSKaroly Pados } 2229ba93cc7dSKaroly Pados 2230ba93cc7dSKaroly Pados static void ftdi_gpio_remove(struct usb_serial_port *port) { } 2231ba93cc7dSKaroly Pados 2232ba93cc7dSKaroly Pados #endif /* CONFIG_GPIOLIB */ 2233ba93cc7dSKaroly Pados 22341da177e4SLinus Torvalds /* 22351da177e4SLinus Torvalds * *************************************************************************** 22361da177e4SLinus Torvalds * FTDI driver specific functions 22371da177e4SLinus Torvalds * *************************************************************************** 22381da177e4SLinus Torvalds */ 22391da177e4SLinus Torvalds 22408f977e42SIan Abbott /* Probe function to check for special devices */ 2241464cbb24SAlan Cox static int ftdi_sio_probe(struct usb_serial *serial, 2242464cbb24SAlan Cox const struct usb_device_id *id) 22438f977e42SIan Abbott { 22443c77f7c9SJulia Lawall const struct ftdi_sio_quirk *quirk = 2245464cbb24SAlan Cox (struct ftdi_sio_quirk *)id->driver_info; 2246fa91d43bSTony Lindgren 2247fa91d43bSTony Lindgren if (quirk && quirk->probe) { 2248fa91d43bSTony Lindgren int ret = quirk->probe(serial); 2249fa91d43bSTony Lindgren if (ret != 0) 2250fa91d43bSTony Lindgren return ret; 2251fa91d43bSTony Lindgren } 2252fa91d43bSTony Lindgren 22538f977e42SIan Abbott usb_set_serial_data(serial, (void *)id->driver_info); 22548f977e42SIan Abbott 2255fa91d43bSTony Lindgren return 0; 22568f977e42SIan Abbott } 22578f977e42SIan Abbott 225812bdbe03SJim Radford static int ftdi_sio_port_probe(struct usb_serial_port *port) 22591da177e4SLinus Torvalds { 22601da177e4SLinus Torvalds struct ftdi_private *priv; 22613c77f7c9SJulia Lawall const struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial); 2262ba93cc7dSKaroly Pados int result; 22631da177e4SLinus Torvalds 226480b6ca48SEric Sesterhenn priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); 226510c642d0SJohan Hovold if (!priv) 22661da177e4SLinus Torvalds return -ENOMEM; 22671da177e4SLinus Torvalds 2268bd09a9f5SAlessio Igor Bogani mutex_init(&priv->cfg_lock); 22690076b4beSJohan Hovold 22700ffbbe25SOliver Neukum if (quirk && quirk->port_probe) 22710ffbbe25SOliver Neukum quirk->port_probe(priv); 22720ffbbe25SOliver Neukum 227312bdbe03SJim Radford usb_set_serial_port_data(port, priv); 22741da177e4SLinus Torvalds 2275f353c0d4SJohan Hovold result = ftdi_determine_type(port); 2276f353c0d4SJohan Hovold if (result) 2277f353c0d4SJohan Hovold goto err_free; 2278f353c0d4SJohan Hovold 2279895f28baSMark Adamson ftdi_set_max_packet_size(port); 22808c4f99cdSJohan Hovold if (read_latency_timer(port) < 0) 22818c4f99cdSJohan Hovold priv->latency = 16; 2282c19db4c9SJohan Hovold write_latency_timer(port); 2283ba93cc7dSKaroly Pados 2284ba93cc7dSKaroly Pados result = ftdi_gpio_init(port); 2285ba93cc7dSKaroly Pados if (result < 0) { 2286ba93cc7dSKaroly Pados dev_err(&port->serial->interface->dev, 2287ba93cc7dSKaroly Pados "GPIO initialisation failed: %d\n", 2288ba93cc7dSKaroly Pados result); 2289ba93cc7dSKaroly Pados } 2290ba93cc7dSKaroly Pados 229112bdbe03SJim Radford return 0; 2292f353c0d4SJohan Hovold 2293f353c0d4SJohan Hovold err_free: 2294f353c0d4SJohan Hovold kfree(priv); 2295f353c0d4SJohan Hovold 2296f353c0d4SJohan Hovold return result; 22971da177e4SLinus Torvalds } 22981da177e4SLinus Torvalds 22998f977e42SIan Abbott /* Setup for the USB-UIRT device, which requires hardwired 23008f977e42SIan Abbott * baudrate (38400 gets mapped to 312500) */ 23011da177e4SLinus Torvalds /* Called from usbserial:serial_probe */ 23020ffbbe25SOliver Neukum static void ftdi_USB_UIRT_setup(struct ftdi_private *priv) 23031da177e4SLinus Torvalds { 23041da177e4SLinus Torvalds priv->flags |= ASYNC_SPD_CUST; 23051da177e4SLinus Torvalds priv->custom_divisor = 77; 2306669a6db1SAlan Cox priv->force_baud = 38400; 2307e49bbce1SJohan Hovold } 23081da177e4SLinus Torvalds 23098f977e42SIan Abbott /* Setup for the HE-TIRA1 device, which requires hardwired 23108f977e42SIan Abbott * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ 2311464cbb24SAlan Cox 23120ffbbe25SOliver Neukum static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) 23138f977e42SIan Abbott { 23141da177e4SLinus Torvalds priv->flags |= ASYNC_SPD_CUST; 23151da177e4SLinus Torvalds priv->custom_divisor = 240; 2316669a6db1SAlan Cox priv->force_baud = 38400; 23171da177e4SLinus Torvalds priv->force_rtscts = 1; 2318e49bbce1SJohan Hovold } 23191da177e4SLinus Torvalds 2320fa91d43bSTony Lindgren /* 2321b760dac2SMartin Geleynse * Module parameter to control latency timer for NDI FTDI-based USB devices. 2322970e2486SLucas De Marchi * If this value is not set in /etc/modprobe.d/ its value will be set 2323970e2486SLucas De Marchi * to 1ms. 2324b760dac2SMartin Geleynse */ 2325b760dac2SMartin Geleynse static int ndi_latency_timer = 1; 2326b760dac2SMartin Geleynse 2327b760dac2SMartin Geleynse /* Setup for the NDI FTDI-based USB devices, which requires hardwired 2328b760dac2SMartin Geleynse * baudrate (19200 gets mapped to 1200000). 2329b760dac2SMartin Geleynse * 2330b760dac2SMartin Geleynse * Called from usbserial:serial_probe. 2331b760dac2SMartin Geleynse */ 2332b760dac2SMartin Geleynse static int ftdi_NDI_device_setup(struct usb_serial *serial) 2333b760dac2SMartin Geleynse { 2334b760dac2SMartin Geleynse struct usb_device *udev = serial->dev; 2335b760dac2SMartin Geleynse int latency = ndi_latency_timer; 2336b760dac2SMartin Geleynse 2337b760dac2SMartin Geleynse if (latency == 0) 2338b760dac2SMartin Geleynse latency = 1; 2339b760dac2SMartin Geleynse if (latency > 99) 2340b760dac2SMartin Geleynse latency = 99; 2341b760dac2SMartin Geleynse 2342bfc51614SGreg Kroah-Hartman dev_dbg(&udev->dev, "%s setting NDI device latency to %d\n", __func__, latency); 2343bfc51614SGreg Kroah-Hartman dev_info(&udev->dev, "NDI device with a latency value of %d\n", latency); 2344b760dac2SMartin Geleynse 2345c1284d77SJohan Hovold /* FIXME: errors are not returned */ 2346c1284d77SJohan Hovold usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 2347b760dac2SMartin Geleynse FTDI_SIO_SET_LATENCY_TIMER_REQUEST, 2348b760dac2SMartin Geleynse FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, 234966e47e60SJohan Hovold latency, 0, NULL, 0, WDR_TIMEOUT); 2350b760dac2SMartin Geleynse return 0; 2351b760dac2SMartin Geleynse } 2352b760dac2SMartin Geleynse 2353b760dac2SMartin Geleynse /* 235420734345SHarald Welte * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko 235520734345SHarald Welte * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from 235620734345SHarald Welte * userspace using openocd. 2357fa91d43bSTony Lindgren */ 235820734345SHarald Welte static int ftdi_jtag_probe(struct usb_serial *serial) 2359fa91d43bSTony Lindgren { 236075240ac4SJohan Hovold struct usb_interface *intf = serial->interface; 236175240ac4SJohan Hovold int ifnum = intf->cur_altsetting->desc.bInterfaceNumber; 2362fa91d43bSTony Lindgren 236375240ac4SJohan Hovold if (ifnum == 0) { 236475240ac4SJohan Hovold dev_info(&intf->dev, "Ignoring interface reserved for JTAG\n"); 2365fa91d43bSTony Lindgren return -ENODEV; 2366fa91d43bSTony Lindgren } 2367fa91d43bSTony Lindgren 2368fa91d43bSTony Lindgren return 0; 2369fa91d43bSTony Lindgren } 23701da177e4SLinus Torvalds 2371c96fbdd0SJean-Christophe PLAGNIOL-VILLARD static int ftdi_8u2232c_probe(struct usb_serial *serial) 2372c96fbdd0SJean-Christophe PLAGNIOL-VILLARD { 2373c96fbdd0SJean-Christophe PLAGNIOL-VILLARD struct usb_device *udev = serial->dev; 2374c96fbdd0SJean-Christophe PLAGNIOL-VILLARD 2375b229a0f8SDoug Goldstein if (udev->manufacturer && !strcmp(udev->manufacturer, "CALAO Systems")) 2376b229a0f8SDoug Goldstein return ftdi_jtag_probe(serial); 2377b229a0f8SDoug Goldstein 2378b229a0f8SDoug Goldstein if (udev->product && 2379470b5d6fSVasyl Vavrychuk (!strcmp(udev->product, "Arrow USB Blaster") || 2380470b5d6fSVasyl Vavrychuk !strcmp(udev->product, "BeagleBone/XDS100V2") || 2381b229a0f8SDoug Goldstein !strcmp(udev->product, "SNAP Connect E10"))) 2382c96fbdd0SJean-Christophe PLAGNIOL-VILLARD return ftdi_jtag_probe(serial); 2383c96fbdd0SJean-Christophe PLAGNIOL-VILLARD 2384c96fbdd0SJean-Christophe PLAGNIOL-VILLARD return 0; 2385c96fbdd0SJean-Christophe PLAGNIOL-VILLARD } 2386c96fbdd0SJean-Christophe PLAGNIOL-VILLARD 2387546d7eecSKevin Vance /* 238871d9a2b9SAdrian Thomasset * First two ports on JTAG adaptors using an FT4232 such as STMicroelectronics's 238971d9a2b9SAdrian Thomasset * ST Micro Connect Lite are reserved for JTAG or other non-UART interfaces and 239071d9a2b9SAdrian Thomasset * can be accessed from userspace. 239171d9a2b9SAdrian Thomasset * The next two ports are enabled as UARTs by default, where port 2 is 239271d9a2b9SAdrian Thomasset * a conventional RS-232 UART. 23936ec2f46cSJean-Christophe PLAGNIOL-VILLARD */ 23946ec2f46cSJean-Christophe PLAGNIOL-VILLARD static int ftdi_stmclite_probe(struct usb_serial *serial) 23956ec2f46cSJean-Christophe PLAGNIOL-VILLARD { 239675240ac4SJohan Hovold struct usb_interface *intf = serial->interface; 239775240ac4SJohan Hovold int ifnum = intf->cur_altsetting->desc.bInterfaceNumber; 23986ec2f46cSJean-Christophe PLAGNIOL-VILLARD 239975240ac4SJohan Hovold if (ifnum < 2) { 240075240ac4SJohan Hovold dev_info(&intf->dev, "Ignoring interface reserved for JTAG\n"); 24016ec2f46cSJean-Christophe PLAGNIOL-VILLARD return -ENODEV; 24026ec2f46cSJean-Christophe PLAGNIOL-VILLARD } 24036ec2f46cSJean-Christophe PLAGNIOL-VILLARD 240471d9a2b9SAdrian Thomasset return 0; 240571d9a2b9SAdrian Thomasset } 240671d9a2b9SAdrian Thomasset 2407c5d1448fSUwe Kleine-König static void ftdi_sio_port_remove(struct usb_serial_port *port) 240812bdbe03SJim Radford { 24091da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 24101da177e4SLinus Torvalds 2411ba93cc7dSKaroly Pados ftdi_gpio_remove(port); 2412ba93cc7dSKaroly Pados 24134cba98ffSJohan Hovold kfree(priv); 241412bdbe03SJim Radford } 24151da177e4SLinus Torvalds 2416a509a7e4SAlan Cox static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) 2417e49bbce1SJohan Hovold { 24181da177e4SLinus Torvalds struct usb_device *dev = port->serial->dev; 24191da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 24201da177e4SLinus Torvalds 24211da177e4SLinus Torvalds /* No error checking for this (will get errors later anyway) */ 24221da177e4SLinus Torvalds /* See ftdi_sio.h for description of what is reset */ 24231da177e4SLinus Torvalds usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 24241da177e4SLinus Torvalds FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, 24251da177e4SLinus Torvalds FTDI_SIO_RESET_SIO, 2426027bf37dSJohan Hovold priv->channel, NULL, 0, WDR_TIMEOUT); 24271da177e4SLinus Torvalds 24281da177e4SLinus Torvalds /* Termios defaults are set by usb_serial_init. We don't change 2429c4f01240SNick Andrew port->tty->termios - this would lose speed settings, etc. 24301da177e4SLinus Torvalds This is same behaviour as serial.c/rs_open() - Kuba */ 24311da177e4SLinus Torvalds 24321da177e4SLinus Torvalds /* ftdi_set_termios will send usb control messages */ 2433be0278ccSJohan Hovold if (tty) 2434be0278ccSJohan Hovold ftdi_set_termios(tty, port, NULL); 24351da177e4SLinus Torvalds 24364cba98ffSJohan Hovold return usb_serial_generic_open(tty, port); 2437e49bbce1SJohan Hovold } 24381da177e4SLinus Torvalds 2439335f8514SAlan Cox static void ftdi_dtr_rts(struct usb_serial_port *port, int on) 2440335f8514SAlan Cox { 2441335f8514SAlan Cox struct ftdi_private *priv = usb_get_serial_port_data(port); 2442335f8514SAlan Cox 2443335f8514SAlan Cox /* Disable flow control */ 2444b2ca6990SJohan Hovold if (!on) { 2445b2ca6990SJohan Hovold if (usb_control_msg(port->serial->dev, 2446335f8514SAlan Cox usb_sndctrlpipe(port->serial->dev, 0), 2447335f8514SAlan Cox FTDI_SIO_SET_FLOW_CTRL_REQUEST, 2448335f8514SAlan Cox FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 2449027bf37dSJohan Hovold 0, priv->channel, NULL, 0, 2450335f8514SAlan Cox WDR_TIMEOUT) < 0) { 2451335f8514SAlan Cox dev_err(&port->dev, "error from flowcontrol urb\n"); 2452335f8514SAlan Cox } 2453b2ca6990SJohan Hovold } 2454335f8514SAlan Cox /* drop RTS and DTR */ 2455335f8514SAlan Cox if (on) 2456335f8514SAlan Cox set_mctrl(port, TIOCM_DTR | TIOCM_RTS); 2457335f8514SAlan Cox else 2458335f8514SAlan Cox clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); 2459335f8514SAlan Cox } 24601da177e4SLinus Torvalds 24611da177e4SLinus Torvalds /* The SIO requires the first byte to have: 24621da177e4SLinus Torvalds * B0 1 24631da177e4SLinus Torvalds * B1 0 24641da177e4SLinus Torvalds * B2..7 length of message excluding byte 0 24651da177e4SLinus Torvalds * 24661da177e4SLinus Torvalds * The new devices do not require this byte 24671da177e4SLinus Torvalds */ 2468d3901a06SJohan Hovold static int ftdi_prepare_write_buffer(struct usb_serial_port *port, 2469c23e5fc1SJohan Hovold void *dest, size_t size) 2470e49bbce1SJohan Hovold { 2471d3901a06SJohan Hovold struct ftdi_private *priv; 2472c23e5fc1SJohan Hovold int count; 2473c23e5fc1SJohan Hovold unsigned long flags; 24741da177e4SLinus Torvalds 2475d3901a06SJohan Hovold priv = usb_get_serial_port_data(port); 24761da177e4SLinus Torvalds 2477e8770484SJohan Hovold if (priv->chip_type == SIO) { 2478c23e5fc1SJohan Hovold unsigned char *buffer = dest; 2479c23e5fc1SJohan Hovold int i, len, c; 24801da177e4SLinus Torvalds 2481c23e5fc1SJohan Hovold count = 0; 2482c23e5fc1SJohan Hovold spin_lock_irqsave(&port->lock, flags); 2483c23e5fc1SJohan Hovold for (i = 0; i < size - 1; i += priv->max_packet_size) { 2484c23e5fc1SJohan Hovold len = min_t(int, size - i, priv->max_packet_size) - 1; 2485c23e5fc1SJohan Hovold c = kfifo_out(&port->write_fifo, &buffer[i + 1], len); 2486c23e5fc1SJohan Hovold if (!c) 2487c23e5fc1SJohan Hovold break; 2488cb1676a6SJohan Hovold port->icount.tx += c; 2489c1aa075aSJohan Hovold buffer[i] = (c << 2) + 1; 2490c23e5fc1SJohan Hovold count += c + 1; 24911da177e4SLinus Torvalds } 2492c23e5fc1SJohan Hovold spin_unlock_irqrestore(&port->lock, flags); 24931da177e4SLinus Torvalds } else { 2494c23e5fc1SJohan Hovold count = kfifo_out_locked(&port->write_fifo, dest, size, 2495c23e5fc1SJohan Hovold &port->lock); 2496cb1676a6SJohan Hovold port->icount.tx += count; 24971da177e4SLinus Torvalds } 24981da177e4SLinus Torvalds 24991da177e4SLinus Torvalds return count; 250095da310eSAlan Cox } 25011da177e4SLinus Torvalds 2502166ceb69SJohan Hovold #define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE) 2503166ceb69SJohan Hovold 250492a19f9cSJiri Slaby static int ftdi_process_packet(struct usb_serial_port *port, 2505ab4cc4efSJohan Hovold struct ftdi_private *priv, unsigned char *buf, int len) 250695da310eSAlan Cox { 2507ab4cc4efSJohan Hovold unsigned char status; 2508733fff67SJohan Hovold bool brkint = false; 25091da177e4SLinus Torvalds int i; 2510cc01f17dSJohan Hovold char flag; 25111da177e4SLinus Torvalds 2512cc01f17dSJohan Hovold if (len < 2) { 2513bfc51614SGreg Kroah-Hartman dev_dbg(&port->dev, "malformed packet\n"); 2514cc01f17dSJohan Hovold return 0; 25151da177e4SLinus Torvalds } 25161da177e4SLinus Torvalds 2517464cbb24SAlan Cox /* Compare new line status to the old one, signal if different/ 2518464cbb24SAlan Cox N.B. packet may be processed more than once, but differences 2519464cbb24SAlan Cox are only processed once. */ 2520ab4cc4efSJohan Hovold status = buf[0] & FTDI_STATUS_B0_MASK; 2521cc01f17dSJohan Hovold if (status != priv->prev_status) { 2522fca5430dSSimon Arlott char diff_status = status ^ priv->prev_status; 2523fca5430dSSimon Arlott 2524fca5430dSSimon Arlott if (diff_status & FTDI_RS0_CTS) 2525cb1676a6SJohan Hovold port->icount.cts++; 2526fca5430dSSimon Arlott if (diff_status & FTDI_RS0_DSR) 2527cb1676a6SJohan Hovold port->icount.dsr++; 2528fca5430dSSimon Arlott if (diff_status & FTDI_RS0_RI) 2529cb1676a6SJohan Hovold port->icount.rng++; 2530d14654dfSPaul Chavent if (diff_status & FTDI_RS0_RLSD) { 2531d14654dfSPaul Chavent struct tty_struct *tty; 2532d14654dfSPaul Chavent 2533cb1676a6SJohan Hovold port->icount.dcd++; 2534d14654dfSPaul Chavent tty = tty_port_tty_get(&port->port); 2535d14654dfSPaul Chavent if (tty) 2536d14654dfSPaul Chavent usb_serial_handle_dcd_change(port, tty, 2537d14654dfSPaul Chavent status & FTDI_RS0_RLSD); 2538d14654dfSPaul Chavent tty_kref_put(tty); 2539d14654dfSPaul Chavent } 2540fca5430dSSimon Arlott 2541f307e5cdSJohan Hovold wake_up_interruptible(&port->port.delta_msr_wait); 2542cc01f17dSJohan Hovold priv->prev_status = status; 25431da177e4SLinus Torvalds } 25441da177e4SLinus Torvalds 2545a6bb1e17SJohan Hovold /* save if the transmitter is empty or not */ 2546ab4cc4efSJohan Hovold if (buf[1] & FTDI_RS_TEMT) 2547a6bb1e17SJohan Hovold priv->transmit_empty = 1; 2548a6bb1e17SJohan Hovold else 2549a6bb1e17SJohan Hovold priv->transmit_empty = 0; 2550a6bb1e17SJohan Hovold 2551ce054039SJohan Hovold if (len == 2) 2552a6bb1e17SJohan Hovold return 0; /* status only */ 2553a6bb1e17SJohan Hovold 2554a6bb1e17SJohan Hovold /* 2555a6bb1e17SJohan Hovold * Break and error status must only be processed for packets with 2556a6bb1e17SJohan Hovold * data payload to avoid over-reporting. 2557a6bb1e17SJohan Hovold */ 2558cc01f17dSJohan Hovold flag = TTY_NORMAL; 2559ab4cc4efSJohan Hovold if (buf[1] & FTDI_RS_ERR_MASK) { 2560733fff67SJohan Hovold /* 2561733fff67SJohan Hovold * Break takes precedence over parity, which takes precedence 2562733fff67SJohan Hovold * over framing errors. Note that break is only associated 2563733fff67SJohan Hovold * with the last character in the buffer and only when it's a 2564733fff67SJohan Hovold * NUL. 2565733fff67SJohan Hovold */ 2566733fff67SJohan Hovold if (buf[1] & FTDI_RS_BI && buf[len - 1] == '\0') { 2567cb1676a6SJohan Hovold port->icount.brk++; 2568733fff67SJohan Hovold brkint = true; 2569733fff67SJohan Hovold } 2570733fff67SJohan Hovold if (buf[1] & FTDI_RS_PE) { 2571cc01f17dSJohan Hovold flag = TTY_PARITY; 2572cb1676a6SJohan Hovold port->icount.parity++; 2573ab4cc4efSJohan Hovold } else if (buf[1] & FTDI_RS_FE) { 2574cc01f17dSJohan Hovold flag = TTY_FRAME; 2575cb1676a6SJohan Hovold port->icount.frame++; 2576166ceb69SJohan Hovold } 2577166ceb69SJohan Hovold /* Overrun is special, not associated with a char */ 2578ab4cc4efSJohan Hovold if (buf[1] & FTDI_RS_OE) { 2579cb1676a6SJohan Hovold port->icount.overrun++; 258092a19f9cSJiri Slaby tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); 25811da177e4SLinus Torvalds } 2582005b3cdeSUwe Bonnes } 25831da177e4SLinus Torvalds 2584ce054039SJohan Hovold port->icount.rx += len - 2; 2585cc01f17dSJohan Hovold 258637ae2315SJohan Hovold if (brkint || port->sysrq) { 2587ce054039SJohan Hovold for (i = 2; i < len; i++) { 2588733fff67SJohan Hovold if (brkint && i == len - 1) { 2589733fff67SJohan Hovold if (usb_serial_handle_break(port)) 2590733fff67SJohan Hovold return len - 3; 2591733fff67SJohan Hovold flag = TTY_BREAK; 2592733fff67SJohan Hovold } 2593ce054039SJohan Hovold if (usb_serial_handle_sysrq_char(port, buf[i])) 2594ce054039SJohan Hovold continue; 2595ce054039SJohan Hovold tty_insert_flip_char(&port->port, buf[i], flag); 2596cc01f17dSJohan Hovold } 259749b2597aSJohan Hovold } else { 2598ce054039SJohan Hovold tty_insert_flip_string_fixed_flag(&port->port, buf + 2, flag, 2599ce054039SJohan Hovold len - 2); 2600cc01f17dSJohan Hovold } 260149b2597aSJohan Hovold 2602ce054039SJohan Hovold return len - 2; 2603cc01f17dSJohan Hovold } 2604cc01f17dSJohan Hovold 26051b551015SJohan Hovold static void ftdi_process_read_urb(struct urb *urb) 2606cc01f17dSJohan Hovold { 26071b551015SJohan Hovold struct usb_serial_port *port = urb->context; 2608cc01f17dSJohan Hovold struct ftdi_private *priv = usb_get_serial_port_data(port); 2609eb0c68eaSJohan Hovold char *data = urb->transfer_buffer; 2610cc01f17dSJohan Hovold int i; 2611cc01f17dSJohan Hovold int len; 2612cc01f17dSJohan Hovold int count = 0; 2613cc01f17dSJohan Hovold 2614cc01f17dSJohan Hovold for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { 2615cc01f17dSJohan Hovold len = min_t(int, urb->actual_length - i, priv->max_packet_size); 261692a19f9cSJiri Slaby count += ftdi_process_packet(port, priv, &data[i], len); 2617cc01f17dSJohan Hovold } 2618cc01f17dSJohan Hovold 2619cc01f17dSJohan Hovold if (count) 26202e124b4aSJiri Slaby tty_flip_buffer_push(&port->port); 2621cc01f17dSJohan Hovold } 26221da177e4SLinus Torvalds 262395da310eSAlan Cox static void ftdi_break_ctl(struct tty_struct *tty, int break_state) 26241da177e4SLinus Torvalds { 262595da310eSAlan Cox struct usb_serial_port *port = tty->driver_data; 26261da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 262716410115SJohan Hovold u16 value; 26281da177e4SLinus Torvalds 26291da177e4SLinus Torvalds /* break_state = -1 to turn on break, and 0 to turn off break */ 26301da177e4SLinus Torvalds /* see drivers/char/tty_io.c to see it used */ 263116410115SJohan Hovold /* last_set_data_value NEVER has the break bit set in it */ 26321da177e4SLinus Torvalds 2633464cbb24SAlan Cox if (break_state) 263416410115SJohan Hovold value = priv->last_set_data_value | FTDI_SIO_SET_BREAK; 2635464cbb24SAlan Cox else 263616410115SJohan Hovold value = priv->last_set_data_value; 26371da177e4SLinus Torvalds 2638464cbb24SAlan Cox if (usb_control_msg(port->serial->dev, 2639464cbb24SAlan Cox usb_sndctrlpipe(port->serial->dev, 0), 26401da177e4SLinus Torvalds FTDI_SIO_SET_DATA_REQUEST, 26411da177e4SLinus Torvalds FTDI_SIO_SET_DATA_REQUEST_TYPE, 2642027bf37dSJohan Hovold value, priv->channel, 264366e47e60SJohan Hovold NULL, 0, WDR_TIMEOUT) < 0) { 2644bfc51614SGreg Kroah-Hartman dev_err(&port->dev, "%s FAILED to enable/disable break state (state was %d)\n", 2645bfc51614SGreg Kroah-Hartman __func__, break_state); 26461da177e4SLinus Torvalds } 26471da177e4SLinus Torvalds 2648bfc51614SGreg Kroah-Hartman dev_dbg(&port->dev, "%s break state is %d - urb is %d\n", __func__, 264916410115SJohan Hovold break_state, value); 26501da177e4SLinus Torvalds 26511da177e4SLinus Torvalds } 26521da177e4SLinus Torvalds 2653a37025b5SJohan Hovold static bool ftdi_tx_empty(struct usb_serial_port *port) 26546f602912SJarkko Huijts { 26555fb0432eSJohan Hovold unsigned char buf[2]; 26566f602912SJarkko Huijts int ret; 26576f602912SJarkko Huijts 2658c4133648SJohan Hovold ret = ftdi_get_modem_status(port, buf); 26595fb0432eSJohan Hovold if (ret == 2) { 26606f602912SJarkko Huijts if (!(buf[1] & FTDI_RS_TEMT)) 2661a37025b5SJohan Hovold return false; 26625fb0432eSJohan Hovold } 26636f602912SJarkko Huijts 2664a37025b5SJohan Hovold return true; 26656f602912SJarkko Huijts } 26666f602912SJarkko Huijts 26671da177e4SLinus Torvalds /* old_termios contains the original termios settings and tty->termios contains 26681da177e4SLinus Torvalds * the new setting to be used 26691da177e4SLinus Torvalds * WARNING: set_termios calls this with old_termios in kernel space 26701da177e4SLinus Torvalds */ 267195da310eSAlan Cox static void ftdi_set_termios(struct tty_struct *tty, 267295da310eSAlan Cox struct usb_serial_port *port, struct ktermios *old_termios) 2673e49bbce1SJohan Hovold { 26741da177e4SLinus Torvalds struct usb_device *dev = port->serial->dev; 2675bfc51614SGreg Kroah-Hartman struct device *ddev = &port->dev; 26761da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 2677adc8d746SAlan Cox struct ktermios *termios = &tty->termios; 2678669a6db1SAlan Cox unsigned int cflag = termios->c_cflag; 2679df1cd63dSJohan Hovold u16 value, index; 2680df1cd63dSJohan Hovold int ret; 26811da177e4SLinus Torvalds 2682464cbb24SAlan Cox /* Force baud rate if this device requires it, unless it is set to 2683464cbb24SAlan Cox B0. */ 2684669a6db1SAlan Cox if (priv->force_baud && ((termios->c_cflag & CBAUD) != B0)) { 2685bfc51614SGreg Kroah-Hartman dev_dbg(ddev, "%s: forcing baud rate for this device\n", __func__); 268695da310eSAlan Cox tty_encode_baud_rate(tty, priv->force_baud, 2687bd5e47ccSAndrew Morton priv->force_baud); 26881da177e4SLinus Torvalds } 26891da177e4SLinus Torvalds 26901da177e4SLinus Torvalds /* Force RTS-CTS if this device requires it. */ 26911da177e4SLinus Torvalds if (priv->force_rtscts) { 2692bfc51614SGreg Kroah-Hartman dev_dbg(ddev, "%s: forcing rtscts for this device\n", __func__); 2693669a6db1SAlan Cox termios->c_cflag |= CRTSCTS; 26941da177e4SLinus Torvalds } 26951da177e4SLinus Torvalds 26968704211fSColin Leitner /* 2697c1f15196SColin Leitner * All FTDI UART chips are limited to CS7/8. We shouldn't pretend to 26988704211fSColin Leitner * support CS5/6 and revert the CSIZE setting instead. 2699c1f15196SColin Leitner * 2700c1f15196SColin Leitner * CS5 however is used to control some smartcard readers which abuse 2701c1f15196SColin Leitner * this limitation to switch modes. Original FTDI chips fall back to 2702c1f15196SColin Leitner * eight data bits. 2703c1f15196SColin Leitner * 2704c1f15196SColin Leitner * TODO: Implement a quirk to only allow this with mentioned 2705c1f15196SColin Leitner * readers. One I know of (Argolis Smartreader V1) 2706c1f15196SColin Leitner * returns "USB smartcard server" as iInterface string. 2707c1f15196SColin Leitner * The vendor didn't bother with a custom VID/PID of 2708c1f15196SColin Leitner * course. 27098704211fSColin Leitner */ 2710c1f15196SColin Leitner if (C_CSIZE(tty) == CS6) { 27118704211fSColin Leitner dev_warn(ddev, "requested CSIZE setting not supported\n"); 27128704211fSColin Leitner 27138704211fSColin Leitner termios->c_cflag &= ~CSIZE; 27148704211fSColin Leitner if (old_termios) 27158704211fSColin Leitner termios->c_cflag |= old_termios->c_cflag & CSIZE; 27168704211fSColin Leitner else 27178704211fSColin Leitner termios->c_cflag |= CS8; 27188704211fSColin Leitner } 27198704211fSColin Leitner 2720669a6db1SAlan Cox cflag = termios->c_cflag; 27211da177e4SLinus Torvalds 2722a816e311SYing Xue if (!old_termios) 2723c515598eSAndrew Worsley goto no_skip; 2724c515598eSAndrew Worsley 2725b1ffb4c8SAndrew Worsley if (old_termios->c_cflag == termios->c_cflag 2726b1ffb4c8SAndrew Worsley && old_termios->c_ispeed == termios->c_ispeed 2727b1ffb4c8SAndrew Worsley && old_termios->c_ospeed == termios->c_ospeed) 2728b1ffb4c8SAndrew Worsley goto no_c_cflag_changes; 2729b1ffb4c8SAndrew Worsley 27301da177e4SLinus Torvalds /* NOTE These routines can get interrupted by 2731464cbb24SAlan Cox ftdi_sio_read_bulk_callback - need to examine what this means - 2732464cbb24SAlan Cox don't see any problems yet */ 27331da177e4SLinus Torvalds 2734b1ffb4c8SAndrew Worsley if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) == 2735b1ffb4c8SAndrew Worsley (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB))) 2736b1ffb4c8SAndrew Worsley goto no_data_parity_stop_changes; 2737b1ffb4c8SAndrew Worsley 2738c515598eSAndrew Worsley no_skip: 27391da177e4SLinus Torvalds /* Set number of data bits, parity, stop bits */ 27401da177e4SLinus Torvalds 274116410115SJohan Hovold value = 0; 274216410115SJohan Hovold value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : 27431da177e4SLinus Torvalds FTDI_SIO_SET_DATA_STOP_BITS_1); 274438fcb830SRoland Koebler if (cflag & PARENB) { 274538fcb830SRoland Koebler if (cflag & CMSPAR) 274616410115SJohan Hovold value |= cflag & PARODD ? 274738fcb830SRoland Koebler FTDI_SIO_SET_DATA_PARITY_MARK : 274838fcb830SRoland Koebler FTDI_SIO_SET_DATA_PARITY_SPACE; 274938fcb830SRoland Koebler else 275016410115SJohan Hovold value |= cflag & PARODD ? 275138fcb830SRoland Koebler FTDI_SIO_SET_DATA_PARITY_ODD : 275238fcb830SRoland Koebler FTDI_SIO_SET_DATA_PARITY_EVEN; 275338fcb830SRoland Koebler } else { 275416410115SJohan Hovold value |= FTDI_SIO_SET_DATA_PARITY_NONE; 275538fcb830SRoland Koebler } 27561da177e4SLinus Torvalds switch (cflag & CSIZE) { 2757c1f15196SColin Leitner case CS5: 2758c1f15196SColin Leitner dev_dbg(ddev, "Setting CS5 quirk\n"); 2759c1f15196SColin Leitner break; 2760bfc51614SGreg Kroah-Hartman case CS7: 276116410115SJohan Hovold value |= 7; 2762bfc51614SGreg Kroah-Hartman dev_dbg(ddev, "Setting CS7\n"); 2763bfc51614SGreg Kroah-Hartman break; 27648704211fSColin Leitner default: 2765bfc51614SGreg Kroah-Hartman case CS8: 276616410115SJohan Hovold value |= 8; 2767bfc51614SGreg Kroah-Hartman dev_dbg(ddev, "Setting CS8\n"); 2768bfc51614SGreg Kroah-Hartman break; 27691da177e4SLinus Torvalds } 27701da177e4SLinus Torvalds 2771464cbb24SAlan Cox /* This is needed by the break command since it uses the same command 2772464cbb24SAlan Cox - but is or'ed with this value */ 277316410115SJohan Hovold priv->last_set_data_value = value; 27741da177e4SLinus Torvalds 27751da177e4SLinus Torvalds if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 27761da177e4SLinus Torvalds FTDI_SIO_SET_DATA_REQUEST, 27771da177e4SLinus Torvalds FTDI_SIO_SET_DATA_REQUEST_TYPE, 2778027bf37dSJohan Hovold value, priv->channel, 277966e47e60SJohan Hovold NULL, 0, WDR_SHORT_TIMEOUT) < 0) { 2780bfc51614SGreg Kroah-Hartman dev_err(ddev, "%s FAILED to set databits/stopbits/parity\n", 2781bfc51614SGreg Kroah-Hartman __func__); 27821da177e4SLinus Torvalds } 27831da177e4SLinus Torvalds 27841da177e4SLinus Torvalds /* Now do the baudrate */ 2785b1ffb4c8SAndrew Worsley no_data_parity_stop_changes: 27861da177e4SLinus Torvalds if ((cflag & CBAUD) == B0) { 27871da177e4SLinus Torvalds /* Disable flow control */ 27881da177e4SLinus Torvalds if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 27891da177e4SLinus Torvalds FTDI_SIO_SET_FLOW_CTRL_REQUEST, 27901da177e4SLinus Torvalds FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 2791027bf37dSJohan Hovold 0, priv->channel, 279266e47e60SJohan Hovold NULL, 0, WDR_TIMEOUT) < 0) { 2793bfc51614SGreg Kroah-Hartman dev_err(ddev, "%s error from disable flowcontrol urb\n", 2794194343d9SGreg Kroah-Hartman __func__); 27951da177e4SLinus Torvalds } 27961da177e4SLinus Torvalds /* Drop RTS and DTR */ 279774ede0ffSIan Abbott clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); 27981da177e4SLinus Torvalds } else { 27991da177e4SLinus Torvalds /* set the baudrate determined before */ 28009c67d28eSAlessio Igor Bogani mutex_lock(&priv->cfg_lock); 2801464cbb24SAlan Cox if (change_speed(tty, port)) 2802bfc51614SGreg Kroah-Hartman dev_err(ddev, "%s urb failed to set baudrate\n", __func__); 28039c67d28eSAlessio Igor Bogani mutex_unlock(&priv->cfg_lock); 280472a755fcSPeter Favrholdt /* Ensure RTS and DTR are raised when baudrate changed from 0 */ 28053177130fSJohan Hovold if (old_termios && (old_termios->c_cflag & CBAUD) == B0) 280674ede0ffSIan Abbott set_mctrl(port, TIOCM_DTR | TIOCM_RTS); 28071da177e4SLinus Torvalds } 28081da177e4SLinus Torvalds 2809b1ffb4c8SAndrew Worsley no_c_cflag_changes: 2810df1cd63dSJohan Hovold /* Set hardware-assisted flow control */ 2811df1cd63dSJohan Hovold value = 0; 28121da177e4SLinus Torvalds 2813df1cd63dSJohan Hovold if (C_CRTSCTS(tty)) { 2814df1cd63dSJohan Hovold dev_dbg(&port->dev, "enabling rts/cts flow control\n"); 2815df1cd63dSJohan Hovold index = FTDI_SIO_RTS_CTS_HS; 2816df1cd63dSJohan Hovold } else if (I_IXON(tty)) { 2817df1cd63dSJohan Hovold dev_dbg(&port->dev, "enabling xon/xoff flow control\n"); 2818df1cd63dSJohan Hovold index = FTDI_SIO_XON_XOFF_HS; 2819df1cd63dSJohan Hovold value = STOP_CHAR(tty) << 8 | START_CHAR(tty); 28201da177e4SLinus Torvalds } else { 2821df1cd63dSJohan Hovold dev_dbg(&port->dev, "disabling flow control\n"); 2822df1cd63dSJohan Hovold index = FTDI_SIO_DISABLE_FLOW_CTRL; 2823df1cd63dSJohan Hovold } 2824df1cd63dSJohan Hovold 2825027bf37dSJohan Hovold index |= priv->channel; 2826df1cd63dSJohan Hovold 2827df1cd63dSJohan Hovold ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 28281da177e4SLinus Torvalds FTDI_SIO_SET_FLOW_CTRL_REQUEST, 28291da177e4SLinus Torvalds FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 2830df1cd63dSJohan Hovold value, index, NULL, 0, WDR_TIMEOUT); 2831df1cd63dSJohan Hovold if (ret < 0) 2832df1cd63dSJohan Hovold dev_err(&port->dev, "failed to set flow control: %d\n", ret); 283395da310eSAlan Cox } 28341da177e4SLinus Torvalds 2835a4afff6bSJohan Hovold /* 2836a4afff6bSJohan Hovold * Get modem-control status. 2837a4afff6bSJohan Hovold * 2838a4afff6bSJohan Hovold * Returns the number of status bytes retrieved (device dependant), or 2839a4afff6bSJohan Hovold * negative error code. 2840a4afff6bSJohan Hovold */ 2841c4133648SJohan Hovold static int ftdi_get_modem_status(struct usb_serial_port *port, 2842a4afff6bSJohan Hovold unsigned char status[2]) 28431da177e4SLinus Torvalds { 28441da177e4SLinus Torvalds struct ftdi_private *priv = usb_get_serial_port_data(port); 284566e47e60SJohan Hovold unsigned char *buf; 2846a3f8168bSJohan Hovold int len; 28471da177e4SLinus Torvalds int ret; 28481da177e4SLinus Torvalds 284966e47e60SJohan Hovold buf = kmalloc(2, GFP_KERNEL); 285066e47e60SJohan Hovold if (!buf) 285166e47e60SJohan Hovold return -ENOMEM; 2852a3f8168bSJohan Hovold /* 28536fbd9142SJohan Hovold * The device returns a two byte value (the SIO a 1 byte value) in the 28546fbd9142SJohan Hovold * same format as the data returned from the IN endpoint. 2855a3f8168bSJohan Hovold */ 28566fbd9142SJohan Hovold if (priv->chip_type == SIO) 2857a3f8168bSJohan Hovold len = 1; 28586fbd9142SJohan Hovold else 2859a3f8168bSJohan Hovold len = 2; 28601da177e4SLinus Torvalds 2861a3f8168bSJohan Hovold ret = usb_control_msg(port->serial->dev, 2862a3f8168bSJohan Hovold usb_rcvctrlpipe(port->serial->dev, 0), 2863a3f8168bSJohan Hovold FTDI_SIO_GET_MODEM_STATUS_REQUEST, 2864a3f8168bSJohan Hovold FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, 2865027bf37dSJohan Hovold 0, priv->channel, 2866a3f8168bSJohan Hovold buf, len, WDR_TIMEOUT); 2867427c3a95SJohan Hovold 2868427c3a95SJohan Hovold /* NOTE: We allow short responses and handle that below. */ 2869427c3a95SJohan Hovold if (ret < 1) { 2870a4afff6bSJohan Hovold dev_err(&port->dev, "failed to get modem status: %d\n", ret); 2871427c3a95SJohan Hovold if (ret >= 0) 2872427c3a95SJohan Hovold ret = -EIO; 28732c2ee545SJohan Hovold ret = usb_translate_errors(ret); 2874a3f8168bSJohan Hovold goto out; 28752c2ee545SJohan Hovold } 2876a3f8168bSJohan Hovold 2877a4afff6bSJohan Hovold status[0] = buf[0]; 2878a4afff6bSJohan Hovold if (ret > 1) 2879a4afff6bSJohan Hovold status[1] = buf[1]; 2880a4afff6bSJohan Hovold else 2881a4afff6bSJohan Hovold status[1] = 0; 2882a4afff6bSJohan Hovold 2883a4afff6bSJohan Hovold dev_dbg(&port->dev, "%s - 0x%02x%02x\n", __func__, status[0], 2884a4afff6bSJohan Hovold status[1]); 2885a4afff6bSJohan Hovold out: 2886a4afff6bSJohan Hovold kfree(buf); 2887a4afff6bSJohan Hovold 2888a4afff6bSJohan Hovold return ret; 2889a4afff6bSJohan Hovold } 2890a4afff6bSJohan Hovold 2891a4afff6bSJohan Hovold static int ftdi_tiocmget(struct tty_struct *tty) 2892a4afff6bSJohan Hovold { 2893a4afff6bSJohan Hovold struct usb_serial_port *port = tty->driver_data; 2894a4afff6bSJohan Hovold struct ftdi_private *priv = usb_get_serial_port_data(port); 2895a4afff6bSJohan Hovold unsigned char buf[2]; 2896a4afff6bSJohan Hovold int ret; 2897a4afff6bSJohan Hovold 2898c4133648SJohan Hovold ret = ftdi_get_modem_status(port, buf); 2899a4afff6bSJohan Hovold if (ret < 0) 2900a4afff6bSJohan Hovold return ret; 2901a4afff6bSJohan Hovold 290266e47e60SJohan Hovold ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | 29031da177e4SLinus Torvalds (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | 29041da177e4SLinus Torvalds (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | 29051da177e4SLinus Torvalds (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | 29061da177e4SLinus Torvalds priv->last_dtr_rts; 2907a4afff6bSJohan Hovold 290866e47e60SJohan Hovold return ret; 29091da177e4SLinus Torvalds } 29101da177e4SLinus Torvalds 291120b9d177SAlan Cox static int ftdi_tiocmset(struct tty_struct *tty, 291295da310eSAlan Cox unsigned int set, unsigned int clear) 29131da177e4SLinus Torvalds { 291495da310eSAlan Cox struct usb_serial_port *port = tty->driver_data; 2915a09aa7ddSGreg Kroah-Hartman 291674ede0ffSIan Abbott return update_mctrl(port, set, clear); 29171da177e4SLinus Torvalds } 29181da177e4SLinus Torvalds 291900a0d0d6SAlan Cox static int ftdi_ioctl(struct tty_struct *tty, 2920464cbb24SAlan Cox unsigned int cmd, unsigned long arg) 29211da177e4SLinus Torvalds { 292295da310eSAlan Cox struct usb_serial_port *port = tty->driver_data; 292359556608SJohan Hovold void __user *argp = (void __user *)arg; 29241da177e4SLinus Torvalds 29251da177e4SLinus Torvalds switch (cmd) { 2926c466cd2bSGreg Kroah-Hartman case TIOCSERGETLSR: 292759556608SJohan Hovold return get_lsr_info(port, argp); 29281da177e4SLinus Torvalds default: 29291da177e4SLinus Torvalds break; 29301da177e4SLinus Torvalds } 29314d5147ecSJohan Hovold 293295da310eSAlan Cox return -ENOIOCTLCMD; 293395da310eSAlan Cox } 29341da177e4SLinus Torvalds 2935e17c1aa2SJohan Hovold module_usb_serial_driver(serial_drivers, id_table_combined); 29361da177e4SLinus Torvalds 29371da177e4SLinus Torvalds MODULE_AUTHOR(DRIVER_AUTHOR); 29381da177e4SLinus Torvalds MODULE_DESCRIPTION(DRIVER_DESC); 29391da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 29401da177e4SLinus Torvalds 2941a65ab973SUtkarsh Verma module_param(ndi_latency_timer, int, 0644); 2942b760dac2SMartin Geleynse MODULE_PARM_DESC(ndi_latency_timer, "NDI device latency timer override"); 2943