
On 18. 01. 19 16:13, Michal Simek wrote:
U-Boot with I2C_DM enabled is not capable to list i2c busses connected to i2c mux. For getting this work there is a need to find out highest alias ID and use this uniq number for new buses connected to I2C mux. This series is making this happen.
There is only one missing piece which is that also i2c controllers which are not listed in DT are not using this feature. For getting this work it would be necessary to setup dev->req_seq in pre_bind function.
int i2c_pre_bind(struct udevice *dev) { if (dev->req_seq == -1) { dev->req_seq = ++i2c_highest_id; } return 0; }
It can be done also in post_bind but it looks quite weird that controller has highest ID then i2c-mux sub-buses connected to it. For example: ZynqMP> i2c bus Bus 3: i2c@ff020000 20: gpio@20, offset len 1, flags 0 21: gpio@21, offset len 1, flags 0 75: i2c-mux@75, offset len 1, flags 0 Bus 0: i2c@ff020000->i2c-mux@75->i2c@0 Bus 1: i2c@ff020000->i2c-mux@75->i2c@1 Bus 2: i2c@ff020000->i2c-mux@75->i2c@2 Bus 17: i2c@ff030000 74: i2c-mux@74, offset len 1, flags 0 75: i2c-mux@75, offset len 1, flags 0 Bus 4: i2c@ff030000->i2c-mux@74->i2c@0 Bus 5: i2c@ff030000->i2c-mux@74->i2c@1 Bus 6: i2c@ff030000->i2c-mux@74->i2c@2 Bus 7: i2c@ff030000->i2c-mux@74->i2c@3 ...
That's why I think it would be better to introduce pre_bind hooks and call it in device_bind_common() before binding childs.
I have retested again and this is working properly.
This is the patch.
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index aaece115f02f..8430a23eece7 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -637,14 +637,28 @@ int i2c_uclass_init(struct uclass *class) return 0; }
+static int i2c_post_bind(struct udevice *dev) +{ + int ret = 0; + + debug("%s %d\n", __func__, dev->req_seq); + + if (dev->req_seq == -1) + dev->req_seq = ++i2c_highest_id; + +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) + ret = dm_scan_fdt_dev(dev); +#endif + + return ret; +} + UCLASS_DRIVER(i2c) = { .id = UCLASS_I2C, .name = "i2c", .flags = DM_UC_FLAG_SEQ_ALIAS, .init = i2c_uclass_init, -#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) - .post_bind = dm_scan_fdt_dev, -#endif + .post_bind = i2c_post_bind, .post_probe = i2c_post_probe, .per_device_auto_alloc_size = sizeof(struct dm_i2c_bus), .per_child_platdata_auto_alloc_size = sizeof(struct dm_i2c_chip),
And this is the output ZynqMP> i2c bus Bus 0: i2c@ff020000 20: gpio@20, offset len 1, flags 0 21: gpio@21, offset len 1, flags 0 75: i2c-mux@75, offset len 1, flags 0 Bus 1: i2c@ff020000->i2c-mux@75->i2c@0 Bus 2: i2c@ff020000->i2c-mux@75->i2c@1 Bus 3: i2c@ff020000->i2c-mux@75->i2c@2 Bus 4: i2c@ff030000 74: i2c-mux@74, offset len 1, flags 0 75: i2c-mux@75, offset len 1, flags 0 Bus 5: i2c@ff030000->i2c-mux@74->i2c@0 Bus 6: i2c@ff030000->i2c-mux@74->i2c@1 Bus 7: i2c@ff030000->i2c-mux@74->i2c@2 Bus 8: i2c@ff030000->i2c-mux@74->i2c@3 Bus 9: i2c@ff030000->i2c-mux@74->i2c@4 Bus 10: i2c@ff030000->i2c-mux@75->i2c@0 Bus 11: i2c@ff030000->i2c-mux@75->i2c@1 Bus 12: i2c@ff030000->i2c-mux@75->i2c@2 Bus 13: i2c@ff030000->i2c-mux@75->i2c@3 Bus 14: i2c@ff030000->i2c-mux@75->i2c@4 Bus 15: i2c@ff030000->i2c-mux@75->i2c@5 Bus 16: i2c@ff030000->i2c-mux@75->i2c@6 Bus 17: i2c@ff030000->i2c-mux@75->i2c@7
Without this fix i2c controllers have only -1 because they are not listed in DT.
I will send this as a patch when this is all reviewed.
Thanks, Michal