Hi, I’m the Toradex AI Assistant. The Toradex Support team will follow up with you shortly!
Did you like my answer?
The approach you are using to handle the fault tolerance of the I2C mux by declaring both a 3-channel and a 2-channel mux in the device tree is indeed a bit unconventional and can lead to unpredictable behavior due to the order of initialization. The device tree does not guarantee the order of initialization based on the order of declaration, which can lead to the issues you are experiencing.
A more robust approach would be to handle the dynamic nature of the I/O expander in the driver code rather than relying on the device tree. Here are a few suggestions:
-
Custom Driver Code: Modify the I2C mux driver to dynamically check the presence of the third I/O expander (
pca9674_3
) at runtime. If the expander is not present, the driver can configure the mux as a 2-channel mux instead of a 3-channel mux. This way, you can handle the fault tolerance within the driver itself. -
Device Tree Overlays: Use device tree overlays to dynamically modify the device tree at runtime based on the presence of the I/O expander. You can create separate overlays for the 2-channel and 3-channel configurations and apply the appropriate overlay during the boot process based on the detected hardware.
-
Deferred Probing: Utilize deferred probing in the driver to wait for the I/O expanders to be initialized before configuring the mux. This can help ensure that the driver only attempts to configure the mux once all necessary components are available.
Here is an example of how you might modify the driver to check for the presence of the third I/O expander:
static int i2c_mux_gpio_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct gpio_desc *gpio3;
int ret;
// Check for the presence of the third I/O expander
gpio3 = devm_gpiod_get_optional(dev, "mux-gpio3", GPIOD_OUT_LOW);
if (IS_ERR(gpio3)) {
dev_err(dev, "Failed to get mux-gpio3\n");
return PTR_ERR(gpio3);
}
if (gpio3) {
// Configure as 3-channel mux
ret = configure_3_channel_mux(client);
} else {
// Configure as 2-channel mux
ret = configure_2_channel_mux(client);
}
return ret;
}
In this example, configure_3_channel_mux
and configure_2_channel_mux
are functions that configure the mux as a 3-channel or 2-channel mux, respectively, based on the presence of the third I/O expander.
By handling the fault tolerance in the driver code, you can ensure a more predictable and reliable behavior regardless of the order of declaration in the device tree.
Please, also check if these links can help you solve your problem: