[PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes

Michael Zaidman posted 13 patches 1 month ago
drivers/hid/Kconfig     |   10 +-
drivers/hid/hid-ft260.c | 1967 ++++++++++++++++++++++++++++++++++++---
2 files changed, 1830 insertions(+), 147 deletions(-)
[PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes
Posted by Michael Zaidman 1 month ago
Mainline supports only the FT260's I2C bridge. This series adds the
UART/TTY interface and GPIO on top of it, and carries the I2C fixes made
alongside them - two years of out-of-tree work [1], now replayed upstream.

It picks up work that stalled twice: Christina Quast's serial driver,
posted as v4 and v5 and never applied, and my own pre-UART GPIO series
from 2023. Patches 1 and 3 link both threads. This is a new series rather
than a v6, being much more than the serial driver now.

The patches keep the order and the granularity in which the work was
developed, so that authorship stays visible: squashing would fold several
people's changes under one name. The UART and I2C changes also interleave
in the code, so regrouping them by interface would mean a rewrite and a
full retest. Only adjacent commits were squashed. Patch 1 is Christina's,
patch 10 is Rio Liu's.

Tested on a UMFT260EV1A with a 24LC512 EEPROM. I2C - reads and writes
that cross the 60-byte write chunk and the 60/180-byte read chunk caps,
SMBus byte-data and block reads, and the shortened read timeout with the
abort path of patch 13. UART - a 2.8 MB pattern in both directions at
115200 and 1.5 Mbaud against an FT2232 peer, without flow control and
with XON/XOFF and RTS/CTS, plus DTR/RTS toggling over TIOCM*. GPIO -
through libgpiod and legacy sysfs. Every commit builds with W=1, and
checkpatch --strict reports no errors and no warnings across the series.

[1] https://github.com/MichaelZaidman/hid-ft260

Christina Quast (1):
  HID: ft260: add serial driver

Michael Zaidman (11):
  HID: ft260: uart: bring-up fixes
  HID: ft260: add GPIO support on top of UART
  HID: ft260: i2c: reduce driver module loading time
  HID: ft260: i2c: silence sysfs store big-numbers
  HID: ft260: i2c: reduce bus-error message severity
  HID: ft260: uart: enable flow control
  HID: ft260: uart: add modem pins control via ioctl
  HID: ft260: gpio: group sysfs attrs per HID interface
  HID: ft260: i2c: fix large write transaction failure
  HID: ft260: workaround for TN_189 errata endpoint STALL after
    enumeration
  HID: ft260: i2c: abort in-flight transfers with STOP before reset

Rio Liu (1):
  HID: ft260: uart: fix active-low RTS/CTS/DTR/DSR polarity

 drivers/hid/Kconfig     |   10 +-
 drivers/hid/hid-ft260.c | 1967 ++++++++++++++++++++++++++++++++++++---
 2 files changed, 1830 insertions(+), 147 deletions(-)

-- 
2.43.0
Re: [PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes
Posted by Linus Walleij 1 month ago
Hi Michael,

thanks for your patch!

On Sat, Aug 22, 2026 at 11:40 PM Michael Zaidman
<michael.zaidman@gmail.com> wrote:

> Mainline supports only the FT260's I2C bridge. This series adds the
> UART/TTY interface and GPIO on top of it, and carries the I2C fixes made
> alongside them - two years of out-of-tree work [1], now replayed upstream.
(...)
>   HID: ft260: add serial driver
(...)
>   HID: ft260: add GPIO support on top of UART

This comment isn't pertaining to this one device in particular.

I'm not a HID maintainer but this trend to make HID devices spawn
serial and GPIO devices sort of turns HID into the new MFD, but
I suppose Jiri and Lee has discussed this phenomenon in the past?

Yours,
Linus Walleij
Re: [PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes
Posted by Lee Jones 1 month ago
On Tue, 25 Aug 2026, Linus Walleij wrote:

> Hi Michael,
> 
> thanks for your patch!
> 
> On Sat, Aug 22, 2026 at 11:40 PM Michael Zaidman
> <michael.zaidman@gmail.com> wrote:
> 
> > Mainline supports only the FT260's I2C bridge. This series adds the
> > UART/TTY interface and GPIO on top of it, and carries the I2C fixes made
> > alongside them - two years of out-of-tree work [1], now replayed upstream.
> (...)
> >   HID: ft260: add serial driver
> (...)
> >   HID: ft260: add GPIO support on top of UART
> 
> This comment isn't pertaining to this one device in particular.
> 
> I'm not a HID maintainer but this trend to make HID devices spawn
> serial and GPIO devices sort of turns HID into the new MFD, but
> I suppose Jiri and Lee has discussed this phenomenon in the past?

What is this?  4 device drivers in one, shoved into HID?  Each
component; HID, I2C, GPIO, UART, should live in its respective
subsystem, surely?

-- 
Lee Jones
Re: [PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes
Posted by Michael Zaidman 1 month ago
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.

Thanks,
Michael
Re: [PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes
Posted by Lee Jones 1 month ago
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
Re: [PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes
Posted by Michael Zaidman 1 month ago
On Thu, 27 Aug 2026 at 21:51 +0100, Lee Jones wrote:
> 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.

Understood, and I am not going to argue MFD scope with you. But this
is not specific to my series, so I would rather not decide it here on
my own.

drivers/hid already registers other subsystems' devices from a
hid_driver: hid-cp2112 adds an i2c_adapter and a gpiochip, hid-mcp2221
adds an i2c_adapter, a gpiochip and an IIO device, and hid-ft260 has
hosted the I2C adapter since v5.13, commit 6a82582d9fa4 ("HID: ft260:
add usb hid to i2c host bridge driver").

So the split you are asking for is not a change to this series. It
means moving code that has been in drivers/hid since v5.13 into an MFD
parent with cells, and the same reasoning would apply to cp2112 and
mcp2221. I am willing to discuss that as its own conversion, but it
needs the HID maintainers to agree on the direction first, and I do
not think the UART and GPIO support should wait behind it.

It would also spread the driver over four trees, so a fix touching the
shared chip state becomes a cross-tree series with coordinated merges
between four maintainers - a cost the single driver does not have.

Jiri, Benjamin - this is your call. Do you want FT260 functionality to
keep growing inside hid-ft260, as cp2112 and mcp2221 do today, or do
you want a drivers/hid to MFD conversion for this class of USB HID
bridge chips?

Thanks,
Michael
Re: [PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes
Posted by Linus Walleij 2 weeks ago
Hi Benjamin, Lee,

On Tue, Sep 1, 2026 at 4:03 PM Benjamin Tissoires <bentiss@kernel.org> wrote:

> TBH, I'm not a big fan of having multiple subsystems children into HID.
> Mostly because I can't review the best practive in each of them. However,
> for quite a long time, HID was mostly for input devices, and input is a
> different subsystem.
>
> That being said, there are 2 types of HID devices:
> - ones with defined standard usages (keyboards, mice, touchscreen,
>         battery, etc) and using MFD for those would certainly be overthinking
> - others use raw HID device with a custom protocol (cp2112, mcp2221,
>         ft260), these could be MFD candidates

Surely, as HID start to attract chips which clearly fall into the MFD
category of things, with a plethora of subsystems hooking into the
same HID device, we must find a way for HID devices to spawn
MFD cells?

MFD solved and evolved a system for handling exactly this type
of situation.

Whether there should be an MFD device in the middle spawning
each a HID, GPIO, I2C, UART cell or whether HID device itself should
sit in the nexus and gain the ability to simply spawn out MFD cells
from itself is what we need to figure out.

Yours,
Linus Walleij
Re: [PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes
Posted by Lee Jones 1 week, 4 days ago
On Mon, 14 Sep 2026, Linus Walleij wrote:

> Hi Benjamin, Lee,
> 
> On Tue, Sep 1, 2026 at 4:03 PM Benjamin Tissoires <bentiss@kernel.org> wrote:
> 
> > TBH, I'm not a big fan of having multiple subsystems children into HID.
> > Mostly because I can't review the best practive in each of them. However,
> > for quite a long time, HID was mostly for input devices, and input is a
> > different subsystem.
> >
> > That being said, there are 2 types of HID devices:
> > - ones with defined standard usages (keyboards, mice, touchscreen,
> >         battery, etc) and using MFD for those would certainly be overthinking
> > - others use raw HID device with a custom protocol (cp2112, mcp2221,
> >         ft260), these could be MFD candidates
> 
> Surely, as HID start to attract chips which clearly fall into the MFD
> category of things, with a plethora of subsystems hooking into the
> same HID device, we must find a way for HID devices to spawn
> MFD cells?
> 
> MFD solved and evolved a system for handling exactly this type
> of situation.
> 
> Whether there should be an MFD device in the middle spawning
> each a HID, GPIO, I2C, UART cell or whether HID device itself should
> sit in the nexus and gain the ability to simply spawn out MFD cells
> from itself is what we need to figure out.

There's no figuring that part out.

If you want to use the MFD API, the part that uses it must reside in
drivers/mfd.  Else it becomes a nightmare to maintain and things get
wild, quickly.

You'd be surprised what "creative" engineers can do with it!

-- 
Lee Jones
Re: [PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes
Posted by Lee Jones 1 week, 3 days ago
On Thu, 17 Sep 2026, Benjamin Tissoires wrote:

> On Sep 16 2026, Lee Jones wrote:
> > On Mon, 14 Sep 2026, Linus Walleij wrote:
> > 
> > > Hi Benjamin, Lee,
> > > 
> > > On Tue, Sep 1, 2026 at 4:03 PM Benjamin Tissoires <bentiss@kernel.org> wrote:
> > > 
> > > > TBH, I'm not a big fan of having multiple subsystems children into HID.
> > > > Mostly because I can't review the best practive in each of them. However,
> > > > for quite a long time, HID was mostly for input devices, and input is a
> > > > different subsystem.
> > > >
> > > > That being said, there are 2 types of HID devices:
> > > > - ones with defined standard usages (keyboards, mice, touchscreen,
> > > >         battery, etc) and using MFD for those would certainly be overthinking
> > > > - others use raw HID device with a custom protocol (cp2112, mcp2221,
> > > >         ft260), these could be MFD candidates
> > > 
> > > Surely, as HID start to attract chips which clearly fall into the MFD
> > > category of things, with a plethora of subsystems hooking into the
> > > same HID device, we must find a way for HID devices to spawn
> > > MFD cells?
> > > 
> > > MFD solved and evolved a system for handling exactly this type
> > > of situation.
> > > 
> > > Whether there should be an MFD device in the middle spawning
> > > each a HID, GPIO, I2C, UART cell or whether HID device itself should
> > > sit in the nexus and gain the ability to simply spawn out MFD cells
> > > from itself is what we need to figure out.
> > 
> > There's no figuring that part out.
> > 
> > If you want to use the MFD API, the part that uses it must reside in
> > drivers/mfd.  Else it becomes a nightmare to maintain and things get
> > wild, quickly.
> 
> Historically speaking, HID devices always have been under drivers/hid.
> They are usually leaf drivers, only hooking to input/battery/LEDs.
> 
> As mentioned, hid-sensor-hub is an exception but this got sorted out by
> splitting the HID part from the IIO.
> 
> Looking at the various MFD-like HID drivers, they all share the common
> point of not really being HID devices: they rely on a custom protocol
> handled in .raw_event().
> 
> So I think I'd be OK to have those drivers moved to the mfd tree as long
> as they only rely on low level HID API, and do not have to deal with
> "generic" HID report descriptors. If that arise, I think we should split
> the HID/MFD parts like hid-sensor-hub does.
> 
> So you can have my unformal acked-by for transfering those drivers.

A couple of caveats to this:

Only the most basic set-up parts need to go into MFD (shared resource
allocation, core device initialisation: clocks, resets, regulators,
IRQs, etc.  Anything that does a 'thing' needs to reside in the
applicable sub-system that supports the 'thing'.

Device need to straddle at least 2 additional subsystems to qualify as
an MFD which undoubtibly would be HID and then something else: gpio,
regulator, uart, iio, clk, what have you. 

> Last, I'm currently using a cp2112 as a i2c-hid bridge in my upstream
> CI. It's relying on a DSDT override in the VM to actually work, and I'd
> like to keep that around. So my main request here is to keep the
> equivalent of the DSDT override in the MFD cells, at least for this one.

I have no idea what that means, but we can discuss it.  Maybe this lives
in some form of platform data?  I'd be able to advise better when I know
what it is.

-- 
Lee Jones
Re: [PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes
Posted by Michael Zaidman 1 day, 15 hours ago
Hi Benjamin, Lee, Linus,

On Thu, 17 Sep 2026 at 13:07 +0200, Benjamin Tissoires wrote:

> I think HID is just the transport layer (like USB, I2C, SPI, etc...) so
> it shouldn't count as one of the additional subsystems to MFD.

Agreed for the FT260. The HID reports are the transport. The functions
are UART, GPIO and I2C.

Jiri answered me off-list on 11 September, before the mails of 14 to
17 September. He has no strong preference, and he left the sequencing
to me.

I will land the current driver first, and do the MFD split as its own
series once this one is in the tree.

GPIO support has been in the out-of-tree driver since 20 November 2022
[1]. The serial driver was added there on 12 January 2024.
That is where its bugs were found and fixed. Folding an MFD conversion
into the same series would replace that structure while the UART and
GPIO support is still under review. Landing the tested layout first
keeps those two reviews apart.

I maintain this driver in my free time, and my bandwidth for the next
few months is limited. A split across drivers/mfd, drivers/tty,
drivers/gpio and drivers/i2c in this series would stall the UART and
GPIO support.

The parent device depends on the strap pins. One HID feature report,
0xA1 System Settings, carries chip mode, the clock, i2c_enable,
uart_mode, the UART frame and flow control, and the GPIO pin-function
selects. The I2C interface owns that report, and registers the
gpiochip, in I2C-only mode. The UART interface does both once UART is
strapped. Enabling I2C or changing the UART mode moves pins between the
I2C or UART function and GPIO. That parent is easier to define against
a driver that is already in the tree.

The MFD series will follow the constraints from this thread. Lee, the
code that calls the MFD API will live in drivers/mfd, and that file
will do the shared setup only. The UART, GPIO and I2C drivers will live
in their own subsystems. Benjamin, the child devices will keep fwnode
support, so an ACPI or DT child can attach the way your cp2112 CI does
today.

On Tue, 1 Sep 2026 at 16:02 +0200, Benjamin Tissoires wrote:

> It is maybe a lot to ask, but Michael, can you demo the MFD split on
> one/two functionality so we can check which approach is the best?
> Ideally 2 features that would be intricating well enough to demonstrate
> how hard/easy it would be.

The two features that interact here are GPIO and the I2C and UART
functions.
The split is one MFD parent for the two HID interfaces. A demo that
splits only the I2C part cannot show the gpiochip ownership above,
which moves between the I2C and the UART interface: with the I2C side
moved out, there is no configuration where that change can be tested.
The MFD series has to do the whole device at once, and it comes after
this one.

[1] https://github.com/MichaelZaidman/hid-ft260/commit/e40e56953e8c2b23c222d76e97b5f5e274b91603

Thanks,
Michael