[U-Boot] [PATCH 4/4] i2c: mux: Add support for not listed sub-buses

Michal Simek monstr at monstr.eu
Thu Jan 24 08:27:56 UTC 2019


Hi Heiko,

On 18. 01. 19 16:13, Michal Simek 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(-)
> 
> 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);
>  		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;
> +
> +		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,
> 

Can you please take a look at this series?

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190124/0260e2a4/attachment.sig>


More information about the U-Boot mailing list