From 9d345fc44754b20fce920934e80f219205102e3b Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Tue, 3 Sep 2024 12:25:09 -0700 Subject: [PATCH] drivers: i3c: add support for setaasa initialization Adds a new DTS prop for i3c devices as support for the CCC SETAASA requires prior knowledge of the target if it supports it according to i3c spec v1.1.1 section 5.19.3.23. This will be used as an optimization for bus initialization. Signed-off-by: Ryan McClelland --- drivers/i3c/i3c_common.c | 38 +++++++++++++++++++++++-- drivers/i3c/i3c_shell.c | 3 +- dts/bindings/i3c/i3c-device.yaml | 6 ++++ include/zephyr/drivers/i3c.h | 8 ++++++ include/zephyr/drivers/i3c/devicetree.h | 1 + 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/drivers/i3c/i3c_common.c b/drivers/i3c/i3c_common.c index 72e82a787a9beb..d36a5ca6ddc177 100644 --- a/drivers/i3c/i3c_common.c +++ b/drivers/i3c/i3c_common.c @@ -591,11 +591,12 @@ int i3c_device_basic_info_get(struct i3c_device_desc *target) */ static int i3c_bus_setdasa(const struct device *dev, const struct i3c_dev_list *dev_list, - bool *need_daa) + bool *need_daa, bool *need_aasa) { int i, ret; *need_daa = false; + *need_aasa = false; /* Loop through the registered I3C devices */ for (i = 0; i < dev_list->num_i3c; i++) { @@ -610,6 +611,17 @@ static int i3c_bus_setdasa(const struct device *dev, continue; } + /* + * A device that supports SETAASA and will use the same dynamic + * address as its static address if a different dynamic address + * is not requested + */ + if ((desc->supports_setaasa) && ((desc->init_dynamic_addr == 0) || + desc->init_dynamic_addr == desc->static_addr)) { + *need_aasa = true; + continue; + } + LOG_DBG("SETDASA for 0x%x", desc->static_addr); ret = i3c_ccc_do_setdasa(desc); @@ -639,6 +651,7 @@ int i3c_bus_init(const struct device *dev, const struct i3c_dev_list *dev_list) { int i, ret = 0; bool need_daa = true; + bool need_aasa = true; struct i3c_ccc_events i3c_events; #ifdef CONFIG_I3C_INIT_RSTACT @@ -684,11 +697,32 @@ int i3c_bus_init(const struct device *dev, const struct i3c_dev_list *dev_list) /* * Set static addresses as dynamic addresses. */ - ret = i3c_bus_setdasa(dev, dev_list, &need_daa); + ret = i3c_bus_setdasa(dev, dev_list, &need_daa, &need_aasa); if (ret != 0) { goto err_out; } + /* + * Perform Set All Addresses to Static Address if possible. + */ + if (need_aasa) { + ret = i3c_ccc_do_setaasa_all(dev); + if (ret != 0) { + for (i = 0; i < dev_list->num_i3c; i++) { + struct i3c_device_desc *desc = &dev_list->i3c[i]; + /* + * Only set for devices that support SETAASA and do not + * request a different dynamic address than its SA + */ + if ((desc->supports_setaasa) && (desc->static_addr != 0) && + ((desc->init_dynamic_addr == 0) || + desc->init_dynamic_addr == desc->static_addr)) { + desc->dynamic_addr = desc->static_addr; + } + } + } + } + /* * Perform Dynamic Address Assignment if needed. */ diff --git a/drivers/i3c/i3c_shell.c b/drivers/i3c/i3c_shell.c index dd9955520ed35e..454d5bde145b55 100644 --- a/drivers/i3c/i3c_shell.c +++ b/drivers/i3c/i3c_shell.c @@ -550,7 +550,8 @@ static int cmd_i3c_ccc_setaasa(const struct shell *shell_ctx, size_t argc, char SYS_SLIST_FOR_EACH_NODE(&data->attached_dev.devices.i3c, node) { struct i3c_device_desc *desc = CONTAINER_OF(node, struct i3c_device_desc, node); - if ((desc->dynamic_addr == 0) && (desc->static_addr != 0)) { + if ((desc->supports_setaasa) && (desc->dynamic_addr == 0) && + (desc->static_addr != 0)) { desc->dynamic_addr = desc->static_addr; } } diff --git a/dts/bindings/i3c/i3c-device.yaml b/dts/bindings/i3c/i3c-device.yaml index 48a0bd01e71f25..297e28e632577d 100644 --- a/dts/bindings/i3c/i3c-device.yaml +++ b/dts/bindings/i3c/i3c-device.yaml @@ -61,3 +61,9 @@ properties: type: int description: | Dynamic address to be assigned to the device. + + supports-setaasa: + type: boolean + description: | + Indicates if the device supports the CCC SETAASA. If true, it will + be used as an optimization for bus initialization. diff --git a/include/zephyr/drivers/i3c.h b/include/zephyr/drivers/i3c.h index 4eed486092cf21..9c0a5e241d1397 100644 --- a/include/zephyr/drivers/i3c.h +++ b/include/zephyr/drivers/i3c.h @@ -949,6 +949,14 @@ struct i3c_device_desc { */ const uint8_t init_dynamic_addr; + /** + * Device support for SETAASA + * + * This will be used as an optimization for bus initializtion if the + * device supports SETAASA. + */ + const bool supports_setaasa; + /** * Dynamic Address for this target device used for communication. * diff --git a/include/zephyr/drivers/i3c/devicetree.h b/include/zephyr/drivers/i3c/devicetree.h index 4834b5bbd85ecd..803f17d55179b5 100644 --- a/include/zephyr/drivers/i3c/devicetree.h +++ b/include/zephyr/drivers/i3c/devicetree.h @@ -71,6 +71,7 @@ extern "C" { | DT_PROP_BY_IDX(node_id, reg, 2), \ .init_dynamic_addr = \ DT_PROP_OR(node_id, assigned_address, 0), \ + .supports_setaasa = DT_PROP(node_id, supports_setaasa), \ }, /**