Coder Social home page Coder Social logo

hid-ft260's Introduction

hid-ft260

Overview

FTDI FT260 Linux kernel driver

The FTDI FT260 chip implements USB to I2C/UART bridges through two USB HID class interfaces. The first - is for I2C and the second for UART. Each interface is independent, and the kernel detects it as a separate USB hidraw device. In addition, the chip implements 14 GPIOs via multifunctional pins.

Current status

The main branch of this repository holds the most comprehensive version of the FT260 Linux kernel driver:

  1. I2C support - upstreamed into the kernel 5.13 mainline.
  2. UART support - two implementations (1) and (2) of the initial UART support were around for some time, and now they are unified, fixed several issues and merged into the main branch of this repo. It is submitted upstream via this commit.
  3. GPIO support - developed in the gpio branch, reapplied on top of the latest UART support, and is merged into the main branch of this repo. The earlier GPIO version (before UART support) was submitted upstream via this commit.

I2C Interface

FTDI suggests using hidraw and libusb userspace libraries to operate the FT260 I2C host controller via hidraw Linux kernel driver. But this approach makes the standard Linux I2C tools useless, and it does not allow the I2C sysfs tree instantiation required by I2C multiplexers and switches.

This driver enables the FT260 to be seen and handled by the Linux kernel i2c-core code as a regular I2C bus adapter, like when the I2C controller is a part of the MCU or CPU vendor chipset. It provides the following benefits:

  1. It enables usage of the standard Linux userspace I2C tools like i2c-tools and a wide range of userspace applications relying on the /dev/i2c-x kernel API.
  2. The driver exposes the FT260 I2C controller device via sys/bus/i2c bus to other I2C devices relied on it. It allows the sysfs I2C tree instantiation, essential for complex I2C topologies, built with I2C multiplexers and/or I2C switches.
  3. It guarantees atomic access at the kernel level to the I2C devices, resided on the I2C controller's bus, implicitly enabling concurrent access to the I2C bus from multiple userspace processes instead of explicit contexts synchronization when such access is done via hidraw and libusb userspace libraries.

UART Interface

This driver adds a serial interface /dev/ttyFTx, which implements tty serial driver ops, making it easier to configure the baud rate, transmit and receive data, and termios settings.

References

  1. DS_FT260.pdf
  2. AN_394_User_Guide_for_FT260.pdf

HOWTO

Getting started

git clone https://github.com/MichaelZaidman/hid-ft260.git
cd hid-ft260
make
sudo insmod hid-ft260.ko

If you got the below failure, your kernel does not support the hid_is_usb, which was added by https://lkml.org/lkml/2021/12/13/526 commit.

/home/swuser/sw/hid-ft260/hid-ft260.c: In function ‘ft260_probe’:
/home/swuser/sw/hid-ft260/hid-ft260.c:928:7: error: implicit declaration of function ‘hid_is_usb’ [-Werror=implicit-function-declaration]
  if (!hid_is_usb(hdev))

As workaround you can comment two lines in the ft260_probe routine:

        if (!hid_is_usb(hdev))
                return -EINVAL;

Configure ft260 device via sysfs

The driver exposes multiple attributes to user space via sysfs.

Since the order and number of the USB devices vary between systems, the sysfs path to the USB device may change even on the same system.

You can figure out the sysfs path yourself or use the setenv script to set the environment variable per USB interface of every FT260 device.

. ./setenv.sh

Example with 2 ft260 devices:

$ . setenv.sh
sysfs_i2c_15
sysfs_i2c_0

$ echo $sysfs_i2c_0
/sys/bus/hid/drivers/ft260/0003:0403:6030.0007

$ echo $sysfs_i2c_15
/sys/bus/hid/drivers/ft260/0003:0403:6030.000C

Now we can see all availiable attributes:

$ ls $sysfs_i2c_0

Change I2C bus clock

Figure out the sysfs ft260 device node path, as explained earlier. To set the i2c clock to 400KHz on my system, I run this command:

sudo bash -c 'echo 400 > $sysfs_i2c_0/clock'

Set a multifunctional pin as GPIO

The FT260 has three pins that have more than two functions: DIO7 (pin 14), DIO0 (pin 7), and DIO12 (pin 27). The function of these pins can be configured by eFUSE, EEPROM, or via the sysfs interface.

For the sysfs method, you need to figure out the sysfs ft260 device node path, as explained earlier.

In this example, I configure pin 14 to act as GPIO2:

$ cat $sysfs_i2c_0/gpio2_func
1
$ sudo bash -c "echo 0 > $sysfs_i2c_0/gpio2_func"
$ cat $sysfs_i2c_0/gpio2_func
0
$ sudo gpioget 0 2
0
$ sudo gpioset 0 2=1
$ sudo gpioget 0 2
1
$ sudo gpioset 0 2=0
$ sudo gpioget 0 2
0

hid-ft260's People

Contributors

enrikb avatar michaelzaidman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

hid-ft260's Issues

hid-ft260 crashes both FT260 and USB hub when behind 2 USB hubs

I use your driver to control i2c devices behind a FT260 very easily -- thanks for your work :)

I am facing an issue however when plugging in an FT260 behind 2 USB hubs in series with the hid-ft260 module inserted. The second USB hub disappears from lsusb and the FT260 device isn't shown either.

There's no randomness to it: I have tried with multiple hubs from various manufacturers and it never works. This doesn't happen when the hid-ft260 module is removed (and hid-raw is used by default).

Details

Machine: Raspberry Pi 3B with raspbian
Kernel: Linux 6.1.21-v7+ #1642 SMP Mon Apr 3 17:20:52 BST 2023 armv7l GNU/Linux
Driver: Compiled from latest code (18732aa)

Event 1: plugging in the 2 hubs

  • USB hub 1 (Terminus) plugged in Pi
  • USB hub 2 (Genesys) plugged in USB hub 1
[ 2734.376805] usb 1-1.4: new high-speed USB device number 66 using dwc_otg
[ 2734.507250] usb 1-1.4: New USB device found, idVendor=1a40, idProduct=0101, bcdDevice= 1.00
[ 2734.507287] usb 1-1.4: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[ 2734.507304] usb 1-1.4: Product: USB2.0 HUB
[ 2734.508004] hub 1-1.4:1.0: USB hub found
[ 2734.508107] hub 1-1.4:1.0: 4 ports detected
[ 2734.926793] usb 1-1.4.4: new high-speed USB device number 67 using dwc_otg
[ 2735.157927] usb 1-1.4.4: New USB device found, idVendor=05e3, idProduct=0608, bcdDevice=85.36
[ 2735.157948] usb 1-1.4.4: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[ 2735.157956] usb 1-1.4.4: Product: USB2.0 Hub
[ 2735.158516] hub 1-1.4.4:1.0: USB hub found
[ 2735.158796] hub 1-1.4.4:1.0: 4 ports detected
$ lsusb
Bus 001 Device 067: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 066: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 003: ID 0424:ec00 Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Event 2: Plugging in the FT260 in the USB hub 2

[ 2816.077678] usb 1-1.4.4.4: new full-speed USB device number 68 using dwc_otg
[ 2816.213447] usb 1-1.4.4.4: New USB device found, idVendor=0403, idProduct=6030, bcdDevice=22.00
[ 2816.213483] usb 1-1.4.4.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 2816.213500] usb 1-1.4.4.4: Product: FT260
[ 2816.213512] usb 1-1.4.4.4: Manufacturer: FTDI
[ 2816.299337] ft260 0003:0403:6030.001B: chip code: 0260 0200
[ 2816.300938] ft260_is_interface_enabled: interface:  0x00
[ 2816.300952] ft260_is_interface_enabled: chip mode:  0x00
[ 2816.300963] ft260_is_interface_enabled: clock_ctl:  0x02
[ 2816.300972] ft260_is_interface_enabled: i2c_enable: 0x01
[ 2816.300981] ft260_is_interface_enabled: uart_mode:  0x03
[ 2816.300991] ft260_is_interface_enabled: gpio2_func: 0x01
[ 2816.301000] ft260_is_interface_enabled: gpioA_func: 0x03
[ 2816.301009] ft260_is_interface_enabled: gpioG_func: 0x06
[ 2816.301018] ft260_is_interface_enabled: wakeup_int: 0x01
[ 2816.301030] ft260 0003:0403:6030.001B: USB HID v1.11 Device [FTDI FT260] on usb-3f980000.usb-1.4.4.4/input0
[ 2816.301436] ft260_xfer_status: bus_status 0x20, wakeup
[ 2816.301811] ft260_xfer_status: bus_status 0x20, clock 100
[ 2816.302348] ft260 0003:0403:6030.001B: initialize gpio chip
[ 2816.302363] ft260 0003:0403:6030.001B: enabled GPIOs: 0000
[ 2816.399451] ft260 0003:0403:6030.001C: chip code: 0260 0200
[ 2816.401062] ft260_is_interface_enabled: interface:  0x01
[ 2816.401076] ft260_is_interface_enabled: chip mode:  0x00
[ 2816.401086] ft260_is_interface_enabled: clock_ctl:  0x02
[ 2816.401096] ft260_is_interface_enabled: i2c_enable: 0x01
[ 2816.401105] ft260_is_interface_enabled: uart_mode:  0x03
[ 2816.401114] ft260_is_interface_enabled: gpio2_func: 0x01
[ 2816.401123] ft260_is_interface_enabled: gpioA_func: 0x03
[ 2816.401132] ft260_is_interface_enabled: gpioG_func: 0x06
[ 2816.401142] ft260_is_interface_enabled: wakeup_int: 0x01
[ 2816.401171] ft260 0003:0403:6030.001C: uart interface is not supported
$ lsusb
Bus 001 Device 066: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 003: ID 0424:ec00 Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
$ i2cdetect -l
i2c-2	i2c       	bcm2835 (i2c@7e805000)          	I2C adapter

$ ls -la /dev/i2c*
crw-rw---- 1 root i2c 89, 11 Sep 21 09:27 /dev/i2c-11
crw-rw---- 1 root i2c 89,  2 Sep 21 08:40 /dev/i2c-2

The second hub and the FT260 have disappeared.

Expected behaviour

This is what happens when plugged behind 1 hub:

[ 2957.709025] usb 1-1.4.3: new full-speed USB device number 70 using dwc_otg
[ 2957.944678] usb 1-1.4.3: New USB device found, idVendor=0403, idProduct=6030, bcdDevice=22.00
[ 2957.944700] usb 1-1.4.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 2957.944709] usb 1-1.4.3: Product: FT260
[ 2957.944715] usb 1-1.4.3: Manufacturer: FTDI
[ 2958.019433] ft260 0003:0403:6030.001D: chip code: 0260 0200
[ 2958.021046] ft260_is_interface_enabled: interface:  0x00
[ 2958.021053] ft260_is_interface_enabled: chip mode:  0x00
[ 2958.021058] ft260_is_interface_enabled: clock_ctl:  0x02
[ 2958.021063] ft260_is_interface_enabled: i2c_enable: 0x01
[ 2958.021067] ft260_is_interface_enabled: uart_mode:  0x03
[ 2958.021072] ft260_is_interface_enabled: gpio2_func: 0x01
[ 2958.021077] ft260_is_interface_enabled: gpioA_func: 0x03
[ 2958.021082] ft260_is_interface_enabled: gpioG_func: 0x06
[ 2958.021086] ft260_is_interface_enabled: wakeup_int: 0x01
[ 2958.021092] ft260 0003:0403:6030.001D: USB HID v1.11 Device [FTDI FT260] on usb-3f980000.usb-1.4.3/input0
[ 2958.022670] ft260_xfer_status: bus_status 0x20, wakeup
[ 2958.023044] ft260_xfer_status: bus_status 0x20, clock 100
[ 2958.023354] ft260 0003:0403:6030.001D: initialize gpio chip
[ 2958.023362] ft260 0003:0403:6030.001D: enabled GPIOs: 0000
[ 2958.109577] ft260 0003:0403:6030.001E: chip code: 0260 0200
[ 2958.111194] ft260_is_interface_enabled: interface:  0x01
[ 2958.111208] ft260_is_interface_enabled: chip mode:  0x00
[ 2958.111218] ft260_is_interface_enabled: clock_ctl:  0x02
[ 2958.111228] ft260_is_interface_enabled: i2c_enable: 0x01
[ 2958.111237] ft260_is_interface_enabled: uart_mode:  0x03
[ 2958.111247] ft260_is_interface_enabled: gpio2_func: 0x01
[ 2958.111256] ft260_is_interface_enabled: gpioA_func: 0x03
[ 2958.111266] ft260_is_interface_enabled: gpioG_func: 0x06
[ 2958.111275] ft260_is_interface_enabled: wakeup_int: 0x01
[ 2958.111300] ft260 0003:0403:6030.001E: uart interface is not supported
$ lsusb
Bus 001 Device 070: ID 0403:6030 Future Technology Devices International, Ltd FT260
Bus 001 Device 069: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 003: ID 0424:ec00 Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub


$ i2cdetect -l
i2c-11	i2c       	FT260 usb-i2c bridge            	I2C adapter
i2c-2	i2c       	bcm2835 (i2c@7e805000)          	I2C adapter

Very happy to provide as many logs and as much help as possible as I'm keen to get this resolved - let me know what you need !

I2C_SMBUS_QUICK support

Hi, all

This ft260 driver is very helpful for me.

I have one question here,

I found the commit that you removed the I2C_SMBUS_QUICK commands.

Can we implement SMBUS quick write command by ft260_i2c_write?
If we set ft260_i2c_write parameter len to 0, is that okay?

HID-FT260: can't build on gcc-14

execution returns error when gcc-14 is being used, caused by incompatible pointers for " tty_operations.write=ft260_uart_write "

GPIO doesn't work under RaspberryPi-OS Bookworm,

Dear Michael,
while HID to i2c still works fine, GPIO stopped to work. Outcome of "gpioinfo":
gpiochip2 - 14 lines:
line 0: unnamed unused input active-high
line 1: unnamed unused input active-high
line 2: unnamed unused input active-high
line 3: unnamed unused input active-high
line 4: unnamed unused input active-high
line 5: unnamed unused input active-high
line 6: unnamed unused input active-high
line 7: unnamed unused input active-high
line 8: unnamed unused input active-high
line 9: unnamed unused input active-high
line 10: unnamed unused input active-high
line 11: unnamed unused input active-high
line 12: unnamed unused input active-high
line 13: unnamed unused input active-high

As well, shell commands from example on github page stopped to work:
$ ~/hid-ft260 $ cat $SYSFS_FT260/gpio2_func
cat: /gpio2_func: No such file or directory

Confirmation that kernel module is correctly loaded:
$ i2cdetect -l
i2c-20 i2c fef04500.i2c I2C adapter
i2c-21 i2c fef09500.i2c I2C adapter
i2c-22 i2c FT260 usb-i2c bridge I2C adapter

Would you be so kind and test yourself to confirm please? Thanks in advance!

Doesn't automatically load 'i2c-dev'

Hi,
Was able to build the kernel module, but it looks like it's missing a dependency as it doesn't automatically load 'i2c-dev.ko'. Maybe this is by design, but it tripped me up for a bit.

Without this I was not able to see any I2C interfaces listed under '/dev/', but they did exist under '/sys/bus/i2c'.

Once loaded I DID see the interface and was able to access chip via Python. Thanks,
Simon.

root@thevoid:/home/simon# cat i2c_test.py
import smbus

bus = smbus.SMBus(20)

DEVICE_ADD = 0x55
DEVICE_REG = 0xE0

version = bus.read_i2c_block_data(DEVICE_ADD, DEVICE_REG, 4)
print(version)

root@thevoid:/home/simon# python3 i2c_test.py 
[0, 0, 0, 1]

Can't compile latest version of the driver on WSL2

Hi Michael,

I would like to read more than 60 bytes at a time but the version of the driver provided with the linux kernel (v5.15.153.1 from WSL2) seems to be pretty old as i'm facing the error unsupported read len.

I tried to compile the latest version of your driver however, i have the following compilation errors:

error: implicit declaration of function ‘timer_delete_sync’

error: initialization of ‘void (*)(struct tty_struct *, struct ktermios *)’ from incompatible pointer type ‘void (*)(struct tty_struct *, const struct ktermios *)’ [-Werror=incompatible-pointer-types]

Do you have any idea of what is hapenning ?

ttyFTx not showing up

I installed the driver, insmod the .ko file , ran the setenv script, however i am not able to see any ttyFTx device in /dev/. Am i missing a step?

irq DIO8

if only use i2c interface, the irq dio8 can get report?

Setting gpio2_fun

Hi, is there a way to set gpio2_func without "sudo" ? I mean could the file come up as +666 from the start.
sudo bash -c "echo 0 > $SYSFS_FT260/gpio2_func"

Regards,

Just a question

Hello.
I'm interested to use an USB to I2C chip/board in order to have a "pure" I2C Master bus.
I need it in order to replace a Raspberry Pi with a Linux machine running on x86 via Proxmox.

Currently I poll I2C sensors via the I2C Master bus generated by the Raspberry Pi, all ok.

So I'm looking for an USB to I2C chip/board that can handle a "pure" I2C Master bus so I can continue to read I2C sensors.

I see that the FTDI FT260 and the Silicon Labs CP2112 are the "right" chips that can do what I need.

Both chips are supported in the Linux Kernel but it seems the Silicon Labs CP2112 have some "limitation" since when the command "i2cdetect" is executed the reply contain the message: Warning: Can't use SMBus Quick Write, will skip some addresses.

image

So it seems the Silicon Labs CP2112 has some limitation for the addresses.

Well, does the FT260 has the same limitation?
In other words, can I use FT260 like the I2C bus generated by the Raspberry Pi?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.