Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 8042

Interfacing (DSI, CSI, I2C, etc.) • i2c module not loading and freezing bus

$
0
0
Hi,
# Summary
I have a b2qt yocto image using Qt6 built for CM4 and CM3. For the CM4 the driver works fine. For the CM3 the driver either fails to load or jams the bus resulting in `i2cdetect` showing all address as active (=> SDA line to ground apparently) jamming everything on the bus or or just fails during probe and nothing on the i2c bus working.

# Set-up Details
We have custom board that takes either a raspberry pi CM3, CM3+ or CM4. Our yocto image in based on a b2qt image that uses the standard raspberry pi meta layer.

If I use i2cdetect I can see our device (ft200xd) on 0x22

Code:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f00:                         -- -- 0a -- -- -- -- --10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --20: -- -- 22 -- -- -- -- -- -- -- -- -- -- -- -- --30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- UU70: -- -- -- -- -- -- -- --
If I try and load the driver I get the following error

Code:

[   94.798487] ft200xd 0-0022: Probing ft200xd_probe:415:[   94.798506] ft200xd 0-0022: ft200xd_read_id: using I²C addr=0x22 (shifted: 0x44)[   94.798513] ft200xd 0-0022: ft200xd_read_id: msg[0]: addr=0x7c, flags=0x0[   94.798519] ft200xd 0-0022: ft200xd_read_id: msg[1]: addr=0x7c, flags=0x4801[   94.798632] ft200xd 0-0022: ft200xd_read_id: received buf[0]=0xfe, buf[1]=0xfe, buf[2]=0xfe[   94.798641] ft200xd 0-0022: ft200xd_read_id: I2C transaction failed: -5
This comes from the following section of code.

Code:

static int ft200xd_read_id(struct ft200xd *ft200xd){int ret;struct i2c_client *client = ft200xd->client;u8 addr = (client->addr << 1);u8 buf[3];struct i2c_msg msg[2] = {{.addr = FT200XD_DEV_ID_CALL_ADDR,.len = sizeof(addr),.buf = &addr,.flags = 0,},{.addr = FT200XD_DEV_ID_CALL_ADDR,.flags = I2C_M_RD | I2C_M_NOSTART | I2C_M_NO_RD_ACK,.len = sizeof(buf),.buf = buf,},};dev_info(&client->dev, "ft200xd_read_id: using I²C addr=0x%02x (shifted: 0x%02x)\n", client->addr, addr);dev_info(&client->dev, "ft200xd_read_id: msg[0]: addr=0x%02x, flags=0x%x\n", msg[0].addr, msg[0].flags);dev_info(&client->dev, "ft200xd_read_id: msg[1]: addr=0x%02x, flags=0x%x\n", msg[1].addr, msg[1].flags);ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));dev_info(&client->dev, "ft200xd_read_id: received buf[0]=0x%02x, buf[1]=0x%02x, buf[2]=0x%02x\n", buf[0], buf[1], buf[2]);if (ret < 0) {dev_err(&client->dev, "%s: I2C transaction failed: %d\n",__func__, ret);return ret;}return (buf[0] << 16) + (buf[1] << 8) + buf[0];}
which is called during probing.

I have also had the prob succeed, but causing the bus to react like this

Code:

i2cdetect -y     0 0 1 2 3 4 5 6 7 8  9  a  b  c  d  e  f00:                   08 09 0a 0b 0c 0d 0e 0f 10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20: 20 21 UU 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e UU 70: 70 71 72 73 74 75 76 77
I can see that our dtoverlay has loaded

Code:

 find /sys -iname *ft200*/sys/kernel/btf/ft200xd/sys/firmware/devicetree/base/soc/i2c@7e205000/ft200xd@22/sys/bus/i2c/drivers/ft200xd/sys/module/ft200xd/sys/module/ft200xd/drivers/i2c:ft200xd
but the device has not properly loaded.

As well as using the same yocto recipe but with a CM4 module installed. I also have a only CM3 qt5 image using the same driver, burnt that to a sd card, booted that and everything works. So exact same hardware and same driver.

# Question
The hardware is clearly not an issue as a swap of image allows the bus to work. This has the same overlay and same driver.

A swap of image (but built from same yocto recipe) and compute module from a CM£ to a CM4 with the same driver and same overlay and the same config.txt.

However something changes. Something breaks the bus. I have no idea where to go. I am clearly getting back rubbish. I can still see my other items on the bus (0x0a and 0x6f that has been bound to a overlay) but these devices are not working correctly anymore.

Any suggestions of where to go would be gratefully received.

# Driver and overlay

Code:

/dts-v1/;/plugin/;// This has already had the patch 0002-device-tree-overlay-fix-for-ft200xd.patch applied to it.// This changed:// -        target = <&i2c_vc>;// +        target = <&ft200xd_i2cbus>;/ {compatible = "brcm,bcm2835";fragment@0 {target = <&ft200xd_i2cbus>;__overlay__ {#address-cells = <1>;#size-cells = <0>;status = "okay";ft200xd: ft200xd@22 {compatible = "ft200xd";reg = <0x22>;status = "okay";};};};ft200xd_frag100: fragment@100 {target = <&i2c_arm>;ft200xd_i2cbus: __overlay__ {status = "okay";};};__overrides__ {i2c0 = <&ft200xd_frag100>, "target:0=",<&i2c0>;i2c_csi_dsi = <&ft200xd_frag100>, "target:0=",<&i2c_csi_dsi>;addr = <&ft200xd>, "reg:0";};};


Prob function ft200xd_probe

Code:

static int ft200xd_probe(struct i2c_client *client) //,//const struct i2c_device_id *id) // tb101 remove second argument to match function profile of i2c_driver{struct ft200xd *ft200xd;int ret = 0;dev_info(&client->dev, "Probing %s:%d:\n",__func__, __LINE__);ft200xd = devm_kzalloc(&client->dev, sizeof(*ft200xd), GFP_KERNEL);if (!ft200xd)return -ENOMEM;ft200xd->client = client;i2c_set_clientdata(client, ft200xd);ret = ft200xd_read_id(ft200xd);if (ret < 0)return -ENODEV;INIT_DELAYED_WORK(&ft200xd->read_work, ft200xd_read_worker);INIT_DELAYED_WORK(&ft200xd->write_work, ft200xd_write_worker);tty_port_init(&ft200xd->port);ft200xd->port.ops = &ft200xd_port_ops;ft200xd->tty_driver = tty_alloc_driver(1, 0);if (!ft200xd->tty_driver)return -ENOMEM;ft200xd->client = client;ft200xd->tty_driver->driver_name = "ft200xd_tty";ft200xd->tty_driver->name = "ttyFT200XD";ft200xd->tty_driver->major = 0;ft200xd->tty_driver->minor_start = 0;ft200xd->tty_driver->type = TTY_DRIVER_TYPE_SERIAL;ft200xd->tty_driver->subtype = SERIAL_TYPE_NORMAL;ft200xd->tty_driver->flags = TTY_DRIVER_REAL_RAW;ft200xd->tty_driver->init_termios = tty_std_termios;ft200xd->tty_driver->init_termios.c_iflag = 0;ft200xd->tty_driver->init_termios.c_oflag = OPOST;ft200xd->tty_driver->init_termios.c_cflag = CS8 | CREAD | CLOCAL;tty_set_operations(ft200xd->tty_driver, &ft200xd_serial_ops);tty_port_link_device(&ft200xd->port, ft200xd->tty_driver, 0);atomic_set(&ft200xd->closing, 0);atomic_set(&ft200xd->stop, 0);mutex_init(&ft200xd->lock);ret = tty_register_driver(ft200xd->tty_driver);if (ret) {dev_err(&client->dev,"%s - tty_register_driver failed: %d\n",__func__, ret);goto err_tty;}// tn101 dev_info(&client->dev, "Probed, id: %06x\n", ret); // tb101return ret;err_tty:tty_driver_kref_put(ft200xd->tty_driver); // tb101 put_tty_driver(ft200xd->tty_driver);return ret;}

Statistics: Posted by NTVisitor — Mon Jul 28, 2025 8:51 pm



Viewing all articles
Browse latest Browse all 8042

Trending Articles