Re: [PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes
From: Lee Jones
Date: Thu Aug 27 2026 - 16:51:37 EST
On Thu, 27 Aug 2026, Michael Zaidman wrote:
> On Thu, Aug 27, 2026 at 14:27 +0100, Lee Jones wrote:
> > What is this? 4 device drivers in one, shoved into HID? Each
> > component; HID, I2C, GPIO, UART, should live in its respective
> > subsystem, surely?
>
> The FT260 is a USB HID protocol converter, not four MMIO blocks behind
> an MFD. I2C, UART and GPIO are HID reports on one chip. Mainline
> hid-ft260 already hosts the I2C adapter in HID for that reason. This
> series adds GPIO and UART the same way.
>
> hid-cp2112 and hid-mcp2221 already register an i2c_adapter and a
> gpiochip from a hid_driver. They are not split into i2c/ and gpio/.
>
> A subsystem split does not give independent drivers here. The control
> and pin mux live in one feature report, and input is one raw_event.
>
> System status (HID feature 0xA1) is chip-wide, not per USB interface.
> chip_mode (DCNF0/DCNF1), the 12/24/48 MHz clock, i2c_enable, uart_mode,
> UART configuration (baud/frame/flow), I2C reset and I2C clock, GPIO2/A/G
> function select, DCD/RI enable, and power-save are fields or SET
> requests on that same report. Probe on either HID interface reads 0xA1
> and then decides I2C vs UART from chip_mode plus bInterfaceNumber.
>
> GPIO is not a third USB function. It is feature report 0xB0. Which pins
> are GPIO depends on that 0xA1 map: I2C enable takes GPIO0/1 (SCL/SDA);
> uart_mode takes or frees RX/TX, RTS/CTS, DTR/DSR and DCD/RI; GPIO2/A/G
> are UART/power LEDs vs GPIO; GPIO3 is wakeup vs GPIO. The gpiochip is
> attached to the I2C HID interface in I2C-only mode and to the UART HID
> interface in UART or dual mode. TIOCMGET/TIOCMSET use that gpiochip
> when the modem pins are in GPIO mode. Changing UART flow control
> rewrites 0xA1 and then updates the GPIO enable mask.
>
> Input is one hid_driver.raw_event. It dispatches I2C read payloads
> (0xD0-0xDE), UART RX, and UART interrupt status (0xB1) by report ID.
> Dual-mode still has two USB HID interfaces, but they are two pipes to
> one chip. There is one 0xA1; there are not two register files.
>
> USB reset (the TN_189 workaround) resets the whole device and rebinds
> every interface. Idle wakeup uses chip-wide GET reports (0xA0 / 0xC0)
> and power_saving_en from 0xA1.
>
> UART is still HID reports on the UART interface (0xE0 / 0xB1 / data
> reports), not an 8250-style port. Putting it in drivers/tty would not
> remove the 0xA1/0xB0 coupling.
>
> An MFD split would still need a HID core that owns 0xA1, 0xB0 and
> raw_event, with I2C/GPIO/UART cells calling back into it, and with GPIO
> availability depending on UART/I2C mode and on which interface probed.
> That cell-and-core layout is this driver already. Splitting it does
> not give I2C, GPIO, or UART their own independent devices; it is
> still one HID protocol converter, in four files to keep aligned
> across kernel versions.
That's precisely what MFD is. It's one chip, usually with a shared and
overlapping register spaces, that conducts multiple functions. This is
no different to any other single-chip device or SoC.
Shoving everything into a single driver isn't how things are done in
Linux. This should be divided up into the associated sub-systems where
each part can be reviewed and looked after by the appropriate SMEs.
--
Lee Jones