Hi all,
The i2c-gpio-mux can be used to describe a multiplexer built upon
several i2c isolators having an enable pin (such as LTC4310):
+---------------+ +------+ +------+
| +-----------+ | | dev | | dev |
| | GPIO_EN_A |-|-----------| +------+ +------+
| +-----------+ | +-----+---+ | |
| | |--| isol. A |---------+---------+
| +-----+ | | +---------+
| SOC | I2C |---|--|
| +-----+ | | +---------+
| | |--| isol. B |------+---------+---------+
| +-----------+ | +-----+---+ | | |
| | GPIO_EN_B |-|-----------| +------+ +------+ +------+
| +-----------+ | | dev | | dev | | dev |
+---------------+ +------+ +------+ +------+
These isolators often need some time between their enable pin's
assertion and the first i2c transfer. If the first i2c transfer
happens before this enabling time is reached, transfer fails.
There is no available option to configure such a time in the
i2c-gpio-mux driver.
Add a optional property in the bindings called 'transition-delay-us'.
If present, driver waits for this delay every time a new bus is
selected, i.e. before returning from the bus_select() callback.
Changes in v2:
* Rewrite bindings' commit log
* Express the 'transition delay' in us instead of ms
Bastien Curutchet (3):
dt-bindings: i2c: gpio: Add 'transition-delay-us' property
i2c: mux: gpio: Re-order #include to match alphabetic order
i2c: mux: gpio: Add support for the 'transition-delay-us' property
.../devicetree/bindings/i2c/i2c-mux-gpio.yaml | 3 +++
drivers/i2c/muxes/i2c-mux-gpio.c | 14 ++++++++++----
include/linux/platform_data/i2c-mux-gpio.h | 2 ++
3 files changed, 15 insertions(+), 4 deletions(-)
--
2.44.0
I2C MUXes described by the i2c-gpio-mux sometimes need a significant
amount of time to switch from a bus to another. When a new bus is
selected, the first I2C transfer can fail if it occurs too early. There
is no way to describe this transition delay that has to be waited before
starting the first I2C transfer.
Add a 'transition-delay-us' property that indicates the delay to be
respected before doing the first i2c transfer.
Signed-off-by: Bastien Curutchet <[email protected]>
---
Documentation/devicetree/bindings/i2c/i2c-mux-gpio.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.yaml b/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.yaml
index f34cc7ad5a00..20d72c3e1e10 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.yaml
+++ b/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.yaml
@@ -57,6 +57,9 @@ properties:
last value used.
$ref: /schemas/types.yaml#/definitions/uint32
+ transition-delay-us:
+ description: Delay to wait before doing any transfer when a new bus gets selected.
+
allOf:
- $ref: i2c-mux.yaml
--
2.44.0
The #includes don't match alphabetic order.
Re-order #includes to match the alphabetic order before adding a new
one.
Signed-off-by: Bastien Curutchet <[email protected]>
---
drivers/i2c/muxes/i2c-mux-gpio.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
index d6bbb8b68333..c61e9d9ea695 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
@@ -5,16 +5,16 @@
* Peter Korsgaard <[email protected]>
*/
+#include <linux/bits.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
+#include <linux/module.h>
#include <linux/overflow.h>
#include <linux/platform_data/i2c-mux-gpio.h>
#include <linux/platform_device.h>
-#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/bits.h>
-#include <linux/gpio/consumer.h>
-#include <linux/gpio/driver.h>
struct gpiomux {
struct i2c_mux_gpio_platform_data data;
--
2.44.0
Some hardware need some time to switch from a bus to another. This can
cause the first transfers following the selection of a bus to fail.
There is no way to configure this kind of waiting time in the driver.
Add support for the 'transition-delay-us' device-tree property. When set,
the i2c_mux_gpio_select() applies a delay before returning, leaving
enough time to the hardware to switch to the new bus.
Signed-off-by: Bastien Curutchet <[email protected]>
---
drivers/i2c/muxes/i2c-mux-gpio.c | 6 ++++++
include/linux/platform_data/i2c-mux-gpio.h | 2 ++
2 files changed, 8 insertions(+)
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
index c61e9d9ea695..b9cfc80660e2 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
@@ -6,6 +6,7 @@
*/
#include <linux/bits.h>
+#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/i2c.h>
@@ -37,6 +38,9 @@ static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan)
i2c_mux_gpio_set(mux, chan);
+ if (mux->data.transition_delay)
+ udelay(mux->data.transition_delay);
+
return 0;
}
@@ -116,6 +120,8 @@ static int i2c_mux_gpio_probe_fw(struct gpiomux *mux,
if (device_property_read_u32(dev, "idle-state", &mux->data.idle))
mux->data.idle = I2C_MUX_GPIO_NO_IDLE;
+ device_property_read_u32(dev, "transition-delay-us", &mux->data.transition_delay);
+
return 0;
}
diff --git a/include/linux/platform_data/i2c-mux-gpio.h b/include/linux/platform_data/i2c-mux-gpio.h
index 816a4cd3ccb5..c449f714d32b 100644
--- a/include/linux/platform_data/i2c-mux-gpio.h
+++ b/include/linux/platform_data/i2c-mux-gpio.h
@@ -19,6 +19,7 @@
* position
* @n_values: Number of multiplexer positions (busses to instantiate)
* @idle: Bitmask to write to MUX when idle or GPIO_I2CMUX_NO_IDLE if not used
+ * @transition_delay: Delay to wait when a new bus is selected
*/
struct i2c_mux_gpio_platform_data {
int parent;
@@ -26,6 +27,7 @@ struct i2c_mux_gpio_platform_data {
const unsigned *values;
int n_values;
unsigned idle;
+ int transition_delay;
};
#endif /* _LINUX_I2C_MUX_GPIO_H */
--
2.44.0
Hi!
2024-05-29 at 11:17, Bastien Curutchet wrote:
> I2C MUXes described by the i2c-gpio-mux sometimes need a significant
> amount of time to switch from a bus to another. When a new bus is
> selected, the first I2C transfer can fail if it occurs too early. There
> is no way to describe this transition delay that has to be waited before
> starting the first I2C transfer.
>
> Add a 'transition-delay-us' property that indicates the delay to be
> respected before doing the first i2c transfer.
The io-channel-mux has a property with very similar intent named
settle-time-us [1]. I think we should use the same name here.
[1] Documentation/devicetree/bindings/iio/multiplexer/io-channel-mux.yaml
Cheers,
Peter
Hi!
2024-05-29 at 11:17, Bastien Curutchet wrote:
> Some hardware need some time to switch from a bus to another. This can
> cause the first transfers following the selection of a bus to fail.
> There is no way to configure this kind of waiting time in the driver.
>
> Add support for the 'transition-delay-us' device-tree property. When set,
> the i2c_mux_gpio_select() applies a delay before returning, leaving
> enough time to the hardware to switch to the new bus.
>
> Signed-off-by: Bastien Curutchet <[email protected]>
> ---
> drivers/i2c/muxes/i2c-mux-gpio.c | 6 ++++++
> include/linux/platform_data/i2c-mux-gpio.h | 2 ++
> 2 files changed, 8 insertions(+)
>
> diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
> index c61e9d9ea695..b9cfc80660e2 100644
> --- a/drivers/i2c/muxes/i2c-mux-gpio.c
> +++ b/drivers/i2c/muxes/i2c-mux-gpio.c
> @@ -6,6 +6,7 @@
> */
>
> #include <linux/bits.h>
> +#include <linux/delay.h>
> #include <linux/gpio/consumer.h>
> #include <linux/gpio/driver.h>
> #include <linux/i2c.h>
> @@ -37,6 +38,9 @@ static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan)
>
> i2c_mux_gpio_set(mux, chan);
>
> + if (mux->data.transition_delay)
> + udelay(mux->data.transition_delay);
fsleep() is appropriate here.
Cheers,
Peter
On Wed, May 29, 2024 at 02:13:37PM +0200, Peter Rosin wrote:
> Hi!
>
> 2024-05-29 at 11:17, Bastien Curutchet wrote:
> > I2C MUXes described by the i2c-gpio-mux sometimes need a significant
> > amount of time to switch from a bus to another. When a new bus is
> > selected, the first I2C transfer can fail if it occurs too early. There
> > is no way to describe this transition delay that has to be waited before
> > starting the first I2C transfer.
> >
> > Add a 'transition-delay-us' property that indicates the delay to be
> > respected before doing the first i2c transfer.
>
> The io-channel-mux has a property with very similar intent named
> settle-time-us [1]. I think we should use the same name here.
>
> [1] Documentation/devicetree/bindings/iio/multiplexer/io-channel-mux.yaml
Agreed. I knew we had something and went looking... I only checked the
base mux and i2c mux bindings.
Rob
Hi Rob, Hi Peter,
On 6/3/24 17:58, Rob Herring wrote:
> On Wed, May 29, 2024 at 02:13:37PM +0200, Peter Rosin wrote:
>> Hi!
>>
>> 2024-05-29 at 11:17, Bastien Curutchet wrote:
>>> I2C MUXes described by the i2c-gpio-mux sometimes need a significant
>>> amount of time to switch from a bus to another. When a new bus is
>>> selected, the first I2C transfer can fail if it occurs too early. There
>>> is no way to describe this transition delay that has to be waited before
>>> starting the first I2C transfer.
>>>
>>> Add a 'transition-delay-us' property that indicates the delay to be
>>> respected before doing the first i2c transfer.
>>
>> The io-channel-mux has a property with very similar intent named
>> settle-time-us [1]. I think we should use the same name here.
>>
>> [1] Documentation/devicetree/bindings/iio/multiplexer/io-channel-mux.yaml
>
> Agreed. I knew we had something and went looking... I only checked the
> base mux and i2c mux bindings.
>
Ok I'll do this in V3, thank you.
Best regards
Bastien