* [PATCH RFC 0/7] I2C Mux per channel bus speed
@ 2025-09-22 6:20 Marcus Folkesson
2025-09-22 6:20 ` [PATCH RFC 1/7] i2c: core: add callback to change bus frequency Marcus Folkesson
` (7 more replies)
0 siblings, 8 replies; 13+ messages in thread
From: Marcus Folkesson @ 2025-09-22 6:20 UTC (permalink / raw)
To: Wolfram Sang, Peter Rosin, Michael Hennerich, Bartosz Golaszewski,
Andi Shyti
Cc: linux-i2c, linux-kernel, linux-arm-kernel, Marcus Folkesson
This is an RFC on how to implement a feature to have different bus
speeds on different channels with an I2C multiplexer/switch.
The benefit with this approach is that you may group devices after
the fastest bus speed they can handle.
A real-world example is that you could have e.g. a display running @400kHz
and a smart battery running @100kHz using the same I2C controller.
There are many corner cases where this may cause a problem for some
hardware topologies. I've tried to describe those I could think of
in the documentation, see Patch #7.
E.g. one risk is that if the mux driver does not disconnect channels
when Idle, this may cause a higher frequency to "leak" through to
devices that are supposed to run at lower bus speed.
This is not only a "problem" for changing bus speed but could also be
an issue for potential address conflicts.
The implementation is split up into several patches:
Patch #1 Introduce a callback for the i2c controller to set bus speed
Patch #2 Introduce idle state to the mux core.
Patch #3 Introduce functionality to adjust bus speed depending on mux
channel.
Patch #4 Set idle state for an example mux driver
Patch #5 Cleanup i2c-davinci driver a bit to prepare it for set_clk_freq
Parch #6 Implement set_clk_freq for the i2c-davinci driver
Parch #7 Update documentation with this feature
[1] https://elixir.bootlin.com/linux/v6.16.7/source/Documentation/i2c/i2c-topology.rst#L240
[2] https://elixir.bootlin.com/linux/v6.16.7/source/Documentation/i2c/i2c-topology.rst#L298
[3] https://elixir.bootlin.com/linux/v6.16.7/source/Documentation/i2c/i2c-topology.rst#L322
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
Marcus Folkesson (7):
i2c: core: add callback to change bus frequency
i2c: mux: add idle_state property to i2c_mux_core
i2c: mux: add support for per channel bus frequency
i2c: mux: ltc4306: set correct idle_state in i2c_mux_core
i2c: davinci: calculate bus freq from Hz instead of kHz
i2c: davinci: add support for setting bus frequency
docs: i2c: i2c-topology: add section about bus speed
Documentation/i2c/i2c-topology.rst | 176 ++++++++++++++++++++++++++++++++++++
drivers/i2c/busses/i2c-davinci.c | 37 ++++++--
drivers/i2c/i2c-mux.c | 127 +++++++++++++++++++++++---
drivers/i2c/muxes/i2c-mux-ltc4306.c | 3 +
include/linux/i2c-mux.h | 21 +++++
include/linux/i2c.h | 13 +++
6 files changed, 357 insertions(+), 20 deletions(-)
---
base-commit: 22f20375f5b71f30c0d6896583b93b6e4bba7279
change-id: 20250913-i2c-mux-b0063de2ae4d
Best regards,
--
Marcus Folkesson <marcus.folkesson@gmail.com>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH RFC 1/7] i2c: core: add callback to change bus frequency
2025-09-22 6:20 [PATCH RFC 0/7] I2C Mux per channel bus speed Marcus Folkesson
@ 2025-09-22 6:20 ` Marcus Folkesson
2025-09-22 6:20 ` [PATCH RFC 2/7] i2c: mux: add idle_state property to i2c_mux_core Marcus Folkesson
` (6 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Marcus Folkesson @ 2025-09-22 6:20 UTC (permalink / raw)
To: Wolfram Sang, Peter Rosin, Michael Hennerich, Bartosz Golaszewski,
Andi Shyti
Cc: linux-i2c, linux-kernel, linux-arm-kernel, Marcus Folkesson
All devices on the same I2C bus share the same clock line and the bus
frequency has therefor be chosen so that all attached devices are able
to tolarate that clock rate. IOW, the bus speed must be set for the
slowest attached device.
With I2C multiplexers/switches on the other hand, it would be possible
to have different "domains" that runs with different speeds.
Prepare for such a feature by provide an optional callback function to
change bus frequency.
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
include/linux/i2c.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 20fd41b51d5c85ee1665395c07345faafd8e2fca..d147e388dbab27966beb4dfbf869928b429e082c 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -742,6 +742,8 @@ struct i2c_adapter {
struct rt_mutex mux_lock;
int timeout; /* in jiffies */
+ int clock_hz;
+ int (*set_clk_freq)(struct i2c_adapter *adap, u32 clock_hz); /* Optional */
int retries;
struct device dev; /* the adapter device */
unsigned long locked_flags; /* owned by the I2C core */
@@ -835,6 +837,17 @@ i2c_unlock_bus(struct i2c_adapter *adapter, unsigned int flags)
adapter->lock_ops->unlock_bus(adapter, flags);
}
+static inline int
+i2c_adapter_set_clk_freq(struct i2c_adapter *adapter, u32 clock_hz)
+{
+ int ret = -EOPNOTSUPP;
+
+ if (adapter->set_clk_freq)
+ ret = adapter->set_clk_freq(adapter, clock_hz);
+
+ return ret;
+}
+
/**
* i2c_mark_adapter_suspended - Report suspended state of the adapter to the core
* @adap: Adapter to mark as suspended
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC 2/7] i2c: mux: add idle_state property to i2c_mux_core
2025-09-22 6:20 [PATCH RFC 0/7] I2C Mux per channel bus speed Marcus Folkesson
2025-09-22 6:20 ` [PATCH RFC 1/7] i2c: core: add callback to change bus frequency Marcus Folkesson
@ 2025-09-22 6:20 ` Marcus Folkesson
2025-09-22 6:20 ` [PATCH RFC 3/7] i2c: mux: add support for per channel bus frequency Marcus Folkesson
` (5 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Marcus Folkesson @ 2025-09-22 6:20 UTC (permalink / raw)
To: Wolfram Sang, Peter Rosin, Michael Hennerich, Bartosz Golaszewski,
Andi Shyti
Cc: linux-i2c, linux-kernel, linux-arm-kernel, Marcus Folkesson
Muxes treat their channels differently when idle.
Let the mux core have this information to make it available for
internal use.
Reuse the same state values used by CONFIG_MULTIPLEXER.
Possible idle states are:
- MUX_IDLE_AS_IS: Leave channels as is when idle
- MUX_IDLE_DISCONNECT: Disconnect channel (set HiZ when idle)
- <n>: Enable channel n when idle
Default value is set to MUX_IDLE_AS_IS.
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
drivers/i2c/i2c-mux.c | 1 +
include/linux/i2c-mux.h | 21 +++++++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 4d8690981a55dc0e1b35454971923791e6ed9f7f..5caa927c0caae512af029f0d1ae9b7f845ba3f6f 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -250,6 +250,7 @@ struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent,
muxc->select = select;
muxc->deselect = deselect;
muxc->max_adapters = max_adapters;
+ muxc->idle_state = MUX_IDLE_AS_IS;
return muxc;
}
diff --git a/include/linux/i2c-mux.h b/include/linux/i2c-mux.h
index 1784ac7afb116ce64e9e9fca1ee127c2bbbd2fb9..9e230ad69377b74f9ec809c40ccffd95538c4595 100644
--- a/include/linux/i2c-mux.h
+++ b/include/linux/i2c-mux.h
@@ -13,6 +13,7 @@
#ifdef __KERNEL__
+#include <dt-bindings/mux/mux.h>
#include <linux/bitops.h>
struct i2c_mux_core {
@@ -22,6 +23,12 @@ struct i2c_mux_core {
unsigned int arbitrator:1;
unsigned int gate:1;
+ /*
+ * The mux controller state to use when inactive, or one
+ * of MUX_IDLE_AS_IS and MUX_IDLE_DISCONNECT.
+ */
+ int idle_state;
+
void *priv;
int (*select)(struct i2c_mux_core *, u32 chan_id);
@@ -38,6 +45,20 @@ struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent,
int (*select)(struct i2c_mux_core *, u32),
int (*deselect)(struct i2c_mux_core *, u32));
+/*
+ * Mux drivers may only change idle_state, and may only do so
+ * between allocation and registration of the mux controller.
+ */
+static inline void i2c_mux_set_idle_state(struct i2c_mux_core *muxc, int state)
+{
+ muxc->idle_state = state;
+}
+
+static inline int i2c_mux_idle_state(struct i2c_mux_core *muxc)
+{
+ return muxc->idle_state;
+}
+
/* flags for i2c_mux_alloc */
#define I2C_MUX_LOCKED BIT(0)
#define I2C_MUX_ARBITRATOR BIT(1)
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC 3/7] i2c: mux: add support for per channel bus frequency
2025-09-22 6:20 [PATCH RFC 0/7] I2C Mux per channel bus speed Marcus Folkesson
2025-09-22 6:20 ` [PATCH RFC 1/7] i2c: core: add callback to change bus frequency Marcus Folkesson
2025-09-22 6:20 ` [PATCH RFC 2/7] i2c: mux: add idle_state property to i2c_mux_core Marcus Folkesson
@ 2025-09-22 6:20 ` Marcus Folkesson
2025-09-22 6:20 ` [PATCH RFC 4/7] i2c: mux: ltc4306: set correct idle_state in i2c_mux_core Marcus Folkesson
` (4 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Marcus Folkesson @ 2025-09-22 6:20 UTC (permalink / raw)
To: Wolfram Sang, Peter Rosin, Michael Hennerich, Bartosz Golaszewski,
Andi Shyti
Cc: linux-i2c, linux-kernel, linux-arm-kernel, Marcus Folkesson
There could be several reasons why you may need to use a certain speed
on an I2C bus. E.g.
- When several devices are attached to the bus, the speed must be
selected according to the slowest device.
- Electrical conditions may limit the usuable speed on the bus for
different reasons.
With an I2C multiplexer, it is possible to group the attached devices
after their preferred speed by e.g. put all "slow" devices on a separate
channel on the multiplexer.
Consider the following topology:
.----------. 100kHz .--------.
.--------. 400kHz | |--------| dev D1 |
| root |--+-----| I2C MUX | '--------'
'--------' | | |--. 400kHz .--------.
| '----------' '-------| dev D2 |
| .--------. '--------'
'--| dev D3 |
'--------'
One requirement with this design is that a multiplexer may only use the
same or lower bus speed as its parent.
Otherwise, if the multiplexer would have to increase the bus frequency,
then all siblings (D3 in this case) would run into a clock speed it may
not support.
The bus frequency for each channel is set in the devicetree. As the
i2c-mux bindings import the i2c-controller schema, the clock-frequency
property is already allowed.
If no clock-frequency property is set, the channel inherit their parent
bus speed.
The following example uses dt bindings to illustrate the topology above:
i2c {
clock-frequency = <400000>;
i2c-mux {
i2c@0 {
clock-frequency = <100000>;
D1 {
...
};
};
i2c@1 {
D2 {
...
};
};
};
D3 {
...
}
};
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
drivers/i2c/i2c-mux.c | 126 +++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 114 insertions(+), 12 deletions(-)
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 5caa927c0caae512af029f0d1ae9b7f845ba3f6f..22b404597ff91eddb965c48112fdc63250d71e43 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -36,6 +36,72 @@ struct i2c_mux_priv {
u32 chan_id;
};
+static int i2c_mux_select_chan(struct i2c_adapter *adap, u32 chan_id)
+{
+ struct i2c_mux_priv *priv = adap->algo_data;
+ struct i2c_mux_core *muxc = priv->muxc;
+ struct i2c_adapter *parent = muxc->parent;
+ struct i2c_adapter *root;
+ int ret;
+
+ if (priv->adap.clock_hz && priv->adap.clock_hz != parent->clock_hz) {
+ root = i2c_root_adapter(&adap->dev);
+
+ /* if we are parent-locked and the root adapter is our parent,
+ * we already have the lock we need. Otherwise take the bus lock for the root
+ * adaper before changing bus clock.
+ */
+ if ((root != parent && !muxc->mux_locked) || muxc->mux_locked)
+ i2c_lock_bus(parent, I2C_LOCK_ROOT_ADAPTER);
+
+ ret = i2c_adapter_set_clk_freq(root, priv->adap.clock_hz);
+
+ if ((root != parent && !muxc->mux_locked) || muxc->mux_locked)
+ i2c_unlock_bus(parent, I2C_LOCK_ROOT_ADAPTER);
+
+ if (ret < 0) {
+ dev_err(&adap->dev,
+ "Failed to set clock frequency %dHz on root adapter %s: %d\n",
+ priv->adap.clock_hz, root->name, ret);
+
+ return ret;
+ }
+ }
+
+ return muxc->select(muxc, priv->chan_id);
+}
+
+static void i2c_mux_deselect_chan(struct i2c_adapter *adap, u32 chan_id)
+{
+ struct i2c_mux_priv *priv = adap->algo_data;
+ struct i2c_mux_core *muxc = priv->muxc;
+ struct i2c_adapter *parent = muxc->parent;
+ struct i2c_adapter *root;
+ int ret;
+
+ if (parent->clock_hz && parent->clock_hz != priv->adap.clock_hz) {
+ root = i2c_root_adapter(&parent->dev);
+
+ /* if we are parent-locked and the root adapter is our parent,
+ * we already have the lock we need. Otherwise take the bus lock for the root
+ * adaper before changing bus clock.
+ */
+ if ((root != parent && !muxc->mux_locked) || muxc->mux_locked)
+ i2c_lock_bus(parent, I2C_LOCK_ROOT_ADAPTER);
+
+ ret = i2c_adapter_set_clk_freq(root, parent->clock_hz);
+
+ if ((root != parent && !muxc->mux_locked) || muxc->mux_locked)
+ i2c_unlock_bus(parent, I2C_LOCK_ROOT_ADAPTER);
+
+ if (ret < 0)
+ return;
+ }
+
+ if (muxc->deselect)
+ muxc->deselect(muxc, priv->chan_id);
+}
+
static int __i2c_mux_master_xfer(struct i2c_adapter *adap,
struct i2c_msg msgs[], int num)
{
@@ -46,11 +112,11 @@ static int __i2c_mux_master_xfer(struct i2c_adapter *adap,
/* Switch to the right mux port and perform the transfer. */
- ret = muxc->select(muxc, priv->chan_id);
+ ret = i2c_mux_select_chan(adap, priv->chan_id);
if (ret >= 0)
ret = __i2c_transfer(parent, msgs, num);
- if (muxc->deselect)
- muxc->deselect(muxc, priv->chan_id);
+
+ i2c_mux_deselect_chan(adap, priv->chan_id);
return ret;
}
@@ -65,11 +131,11 @@ static int i2c_mux_master_xfer(struct i2c_adapter *adap,
/* Switch to the right mux port and perform the transfer. */
- ret = muxc->select(muxc, priv->chan_id);
+ ret = i2c_mux_select_chan(adap, priv->chan_id);
if (ret >= 0)
ret = i2c_transfer(parent, msgs, num);
- if (muxc->deselect)
- muxc->deselect(muxc, priv->chan_id);
+
+ i2c_mux_deselect_chan(adap, priv->chan_id);
return ret;
}
@@ -86,12 +152,12 @@ static int __i2c_mux_smbus_xfer(struct i2c_adapter *adap,
/* Select the right mux port and perform the transfer. */
- ret = muxc->select(muxc, priv->chan_id);
+ ret = i2c_mux_select_chan(adap, priv->chan_id);
if (ret >= 0)
ret = __i2c_smbus_xfer(parent, addr, flags,
read_write, command, size, data);
- if (muxc->deselect)
- muxc->deselect(muxc, priv->chan_id);
+
+ i2c_mux_deselect_chan(adap, priv->chan_id);
return ret;
}
@@ -108,12 +174,12 @@ static int i2c_mux_smbus_xfer(struct i2c_adapter *adap,
/* Select the right mux port and perform the transfer. */
- ret = muxc->select(muxc, priv->chan_id);
+ ret = i2c_mux_select_chan(adap, priv->chan_id);
if (ret >= 0)
ret = i2c_smbus_xfer(parent, addr, flags,
read_write, command, size, data);
- if (muxc->deselect)
- muxc->deselect(muxc, priv->chan_id);
+
+ i2c_mux_deselect_chan(adap, priv->chan_id);
return ret;
}
@@ -366,6 +432,42 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
}
}
+ of_property_read_u32(child, "clock-frequency", &priv->adap.clock_hz);
+
+ /*
+ * Warn if the mux adapter does not disconnect channels or
+ * if a low-speed channel is seleced during idle.
+ */
+ if (priv->adap.clock_hz < parent->clock_hz)
+ if (muxc->idle_state != MUX_IDLE_DISCONNECT ||
+ muxc->idle_state == chan_id)
+ dev_warn(muxc->dev,
+ "channel %u has improper idle state for this configuration\n",
+ chan_id);
+
+ /*
+ * Warn if the mux adapter is not parent-locked as
+ * this may cause issues for some hardware topologies.
+ */
+ if ((priv->adap.clock_hz < parent->clock_hz) && muxc->mux_locked)
+ dev_warn(muxc->dev,
+ "channel %u is slower than parent on a non parent-locked mux\n",
+ chan_id);
+
+ /* If the mux adapter has no clock-frequency property, inherit from parent */
+ if (!priv->adap.clock_hz)
+ priv->adap.clock_hz = parent->clock_hz;
+
+ /* We don't support mux adapters faster than their parent */
+ if (priv->adap.clock_hz > parent->clock_hz) {
+ dev_err(muxc->dev,
+ "channel (%u) is faster than parent (%u)\n",
+ chan_id, priv->adap.clock_hz, parent->clock_hz);
+
+ of_node_put(mux_node);
+ goto err_free_priv;
+ }
+
priv->adap.dev.of_node = child;
of_node_put(mux_node);
}
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC 4/7] i2c: mux: ltc4306: set correct idle_state in i2c_mux_core
2025-09-22 6:20 [PATCH RFC 0/7] I2C Mux per channel bus speed Marcus Folkesson
` (2 preceding siblings ...)
2025-09-22 6:20 ` [PATCH RFC 3/7] i2c: mux: add support for per channel bus frequency Marcus Folkesson
@ 2025-09-22 6:20 ` Marcus Folkesson
2025-09-22 6:21 ` [PATCH RFC 5/7] i2c: davinci: calculate bus freq from Hz instead of kHz Marcus Folkesson
` (3 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Marcus Folkesson @ 2025-09-22 6:20 UTC (permalink / raw)
To: Wolfram Sang, Peter Rosin, Michael Hennerich, Bartosz Golaszewski,
Andi Shyti
Cc: linux-i2c, linux-kernel, linux-arm-kernel, Marcus Folkesson
Inform the core if we intend to disconnect channels during idle.
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
drivers/i2c/muxes/i2c-mux-ltc4306.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/i2c/muxes/i2c-mux-ltc4306.c b/drivers/i2c/muxes/i2c-mux-ltc4306.c
index 50fbc0d06e62b2743dd7f20c9863d56009dcf0e9..4e81002e2e4d6c63f13cf44e16581aff836f7d4f 100644
--- a/drivers/i2c/muxes/i2c-mux-ltc4306.c
+++ b/drivers/i2c/muxes/i2c-mux-ltc4306.c
@@ -232,6 +232,9 @@ static int ltc4306_probe(struct i2c_client *client)
data = i2c_mux_priv(muxc);
data->chip = chip;
+ if (idle_disc)
+ i2c_mux_set_idle_state(muxc, MUX_IDLE_DISCONNECT);
+
i2c_set_clientdata(client, muxc);
data->regmap = devm_regmap_init_i2c(client, <c4306_regmap_config);
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC 5/7] i2c: davinci: calculate bus freq from Hz instead of kHz
2025-09-22 6:20 [PATCH RFC 0/7] I2C Mux per channel bus speed Marcus Folkesson
` (3 preceding siblings ...)
2025-09-22 6:20 ` [PATCH RFC 4/7] i2c: mux: ltc4306: set correct idle_state in i2c_mux_core Marcus Folkesson
@ 2025-09-22 6:21 ` Marcus Folkesson
2025-09-22 14:42 ` Bartosz Golaszewski
2025-09-22 6:21 ` [PATCH RFC 6/7] i2c: davinci: add support for setting bus frequency Marcus Folkesson
` (2 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Marcus Folkesson @ 2025-09-22 6:21 UTC (permalink / raw)
To: Wolfram Sang, Peter Rosin, Michael Hennerich, Bartosz Golaszewski,
Andi Shyti
Cc: linux-i2c, linux-kernel, linux-arm-kernel, Marcus Folkesson
The bus frequency is unnecessarily converted between Hz and kHz in
several places.
This is probably an old legacy from the old times (pre-devicetrees)
when the davinci_i2c_platform_data took the bus_freq in kHz.
Stick to Hz.
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
drivers/i2c/busses/i2c-davinci.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 6a3d4e9e07f45ecc228943e877cde1fd9d72e8cb..6b18938457d0c5cabc323c364d9330c2890df107 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -117,8 +117,6 @@
/* timeout for pm runtime autosuspend */
#define DAVINCI_I2C_PM_TIMEOUT 1000 /* ms */
-#define DAVINCI_I2C_DEFAULT_BUS_FREQ 100
-
struct davinci_i2c_dev {
struct device *dev;
void __iomem *base;
@@ -209,16 +207,16 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
if (device_is_compatible(dev->dev, "ti,keystone-i2c"))
d = 6;
- clk = ((input_clock / (psc + 1)) / (dev->bus_freq * 1000));
+ clk = ((input_clock / (psc + 1)) / (dev->bus_freq));
/* Avoid driving the bus too fast because of rounding errors above */
- if (input_clock / (psc + 1) / clk > dev->bus_freq * 1000)
+ if (input_clock / (psc + 1) / clk > dev->bus_freq)
clk++;
/*
* According to I2C-BUS Spec 2.1, in FAST-MODE LOW period should be at
* least 1.3uS, which is not the case with 50% duty cycle. Driving HIGH
* to LOW ratio as 1 to 2 is more safe.
*/
- if (dev->bus_freq > 100)
+ if (dev->bus_freq > 100000)
clkl = (clk << 1) / 3;
else
clkl = (clk >> 1);
@@ -269,7 +267,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKL_REG));
dev_dbg(dev->dev, "CLKH = %d\n",
davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKH_REG));
- dev_dbg(dev->dev, "bus_freq = %dkHz\n", dev->bus_freq);
+ dev_dbg(dev->dev, "bus_freq = %dHz\n", dev->bus_freq);
/* Take the I2C module out of reset: */
@@ -761,9 +759,9 @@ static int davinci_i2c_probe(struct platform_device *pdev)
r = device_property_read_u32(&pdev->dev, "clock-frequency", &prop);
if (r)
- prop = DAVINCI_I2C_DEFAULT_BUS_FREQ;
+ prop = I2C_MAX_STANDARD_MODE_FREQ;
- dev->bus_freq = prop / 1000;
+ dev->bus_freq = prop;
dev->has_pfunc = device_property_present(&pdev->dev, "ti,has-pfunc");
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC 6/7] i2c: davinci: add support for setting bus frequency
2025-09-22 6:20 [PATCH RFC 0/7] I2C Mux per channel bus speed Marcus Folkesson
` (4 preceding siblings ...)
2025-09-22 6:21 ` [PATCH RFC 5/7] i2c: davinci: calculate bus freq from Hz instead of kHz Marcus Folkesson
@ 2025-09-22 6:21 ` Marcus Folkesson
2025-09-22 14:43 ` Bartosz Golaszewski
2025-09-22 6:21 ` [PATCH RFC 7/7] docs: i2c: i2c-topology: add section about bus speed Marcus Folkesson
2025-09-23 15:10 ` [PATCH RFC 0/7] I2C Mux per channel " Peter Rosin
7 siblings, 1 reply; 13+ messages in thread
From: Marcus Folkesson @ 2025-09-22 6:21 UTC (permalink / raw)
To: Wolfram Sang, Peter Rosin, Michael Hennerich, Bartosz Golaszewski,
Andi Shyti
Cc: linux-i2c, linux-kernel, linux-arm-kernel, Marcus Folkesson
Populate adapter with clock_hz and set_clk_freq to enable support for
dynamic bus frequency.
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
drivers/i2c/busses/i2c-davinci.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 6b18938457d0c5cabc323c364d9330c2890df107..d3e47738f8ee7e8f69fee49509dcda396c9b7fb6 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -279,6 +279,27 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
return 0;
}
+static int davinci_i2c_set_clk(struct i2c_adapter *adap, u32 clock_hz)
+{
+ struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
+
+ if (dev->bus_freq == clock_hz)
+ return 0;
+
+ dev->bus_freq = clock_hz;
+
+ /* put I2C into reset */
+ davinci_i2c_reset_ctrl(dev, 0);
+
+ /* compute clock dividers */
+ i2c_davinci_calc_clk_dividers(dev);
+
+ /* Take the I2C module out of reset: */
+ davinci_i2c_reset_ctrl(dev, 1);
+
+ return 0;
+}
+
/*
* This routine does i2c bus recovery by using i2c_generic_scl_recovery
* which is provided by I2C Bus recovery infrastructure.
@@ -810,6 +831,8 @@ static int davinci_i2c_probe(struct platform_device *pdev)
adap->dev.parent = &pdev->dev;
adap->timeout = DAVINCI_I2C_TIMEOUT;
adap->dev.of_node = dev_of_node(&pdev->dev);
+ adap->clock_hz = dev->bus_freq;
+ adap->set_clk_freq = davinci_i2c_set_clk;
if (dev->has_pfunc)
adap->bus_recovery_info = &davinci_i2c_scl_recovery_info;
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC 7/7] docs: i2c: i2c-topology: add section about bus speed
2025-09-22 6:20 [PATCH RFC 0/7] I2C Mux per channel bus speed Marcus Folkesson
` (5 preceding siblings ...)
2025-09-22 6:21 ` [PATCH RFC 6/7] i2c: davinci: add support for setting bus frequency Marcus Folkesson
@ 2025-09-22 6:21 ` Marcus Folkesson
2025-09-23 15:10 ` [PATCH RFC 0/7] I2C Mux per channel " Peter Rosin
7 siblings, 0 replies; 13+ messages in thread
From: Marcus Folkesson @ 2025-09-22 6:21 UTC (permalink / raw)
To: Wolfram Sang, Peter Rosin, Michael Hennerich, Bartosz Golaszewski,
Andi Shyti
Cc: linux-i2c, linux-kernel, linux-arm-kernel, Marcus Folkesson
Describe what needs to be consideraed and taken into account
when using different bus speeds for different mux channels.
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
Documentation/i2c/i2c-topology.rst | 176 +++++++++++++++++++++++++++++++++++++
1 file changed, 176 insertions(+)
diff --git a/Documentation/i2c/i2c-topology.rst b/Documentation/i2c/i2c-topology.rst
index 48fce0f7491bf1bcd4a851f685b010386c9ce0d2..362859b5de224272941576a9c82a04843e56f0d0 100644
--- a/Documentation/i2c/i2c-topology.rst
+++ b/Documentation/i2c/i2c-topology.rst
@@ -367,6 +367,182 @@ When D1 or D2 are accessed, accesses to D3 and D4 are locked out while
accesses to D5 may interleave. When D3 or D4 are accessed, accesses to
all other devices are locked out.
+Bus Speed and I2C Multiplexers
+================================
+
+I2C bus multiplexers allows multiple downstream channels to be exposed
+as separate I2C adapters which also could set their own bus speed.
+
+The multiplexer itself cannot change the bus speed as it use the upstream
+clock and data lines to communicate with the downstream devices. The speed
+is therfor changed in the root adapter resulting in that the whole bus is
+affected.
+
+This increases the complexity of the topology and some considerations must
+be taken into.
+
+Bus speed
+----------
+
+Downstream channels of an I2C multiplexer can only operate at the same or
+lower bus speed as the upstream bus. This is because the upstream bus may
+have devices that cannot operate at higher speeds and those will be affected
+by the speed change.
+
+The example below illustrates the problem.
+The root adapter is operating at 100kHz. D2 can only operate with 100kHz,
+but D2 can operate at 400kHz. When D1 is selected, the bus speed of the
+root adapter would have to be is set to 400kHz, a speed that D2 cannot support.
+
+This topology is therefor not allowed: ::
+
+ .----------. 400kHz .--------.
+ .--------. 100kHz | mux- |--------| dev D1 |
+ | root |--+-----| locked | '--------'
+ '--------' | | mux M1 |
+ | '----------'
+ | .--------.
+ '--| dev D2 |
+ '--------'
+
+
+This topology is allowed: ::
+
+ .----------. 100kHz .--------.
+ .--------. 400kHz | mux- |--------| dev D2 |
+ | root |--+-----| locked | '--------'
+ '--------' | mux M1 |--. 400kHz .--------.
+ '----------' '--------| dev D1 |
+ '--------'
+
+Preferred topology
+-------------------
+
+The preferred topology when using different bus speeds is to have the multiplexer
+connected directly to the root adapter without any devices as siblings.
+By this arrangement, the bus speed can be changed without affecting any other devices
+and many of the caveats are avoided.
+
+Other multiplexers in parallell is still okay as those are locked out during transfers.
+
+This is the preferred topology: ::
+
+ .----------. 100kHz .--------.
+ .--------. 400kHz | mux- |--------| dev D2 |
+ | root |--+-----| locked | '--------'
+ '--------' | mux M1 |--. 400kHz .--------.
+ '----------' '--------| dev D1 |
+ '--------'
+Locking
+--------
+
+If the multiplexer is mux-locked, transfers to D3 may interleave between the
+select-transfer-deselect to D1 or D2.
+This results in a situation where the bus speed to D3 may be lower than it
+can handle. This is usually not a problem.
+
+This topology is allowed but some transfers to D3 may be at 100kHz: ::
+
+ .----------. 100kHz .--------.
+ .--------. 400kHz | mux- |--------| dev D1 |
+ | root |--+-----| locked | '--------'
+ '--------' | | mux M1 |--. 400kHz .--------.
+ | '----------' '--------| dev D2 |
+ | .--------. '--------'
+ '--| dev D3 |
+ '--------'
+
+Multiple muxes in series
+--------------------------
+
+When multiple muxes are used in series the same rules applies.
+
+Transfers to D3 may interleave between select-transfer-deselect to D1, which
+results that the bus speed to D2 or D3 will be at 100KHz.
+
+Transfers to D2 may interleave between select-transfer-deselect to D1, which
+results in that the bus speed to D1 may be at 400kHz as the transfer to D2
+will set the bus speed to before the transfer to D1 starts.
+
+This is probably a bad topology ::
+
+ .----------. 400kHz .----------. 100kHz .--------.
+ .--------.400kHz | mux- |--------| mux- |--------| dev D1 |
+ | root |--+----| locked | 400kHz | locked | '--------'
+ '--------' | | mux M1 |--. | mux M2 |
+ | '----------' | '----------'
+ | .--------. | .--------.
+ '--| dev D3 | '--| dev D2 |
+ '--------' '--------'
+
+Multiple muxes in parallell
+----------------------------
+
+When multiple muxes are used in parallell all access to other muxes are locked out
+so this is not a problem.
+
+If the muxes are mux-locked, access to D3 may still interleave though.
+
+In the example below, D3 may not interleave between select-transfer-deselect for D1
+or D2 as both muxes are parent-locked: ::
+
+
+ .----------. 100kHz .--------.
+ | parent- |----------| dev D1 |
+ .--| locked | '--------'
+ | | mux M1 |
+ | '----------'
+ | .----------. 400KHz .--------.
+ .--------. 400kHz | parent- |---------| dev D2 |
+ | root |--+------| locked | '--------'
+ '--------' | | mux M2 |
+ | '----------'
+ | .--------.
+ '--| dev D3 |
+ '--------'
+
+Idle state
+-----------
+
+Muxes have an idle state, which is the state the channels is put into when no channel
+is active. The state is typically one of the following:
+
+- All channels are disconnected
+- The last selected channel is left as-is
+- A predefined channel is selected
+
+Muxes that support an idle state where all channels are disconnected are preferred when using
+different bus speeds. Otherwise high bus speeds may "leak" through to devices that
+may not support that higher speed.
+
+Consider the following example: ::
+
+ .----------. 100kHz .--------.
+ .--------. 400kHz | mux- |--------| dev D1 |
+ | root |--+-----| locked | '--------'
+ '--------' | | mux M1 |--. 400kHz .--------.
+ | '----------' '--------| dev D2 |
+ | .--------. '--------'
+ '--| dev D3 |
+ '--------'
+
+If the idle state of M1 is:
+- All channels disconnected: No problem, D1 and D2 are not affected by communication
+ to D3.
+- Last selected channel: Problem if D1 was the last selected channel. High speed
+ communication to D3 will be "leaked" to D1.
+- Predefined channel: Problem, if the predefined channel D1. Set predefined channel
+ to D2 as D2 may handle 400kHz.
+
+Supported controllers
+-----------------------
+
+Not all I2C controllers support setting the bus speed dynamically.
+At the time of writint, the following controllers has support:
+
+============================ =============================================
+i2c-davinci Supports dynamic bus speed
+============================ =============================================
Mux type of existing device drivers
===================================
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH RFC 5/7] i2c: davinci: calculate bus freq from Hz instead of kHz
2025-09-22 6:21 ` [PATCH RFC 5/7] i2c: davinci: calculate bus freq from Hz instead of kHz Marcus Folkesson
@ 2025-09-22 14:42 ` Bartosz Golaszewski
2025-09-22 14:50 ` Marcus Folkesson
0 siblings, 1 reply; 13+ messages in thread
From: Bartosz Golaszewski @ 2025-09-22 14:42 UTC (permalink / raw)
To: Marcus Folkesson
Cc: Wolfram Sang, Peter Rosin, Michael Hennerich, Bartosz Golaszewski,
Andi Shyti, linux-i2c, linux-kernel, linux-arm-kernel
On Mon, 22 Sep 2025 08:21:00 +0200, Marcus Folkesson
<marcus.folkesson@gmail.com> said:
> The bus frequency is unnecessarily converted between Hz and kHz in
> several places.
> This is probably an old legacy from the old times (pre-devicetrees)
> when the davinci_i2c_platform_data took the bus_freq in kHz.
>
> Stick to Hz.
>
This looks good but would you mind also changing the name of the field to
bus_freq_hz in order to leave zero change of misinterpreting it in the future?
Bartosz
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RFC 6/7] i2c: davinci: add support for setting bus frequency
2025-09-22 6:21 ` [PATCH RFC 6/7] i2c: davinci: add support for setting bus frequency Marcus Folkesson
@ 2025-09-22 14:43 ` Bartosz Golaszewski
0 siblings, 0 replies; 13+ messages in thread
From: Bartosz Golaszewski @ 2025-09-22 14:43 UTC (permalink / raw)
To: Marcus Folkesson
Cc: linux-i2c, linux-kernel, linux-arm-kernel, Wolfram Sang,
Peter Rosin, Michael Hennerich, Bartosz Golaszewski, Andi Shyti
On Mon, 22 Sep 2025 08:21:01 +0200, Marcus Folkesson
<marcus.folkesson@gmail.com> said:
> Populate adapter with clock_hz and set_clk_freq to enable support for
> dynamic bus frequency.
>
> Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
> ---
> drivers/i2c/busses/i2c-davinci.c | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
> diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
> index 6b18938457d0c5cabc323c364d9330c2890df107..d3e47738f8ee7e8f69fee49509dcda396c9b7fb6 100644
> --- a/drivers/i2c/busses/i2c-davinci.c
> +++ b/drivers/i2c/busses/i2c-davinci.c
> @@ -279,6 +279,27 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
> return 0;
> }
>
> +static int davinci_i2c_set_clk(struct i2c_adapter *adap, u32 clock_hz)
> +{
> + struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
> +
> + if (dev->bus_freq == clock_hz)
> + return 0;
> +
> + dev->bus_freq = clock_hz;
> +
> + /* put I2C into reset */
> + davinci_i2c_reset_ctrl(dev, 0);
> +
> + /* compute clock dividers */
> + i2c_davinci_calc_clk_dividers(dev);
> +
> + /* Take the I2C module out of reset: */
> + davinci_i2c_reset_ctrl(dev, 1);
> +
> + return 0;
> +}
> +
> /*
> * This routine does i2c bus recovery by using i2c_generic_scl_recovery
> * which is provided by I2C Bus recovery infrastructure.
> @@ -810,6 +831,8 @@ static int davinci_i2c_probe(struct platform_device *pdev)
> adap->dev.parent = &pdev->dev;
> adap->timeout = DAVINCI_I2C_TIMEOUT;
> adap->dev.of_node = dev_of_node(&pdev->dev);
> + adap->clock_hz = dev->bus_freq;
> + adap->set_clk_freq = davinci_i2c_set_clk;
>
> if (dev->has_pfunc)
> adap->bus_recovery_info = &davinci_i2c_scl_recovery_info;
>
> --
> 2.50.1
>
>
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RFC 5/7] i2c: davinci: calculate bus freq from Hz instead of kHz
2025-09-22 14:42 ` Bartosz Golaszewski
@ 2025-09-22 14:50 ` Marcus Folkesson
0 siblings, 0 replies; 13+ messages in thread
From: Marcus Folkesson @ 2025-09-22 14:50 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Wolfram Sang, Peter Rosin, Michael Hennerich, Andi Shyti,
linux-i2c, linux-kernel, linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 742 bytes --]
Hi Bartosz,
On Mon, Sep 22, 2025 at 07:42:43AM -0700, Bartosz Golaszewski wrote:
> On Mon, 22 Sep 2025 08:21:00 +0200, Marcus Folkesson
> <marcus.folkesson@gmail.com> said:
> > The bus frequency is unnecessarily converted between Hz and kHz in
> > several places.
> > This is probably an old legacy from the old times (pre-devicetrees)
> > when the davinci_i2c_platform_data took the bus_freq in kHz.
> >
> > Stick to Hz.
> >
>
> This looks good but would you mind also changing the name of the field to
> bus_freq_hz in order to leave zero change of misinterpreting it in the future?
Thanks for your review!
Sounds fair, I will change the name to bus_freq_hz in v2.
>
> Bartosz
Best regards,
Marcus Folkesson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RFC 0/7] I2C Mux per channel bus speed
2025-09-22 6:20 [PATCH RFC 0/7] I2C Mux per channel bus speed Marcus Folkesson
` (6 preceding siblings ...)
2025-09-22 6:21 ` [PATCH RFC 7/7] docs: i2c: i2c-topology: add section about bus speed Marcus Folkesson
@ 2025-09-23 15:10 ` Peter Rosin
2025-09-23 20:37 ` Marcus Folkesson
7 siblings, 1 reply; 13+ messages in thread
From: Peter Rosin @ 2025-09-23 15:10 UTC (permalink / raw)
To: Marcus Folkesson, Wolfram Sang, Michael Hennerich,
Bartosz Golaszewski, Andi Shyti
Cc: linux-i2c, linux-kernel, linux-arm-kernel
Hi!
2025-09-22 at 08:20, Marcus Folkesson wrote:
> This is an RFC on how to implement a feature to have different bus
> speeds on different channels with an I2C multiplexer/switch.
>
> The benefit with this approach is that you may group devices after
> the fastest bus speed they can handle.
> A real-world example is that you could have e.g. a display running @400kHz
> and a smart battery running @100kHz using the same I2C controller.
>
> There are many corner cases where this may cause a problem for some
> hardware topologies. I've tried to describe those I could think of
> in the documentation, see Patch #7.
>
> E.g. one risk is that if the mux driver does not disconnect channels
> when Idle, this may cause a higher frequency to "leak" through to
> devices that are supposed to run at lower bus speed.
> This is not only a "problem" for changing bus speed but could also be
> an issue for potential address conflicts.
>
> The implementation is split up into several patches:
>
> Patch #1 Introduce a callback for the i2c controller to set bus speed
> Patch #2 Introduce idle state to the mux core.
> Patch #3 Introduce functionality to adjust bus speed depending on mux
> channel.
> Patch #4 Set idle state for an example mux driver
> Patch #5 Cleanup i2c-davinci driver a bit to prepare it for set_clk_freq
> Parch #6 Implement set_clk_freq for the i2c-davinci driver
> Parch #7 Update documentation with this feature
It seems excessive to add idle_state to struct i2c_mux_core for the sole
purpose of providing a warning in case the idle state runs on lower speed.
Especially so since the default idle behavior is so dependent on the mux.
E.g. the idle state is completely opaque to the driver of the pinctrl mux.
It simply has no way of knowing what the idle pinctrl state actually means,
and can therefore not report back a valid idle state to the i2c-mux core.
The general purpose mux is also problematic. There is currently no API
for the gpmux to dig out the idle state from the mux subsystem. That
can be fixed, of course, but the mux susbsystem might also grow a way
to change the idle state at runtime. Or some other consumer of the "mux
control" used by the I2C gpmux might set it to a new state without the
I2C gpmux having a chance to prevent it (or even know about it).
You can have a gpio mux that only muxes SDA while SCL is always forwarded
to all children. That might not be healthy for devices not expecting
overly high frequencies on the SCL pin. It's probably safe, but who knows?
The above are examples that make the warning inexact.
I'd prefer to just kill this idle state hand-holding from the code and
rely on documentation of the rules instead. Whoever sets this up must
understand I2C anyway; there are plenty of foot guns, so avoiding this
particular one (in a half-baked way) is no big help, methinks.
This has the added benefit of not muddying the waters for the idle state
defines owned by the mux subsystem.
Cheers,
Peter
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RFC 0/7] I2C Mux per channel bus speed
2025-09-23 15:10 ` [PATCH RFC 0/7] I2C Mux per channel " Peter Rosin
@ 2025-09-23 20:37 ` Marcus Folkesson
0 siblings, 0 replies; 13+ messages in thread
From: Marcus Folkesson @ 2025-09-23 20:37 UTC (permalink / raw)
To: Peter Rosin
Cc: Wolfram Sang, Michael Hennerich, Bartosz Golaszewski, Andi Shyti,
linux-i2c, linux-kernel, linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 2763 bytes --]
Hi Peter,
Thanks for your input!
On Tue, Sep 23, 2025 at 05:10:16PM +0200, Peter Rosin wrote:
> Hi!
>
> 2025-09-22 at 08:20, Marcus Folkesson wrote:
> > This is an RFC on how to implement a feature to have different bus
> > speeds on different channels with an I2C multiplexer/switch.
> >
[...]
> > Patch #1 Introduce a callback for the i2c controller to set bus speed
> > Patch #2 Introduce idle state to the mux core.
> > Patch #3 Introduce functionality to adjust bus speed depending on mux
> > channel.
> > Patch #4 Set idle state for an example mux driver
> > Patch #5 Cleanup i2c-davinci driver a bit to prepare it for set_clk_freq
> > Parch #6 Implement set_clk_freq for the i2c-davinci driver
> > Parch #7 Update documentation with this feature
> It seems excessive to add idle_state to struct i2c_mux_core for the sole
> purpose of providing a warning in case the idle state runs on lower speed.
> Especially so since the default idle behavior is so dependent on the mux.
>
> E.g. the idle state is completely opaque to the driver of the pinctrl mux.
> It simply has no way of knowing what the idle pinctrl state actually means,
> and can therefore not report back a valid idle state to the i2c-mux core.
>
> The general purpose mux is also problematic. There is currently no API
> for the gpmux to dig out the idle state from the mux subsystem. That
> can be fixed, of course, but the mux susbsystem might also grow a way
> to change the idle state at runtime. Or some other consumer of the "mux
> control" used by the I2C gpmux might set it to a new state without the
> I2C gpmux having a chance to prevent it (or even know about it).
>
> You can have a gpio mux that only muxes SDA while SCL is always forwarded
> to all children. That might not be healthy for devices not expecting
> overly high frequencies on the SCL pin. It's probably safe, but who knows?
>
> The above are examples that make the warning inexact.
>
> I'd prefer to just kill this idle state hand-holding from the code and
> rely on documentation of the rules instead. Whoever sets this up must
> understand I2C anyway; there are plenty of foot guns, so avoiding this
> particular one (in a half-baked way) is no big help, methinks.
>
> This has the added benefit of not muddying the waters for the idle state
> defines owned by the mux subsystem.
I pretty much buy everything you say here.
I later saw that, as you pointed out, e.g. pca954x let you set the idle
state at runtime which would have increased the complexity a bit.
So, I think it is better to do as you suggest; remove idle_state and
keep the rules in the documentation.
>
> Cheers,
> Peter
Best regards,
Marcus Folkesson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-09-23 20:37 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-22 6:20 [PATCH RFC 0/7] I2C Mux per channel bus speed Marcus Folkesson
2025-09-22 6:20 ` [PATCH RFC 1/7] i2c: core: add callback to change bus frequency Marcus Folkesson
2025-09-22 6:20 ` [PATCH RFC 2/7] i2c: mux: add idle_state property to i2c_mux_core Marcus Folkesson
2025-09-22 6:20 ` [PATCH RFC 3/7] i2c: mux: add support for per channel bus frequency Marcus Folkesson
2025-09-22 6:20 ` [PATCH RFC 4/7] i2c: mux: ltc4306: set correct idle_state in i2c_mux_core Marcus Folkesson
2025-09-22 6:21 ` [PATCH RFC 5/7] i2c: davinci: calculate bus freq from Hz instead of kHz Marcus Folkesson
2025-09-22 14:42 ` Bartosz Golaszewski
2025-09-22 14:50 ` Marcus Folkesson
2025-09-22 6:21 ` [PATCH RFC 6/7] i2c: davinci: add support for setting bus frequency Marcus Folkesson
2025-09-22 14:43 ` Bartosz Golaszewski
2025-09-22 6:21 ` [PATCH RFC 7/7] docs: i2c: i2c-topology: add section about bus speed Marcus Folkesson
2025-09-23 15:10 ` [PATCH RFC 0/7] I2C Mux per channel " Peter Rosin
2025-09-23 20:37 ` Marcus Folkesson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).