I’m working with the Colibri iMX6DL module and have a device tree configuration involving multiple MCP23017 I2C IO expanders. The IO expanders are mapped to two separate I2C buses. Here’s the relevant portion of my device tree:
/* I2C */
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c_1>;
status = "okay";
/* sgtl5000 audio codec connected to SSI2*/
codec2: sgtl5000@0a {
compatible = "fsl,sgtl5000";
reg = <0x0a>;
clocks = <&clk12m>;
lrclk-strength = <0x3>;
VDDA-supply = <®_3p3v>;
VDDIO-supply = <®_3p3v>;
VDDD-supply =<&vgen4_reg>;
};
/* mcp23017 I2C IO Expander */
gpio_ex3: gpio_mcp@20 {
compatible = "microchip,mcp23017";
gpio-controller;
#gpio-cells = <2>;
reg = <0x20>;
status = "okay";
};
gpio_ex4: gpio_mcp@21 {
compatible = "microchip,mcp23017";
gpio-controller;
#gpio-cells = <2>;
reg = <0x21>;
status = "okay";
};
lm75b@48 {
compatible = "national,lm75b", "national,lm75", "national,lm75a";
reg = <0x48>;
};
};
&i2c4 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
status = "okay";
gpio_ex1: gpio_mcp@20 {
compatible = "microchip,mcp23017";
gpio-controller;
#gpio-cells = <2>;
reg = <0x20>;
status = "okay";
};
gpio_ex2: gpio_mcp@21 {
compatible = "microchip,mcp23017";
gpio-controller;
#gpio-cells = <2>;
reg = <0x21>;
status = "okay";
};
/* M41T0M6 real time clock on carrier board */
rtc_i2c: rtc@68 {
compatible = "st,m41t00";
reg = <0x68>;
};
};
When one of the IO expanders on the I2C bus fails (e.g., burns out), the GPIO numbering for the remaining expanders shifts unexpectedly
I tried to mitigate this by explicitly setting the gpio-ranges
property in the device tree to fix the GPIO base numbers. However, after making these changes, I noticed that i2cdetect
shows the address 0x21
instead of the expected UU
, indicating that the driver didn’t claim the device.
how could I fix this numbering?
or how could I solve this issue in any other ways?
Any guidance on resolving this issue would be greatly appreciated!
I’m using a Colibri IMX6dlDL 512 with BSP2.8b6 and the Iris carrier board.
Thank you for your support.
best regard
Mehdi
Hi, I’m the Toradex AI Assistant. I’m in early beta, and I would appreciate your feedback.
The Toradex Support team will follow up with you shortly!
Did you like my answer?
To address the issue of GPIO numbering shifts due to an I2C IO expander failure on the Colibri iMX6DL, you can take the following steps:
-
Fix GPIO Base Numbers:
Ensure that you have correctly set the gpio-ranges
property in your device tree to fix the GPIO base numbers. This property helps in mapping the GPIOs to a fixed range, preventing shifts when an expander fails. Here is an example of how to set the gpio-ranges
property:
gpio_ex3: gpio_mcp@20 {
compatible = "microchip,mcp23017";
gpio-controller;
#gpio-cells = <2>;
reg = <0x20>;
gpio-ranges = <&gpio1 0 0 16>;
status = "okay";
};
gpio_ex4: gpio_mcp@21 {
compatible = "microchip,mcp23017";
gpio-controller;
#gpio-cells = <2>;
reg = <0x21>;
gpio-ranges = <&gpio1 16 0 16>;
status = "okay";
};
-
Check Driver Binding:
Ensure that the driver is correctly binding to the I2C devices. The i2cdetect
tool showing 0x21
instead of UU
indicates that the driver did not claim the device. This could be due to a mismatch in the device tree configuration or a driver issue. Verify that the compatible
property matches the driver’s expected value.
-
Device Tree Configuration:
Double-check your device tree configuration for any discrepancies. Ensure that the reg
property values are unique and correctly assigned to each I2C device.
-
Kernel Logs:
Check the kernel logs (dmesg
) for any error messages related to the I2C devices. This can provide insights into why the driver is not claiming the device.
-
Fallback Mechanism:
Implement a fallback mechanism in your application to handle the failure of an I2C expander. This can include re-scanning the I2C bus and reconfiguring the GPIOs dynamically.
-
Update BSP:
Consider updating to a more recent BSP version if possible, as newer versions may contain bug fixes and improvements related to I2C and GPIO handling.
By following these steps, you should be able to mitigate the
Hi @me_ahani98 !
I understand you are talking about the GPIO chip numbering, right? I would expect that the “internal” GPIO lines for a given GPIO chip (GPIO expander) will remain the same despite having a different GPIO chip numbering.
For such case, I think that a suitable approach is to make use of udev rules so you will have your own symbolic link with a name (and number) that you defined yourself, regardless of the sequence of probing that Linux kernel goes through.
And, being more general, it is safer to create your own udev rules for the devices you need, so you are in control of their names and you do not depend on the number that Linux gives them, which depends on the probing order of the kernel, which is something we can’t control.
Best regards,
Thank you for your insights. Could you please provide a sample udev rule for this scenario? It would be very helpful to see a practical example.
Best regards,
Mehdi