[U-Boot] [PATCH 4/4] i2c: mux: Add support for not listed sub-buses
Simon Glass
sjg at chromium.org
Thu Jan 31 10:04:18 UTC 2019
Hi Michal,
On Fri, 18 Jan 2019 at 08:13, Michal Simek <michal.simek at xilinx.com> wrote:
>
> Before this patch is applied all i2c sub-buses are using number -1 and
> they can't be addresses(switch to). If all busses are listed in DT alias
> they will get proper numbers and U-Boot can work with them.
> In Linux buses which are not listed in DT alias get uniq number which
> starts from the first highest free ID.
>
> This is the behavior on ZynqMP zcu100-revA before this patch is applied.
>
> Bus 0: i2c at ff020000
> 20: gpio at 20, offset len 1, flags 0
> 21: gpio at 21, offset len 1, flags 0
> 75: i2c-mux at 75, offset len 1, flags 0
> Bus -1: i2c at 0
> Bus -1: i2c at 1
> Bus -1: i2c at 2
> Bus 1: i2c at ff030000
> 74: i2c-mux at 74, offset len 1, flags 0
> 75: i2c-mux at 75, offset len 1, flags 0
> Bus -1: i2c at 0
> Bus -1: i2c at 1
> Bus -1: i2c at 2
> Bus -1: i2c at 3
> Bus -1: i2c at 4
> Bus -1: i2c at 0
> Bus -1: i2c at 1
> Bus -1: i2c at 2
> Bus -1: i2c at 3
> Bus -1: i2c at 4
> Bus -1: i2c at 5
> Bus -1: i2c at 6
> Bus -1: i2c at 7
>
> When the patch is applied also i2c-mux busses are listed properly.
>
> ZynqMP> i2c bus
> Bus 0: i2c at ff020000
> 20: gpio at 20, offset len 1, flags 0
> 21: gpio at 21, offset len 1, flags 0
> 75: i2c-mux at 75, offset len 1, flags 0
> Bus 2: i2c at ff020000->i2c-mux at 75->i2c at 0
> Bus 3: i2c at ff020000->i2c-mux at 75->i2c at 1
> Bus 4: i2c at ff020000->i2c-mux at 75->i2c at 2
> Bus 1: i2c at ff030000 (active 1)
> 74: i2c-mux at 74, offset len 1, flags 0
> 75: i2c-mux at 75, offset len 1, flags 0
> Bus 5: i2c at ff030000->i2c-mux at 74->i2c at 0 (active 5)
> 54: generic_54, offset len 1, flags 0
> Bus 6: i2c at ff030000->i2c-mux at 74->i2c at 1
> Bus 7: i2c at ff030000->i2c-mux at 74->i2c at 2
> Bus 8: i2c at ff030000->i2c-mux at 74->i2c at 3
> Bus 9: i2c at ff030000->i2c-mux at 74->i2c at 4
> Bus 10: i2c at ff030000->i2c-mux at 75->i2c at 0
> Bus 11: i2c at ff030000->i2c-mux at 75->i2c at 1
> Bus 12: i2c at ff030000->i2c-mux at 75->i2c at 2
> Bus 13: i2c at ff030000->i2c-mux at 75->i2c at 3
> Bus 14: i2c at ff030000->i2c-mux at 75->i2c at 4
> Bus 15: i2c at ff030000->i2c-mux at 75->i2c at 5
> Bus 16: i2c at ff030000->i2c-mux at 75->i2c at 6
> Bus 17: i2c at ff030000->i2c-mux at 75->i2c at 7
>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
>
> zcu102-revA
>
> Before this patch applied for !DM case with static description
> ZynqMP> i2c bus
> Bus 0: zynq_0
> Bus 1: zynq_0->PCA9544A at 0x75:0
> Bus 2: zynq_0->PCA9544A at 0x75:1
> Bus 3: zynq_0->PCA9544A at 0x75:2
> Bus 4: zynq_1
> Bus 5: zynq_1->PCA9548 at 0x74:0
> Bus 6: zynq_1->PCA9548 at 0x74:1
> Bus 7: zynq_1->PCA9548 at 0x74:2
> Bus 8: zynq_1->PCA9548 at 0x74:3
> Bus 9: zynq_1->PCA9548 at 0x74:4
> Bus 10: zynq_1->PCA9548 at 0x75:0
> Bus 11: zynq_1->PCA9548 at 0x75:1
> Bus 12: zynq_1->PCA9548 at 0x75:2
> Bus 13: zynq_1->PCA9548 at 0x75:3
> Bus 14: zynq_1->PCA9548 at 0x75:4
> Bus 15: zynq_1->PCA9548 at 0x75:5
> Bus 16: zynq_1->PCA9548 at 0x75:6
> Bus 17: zynq_1->PCA9548 at 0x75:7
>
> When Patch is applied with OF_LIVE - of_alias_get_highest_id() is used
> ZynqMP> i2c bus
> Bus 0: i2c at ff020000
> 75: i2c-mux at 75, offset len 1, flags 0
> Bus 2: i2c at ff020000->i2c-mux at 75->i2c at 0
> Bus 3: i2c at ff020000->i2c-mux at 75->i2c at 1
> Bus 4: i2c at ff020000->i2c-mux at 75->i2c at 2
> Bus 1: i2c at ff030000
> 74: i2c-mux at 74, offset len 1, flags 0
> 75: i2c-mux at 75, offset len 1, flags 0
> Bus 5: i2c at ff030000->i2c-mux at 74->i2c at 0
> Bus 6: i2c at ff030000->i2c-mux at 74->i2c at 1
> Bus 7: i2c at ff030000->i2c-mux at 74->i2c at 2
> Bus 8: i2c at ff030000->i2c-mux at 74->i2c at 3
> Bus 9: i2c at ff030000->i2c-mux at 74->i2c at 4
> Bus 10: i2c at ff030000->i2c-mux at 75->i2c at 0
> Bus 11: i2c at ff030000->i2c-mux at 75->i2c at 1
> Bus 12: i2c at ff030000->i2c-mux at 75->i2c at 2
> Bus 13: i2c at ff030000->i2c-mux at 75->i2c at 3
> Bus 14: i2c at ff030000->i2c-mux at 75->i2c at 4
> Bus 15: i2c at ff030000->i2c-mux at 75->i2c at 5
> Bus 16: i2c at ff030000->i2c-mux at 75->i2c at 6
> Bus 17: i2c at ff030000->i2c-mux at 75->i2c at 7
>
> For !OF_LIVE - hardcoded number is used
> ZynqMP> i2c bus
> Bus 0: i2c at ff020000
> 75: i2c-mux at 75, offset len 1, flags 0
> Bus 21: i2c at ff020000->i2c-mux at 75->i2c at 0
> Bus 22: i2c at ff020000->i2c-mux at 75->i2c at 1
> Bus 23: i2c at ff020000->i2c-mux at 75->i2c at 2
> Bus 1: i2c at ff030000
> 74: i2c-mux at 74, offset len 1, flags 0
> 75: i2c-mux at 75, offset len 1, flags 0
> Bus 24: i2c at ff030000->i2c-mux at 74->i2c at 0
> Bus 25: i2c at ff030000->i2c-mux at 74->i2c at 1
> Bus 26: i2c at ff030000->i2c-mux at 74->i2c at 2
> Bus 27: i2c at ff030000->i2c-mux at 74->i2c at 3
> Bus 28: i2c at ff030000->i2c-mux at 74->i2c at 4
> Bus 29: i2c at ff030000->i2c-mux at 75->i2c at 0
> Bus 30: i2c at ff030000->i2c-mux at 75->i2c at 1
> Bus 31: i2c at ff030000->i2c-mux at 75->i2c at 2
> Bus 32: i2c at ff030000->i2c-mux at 75->i2c at 3
> Bus 33: i2c at ff030000->i2c-mux at 75->i2c at 4
> Bus 34: i2c at ff030000->i2c-mux at 75->i2c at 5
> Bus 35: i2c at ff030000->i2c-mux at 75->i2c at 6
> Bus 36: i2c at ff030000->i2c-mux at 75->i2c at 7
>
> ---
> drivers/i2c/muxes/i2c-mux-uclass.c | 35 +++++++++++++++++++++++++++++++++--
> 1 file changed, 33 insertions(+), 2 deletions(-)
This is quite a complicated issue...
>
> diff --git a/drivers/i2c/muxes/i2c-mux-uclass.c b/drivers/i2c/muxes/i2c-mux-uclass.c
> index a680ee176253..cb69d053fd59 100644
> --- a/drivers/i2c/muxes/i2c-mux-uclass.c
> +++ b/drivers/i2c/muxes/i2c-mux-uclass.c
> @@ -9,6 +9,7 @@
> #include <errno.h>
> #include <i2c.h>
> #include <dm/lists.h>
> +#include <dm/of_access.h>
> #include <dm/root.h>
>
> /**
> @@ -59,13 +60,42 @@ static int i2c_mux_post_bind(struct udevice *mux)
> dev_for_each_subnode(node, mux) {
> struct udevice *dev;
> const char *name;
> + const char *arrow = "->";
> + char *full_name;
> + int parent_name_len, arrow_len, mux_name_len, name_len;
>
> name = ofnode_get_name(node);
> - ret = device_bind_driver_to_node(mux, "i2c_mux_bus_drv", name,
> - node, &dev);
> +
> + /* Calculate lenghts of strings */
> + parent_name_len = strlen(mux->parent->name);
> + arrow_len = strlen(arrow);
> + mux_name_len = strlen(mux->name);
> + name_len = strlen(name);
> +
> + full_name = calloc(1, parent_name_len + arrow_len +
> + mux_name_len + arrow_len + name_len + 1);
> + if (!full_name)
> + return -ENOMEM;
> +
> + /* Compose bus name */
> + strcat(full_name, mux->parent->name);
> + strcat(full_name, arrow);
> + strcat(full_name, mux->name);
> + strcat(full_name, arrow);
> + strcat(full_name, name);
> +
> + ret = device_bind_driver_to_node(mux, "i2c_mux_bus_drv",
> + full_name, node, &dev);
Why do we use the full name here? We can create this by looking at the
parents if needed.
> debug(" - bind ret=%d, %s\n", ret, dev ? dev->name : NULL);
> if (ret)
> return ret;
> +
> + /* If dt alias is not found start to allocate new IDs */
> + if (dev->req_seq == -1)
> + dev->req_seq = ++i2c_highest_id;
As in the other patch, if we change this, I think we should do it in
DM core, by adjusting uclass_resolve_seq(). Would that work?
> +
> + debug("%s: MUX bus %d: %s\n", __func__, dev->req_seq,
> + full_name);
> }
>
> return 0;
> @@ -192,6 +222,7 @@ U_BOOT_DRIVER(i2c_mux_bus) = {
>
> UCLASS_DRIVER(i2c_mux) = {
> .id = UCLASS_I2C_MUX,
> + .flags = DM_UC_FLAG_SEQ_ALIAS,
> .name = "i2c_mux",
> .post_bind = i2c_mux_post_bind,
> .post_probe = i2c_mux_post_probe,
> --
> 1.9.1
>
Also we have no i2c mux tests by the look of it, and should add a test
to make sure this works on sandbox.
Regards,
Simon
More information about the U-Boot
mailing list