Re: [PATCH v9 2/5] i2c: mux: add support for per channel bus frequency

Andy Shevchenko
2026-03-24T14:10:47Z

On Tue, Mar 24, 2026 at 02:54:16PM +0100, Marcus Folkesson wrote:
> There may 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 usable 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. putting 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 inherits their parent
> bus speed.

...

> + of_property_read_u32(child, "clock-frequency", &priv->adap.clock_hz);

Wondering if we may use existing API to get i2c timings from fw description?
i2c_parse_fw_timings() (it might be that it needs to be split for pure fwnode
one and device wrapped).

> +
> + /* If the mux adapter has no clock-frequency property, inherit from parent */
> + if (!priv->adap.clock_hz)
> + priv->adap.clock_hz = parent->clock_hz;
> +
> + /*
> + * 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);
> +
> + /* 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 (%u) than parent (%u)\n",
> + chan_id, priv->adap.clock_hz, parent->clock_hz);
> +
> + of_node_put(mux_node);
> + ret = -EINVAL;
> + goto err_free_priv;
> + }

--
With Best Regards,
Andy Shevchenko