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), \ }, /**