summaryrefslogtreecommitdiff
path: root/drivers/usb/serial/ftdi_sio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-18 20:33:46 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-18 20:33:46 +0300
commitc6b48dad92aedaa9bdc013ee495cb5b1bbdf1f11 (patch)
tree8d0bbf19d75fc1bf546ed1b05b560ea2df54689e /drivers/usb/serial/ftdi_sio.c
parent1f7d290a7275edb270dbee13212c37cb59940221 (diff)
parentfb9617edf6c0e1b86a6595cd92dd3f84595221d9 (diff)
downloadlinux-c6b48dad92aedaa9bdc013ee495cb5b1bbdf1f11.tar.xz
Merge tag 'usb-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB updates from Greg KH: "Here is the big set of USB patches for 5.4-rc1. Two major chunks of code are moving out of the tree and into the staging directory, uwb and wusb (wireless USB support), because there are no devices that actually use this protocol anymore, and what we have today probably doesn't work at all given that the maintainers left many many years ago. So move it to staging where it will be removed in a few releases if no one screams. Other than that, lots of little things. The usual gadget and xhci and usb serial driver updates, along with a bunch of sysfs file cleanups due to the driver core changes to support that. Nothing really major, just constant forward progress. All of these have been in linux-next for a while with no reported issues" * tag 'usb-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (159 commits) USB: usbcore: Fix slab-out-of-bounds bug during device reset usb: cdns3: Remove redundant dev_err call in cdns3_probe() USB: rio500: Fix lockdep violation USB: rio500: simplify locking usb: mtu3: register a USB Role Switch for dual role mode usb: common: add USB GPIO based connection detection driver usb: common: create Kconfig file usb: roles: get usb-role-switch from parent usb: roles: Add fwnode_usb_role_switch_get() function device connection: Add fwnode_connection_find_match() usb: roles: Introduce stubs for the exiting functions in role.h dt-bindings: usb: mtu3: add properties about USB Role Switch dt-bindings: usb: add binding for USB GPIO based connection detection driver dt-bindings: connector: add optional properties for Type-B dt-binding: usb: add usb-role-switch property usbip: Implement SG support to vhci-hcd and stub driver usb: roles: intel: Enable static DRD mode for role switch xhci-ext-caps.c: Add property to disable Intel SW switch usb: dwc3: remove generic PHY calibrate() calls usb: core: phy: add support for PHY calibration ...
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r--drivers/usb/serial/ftdi_sio.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 4b3a049561f3..f0688c44b04c 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -2023,6 +2023,46 @@ static int ftdi_read_eeprom(struct usb_serial *serial, void *dst, u16 addr,
return 0;
}
+static int ftdi_gpio_init_ft232h(struct usb_serial_port *port)
+{
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ u16 cbus_config;
+ u8 *buf;
+ int ret;
+ int i;
+
+ buf = kmalloc(4, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ ret = ftdi_read_eeprom(port->serial, buf, 0x1a, 4);
+ if (ret < 0)
+ goto out_free;
+
+ /*
+ * FT232H CBUS Memory Map
+ *
+ * 0x1a: X- (upper nibble -> AC5)
+ * 0x1b: -X (lower nibble -> AC6)
+ * 0x1c: XX (upper nibble -> AC9 | lower nibble -> AC8)
+ */
+ cbus_config = buf[2] << 8 | (buf[1] & 0xf) << 4 | (buf[0] & 0xf0) >> 4;
+
+ priv->gc.ngpio = 4;
+ priv->gpio_altfunc = 0xff;
+
+ for (i = 0; i < priv->gc.ngpio; ++i) {
+ if ((cbus_config & 0xf) == FTDI_FTX_CBUS_MUX_GPIO)
+ priv->gpio_altfunc &= ~BIT(i);
+ cbus_config >>= 4;
+ }
+
+out_free:
+ kfree(buf);
+
+ return ret;
+}
+
static int ftdi_gpio_init_ft232r(struct usb_serial_port *port)
{
struct ftdi_private *priv = usb_get_serial_port_data(port);
@@ -2098,6 +2138,9 @@ static int ftdi_gpio_init(struct usb_serial_port *port)
int result;
switch (priv->chip_type) {
+ case FT232H:
+ result = ftdi_gpio_init_ft232h(port);
+ break;
case FT232RL:
result = ftdi_gpio_init_ft232r(port);
break;