diff --git a/drivers/i3c/i3c_common.c b/drivers/i3c/i3c_common.c index 15b951fd9ec..2f1b402a6ee 100644 --- a/drivers/i3c/i3c_common.c +++ b/drivers/i3c/i3c_common.c @@ -777,28 +777,28 @@ int i3c_device_adv_info_get(struct i3c_device_desc *target) /* GETMRL */ if (i3c_ccc_do_getmrl(target, &mrl) != 0) { /* GETMRL may be optionally supported if no settable limit */ - LOG_DBG("No settable limit for GETMRL"); + LOG_DBG("%s: No settable limit for GETMRL", target->dev->name); } /* GETMWL */ if (i3c_ccc_do_getmwl(target, &mwl) != 0) { /* GETMWL may be optionally supported if no settable limit */ - LOG_DBG("No settable limit for GETMWL"); + LOG_DBG("%s: No settable limit for GETMWL", target->dev->name); } /* GETCAPS */ - ret = i3c_ccc_do_getcaps_fmt1(target, &caps); - /* - * GETCAPS (GETHDRCAP) is required to be supported for I3C v1.0 targets that support HDR - * modes and required if the Target's I3C version is v1.1 or later, but which the version it - * supports it can't be known ahead of time. So if the BCR bit for Advanced capabilities is - * set, then it is expected for GETCAPS to always be supported. Otherwise, then it's a I3C - * v1.0 device without any HDR modes so do not treat as an error if no valid response. - */ - if ((ret != 0) && (target->bcr & I3C_BCR_ADV_CAPABILITIES)) { - return ret; - } else { - ret = 0; + if (((target->flags & I3C_V1P0_SUPPORT) && (target->bcr & I3C_BCR_ADV_CAPABILITIES)) || + (!(target->flags & I3C_V1P0_SUPPORT))) { + /* + * GETCAPS (GETHDRCAP) is required to be supported for I3C v1.0 targets that support + * HDR modes and required if the Target's I3C version is v1.1 or later. + * It is also possible for this function to be called on an 'unknown' device such as + * from a secondary controller gathering info about a target it found about through + * DEFTGTS, and it can't be known ahead of time if it is a v1.0 or v1.1 device. + */ + if (i3c_ccc_do_getcaps_fmt1(target, &caps) != 0) { + LOG_DBG("%s: GETCAPS not received", target->dev->name); + } } /* CRCAPS */ @@ -873,8 +873,9 @@ static int i3c_bus_setdasa(const struct device *dev, const struct i3c_dev_list * * 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)) { + if ((desc->flags & I3C_SUPPORTS_SETAASA) && + ((desc->init_dynamic_addr == 0) || + desc->init_dynamic_addr == desc->static_addr)) { *need_aasa = true; continue; } @@ -1079,7 +1080,8 @@ int i3c_bus_init(const struct device *dev, const struct i3c_dev_list *dev_list) * 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) && + if ((desc->flags & I3C_SUPPORTS_SETAASA) && + (desc->static_addr != 0) && ((desc->init_dynamic_addr == 0) || desc->init_dynamic_addr == desc->static_addr)) { desc->dynamic_addr = desc->static_addr; diff --git a/drivers/i3c/i3c_shell.c b/drivers/i3c/i3c_shell.c index 42652a34e19..99baf3f7041 100644 --- a/drivers/i3c/i3c_shell.c +++ b/drivers/i3c/i3c_shell.c @@ -629,7 +629,7 @@ static int cmd_i3c_ccc_setaasa(const struct shell *sh, size_t argc, char **argv) /* set all devices DA to SA */ I3C_BUS_FOR_EACH_I3CDEV(dev, desc) { - if ((desc->supports_setaasa) && (desc->dynamic_addr == 0) && + if (((desc->flags) & I3C_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 297e28e6325..76e4dafa630 100644 --- a/dts/bindings/i3c/i3c-device.yaml +++ b/dts/bindings/i3c/i3c-device.yaml @@ -67,3 +67,8 @@ properties: description: | Indicates if the device supports the CCC SETAASA. If true, it will be used as an optimization for bus initialization. + + v1p0-support: + type: boolean + description: | + Indicates if the device compiles to I3C v1.0. diff --git a/include/zephyr/drivers/i3c.h b/include/zephyr/drivers/i3c.h index 0f3dab60001..4e94c890b3b 100644 --- a/include/zephyr/drivers/i3c.h +++ b/include/zephyr/drivers/i3c.h @@ -929,12 +929,13 @@ struct i3c_device_desc { const uint8_t init_dynamic_addr; /** - * Device support for SETAASA + * Device Flags * - * This will be used as an optimization for bus initializtion if the + * BIT[0]: This shall be used as an optimization for bus initializtion if the * device supports SETAASA. + * BIT[1]: This shall be used to indicate if the device is a I3C v1.0 device */ - const bool supports_setaasa; + const uint8_t flags; /** * 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 803f17d5517..2ab0749b01e 100644 --- a/include/zephyr/drivers/i3c/devicetree.h +++ b/include/zephyr/drivers/i3c/devicetree.h @@ -52,6 +52,19 @@ extern "C" { #define I3C_DEVICE_ID_DT_INST(inst) \ I3C_DEVICE_ID_DT(DT_DRV_INST(inst)) +/** + * @name I3C device flags. + * @anchor I3C_DEVICE_FLAGS + * @{ + */ + +/** Device supports SETAASA CCC */ +#define I3C_SUPPORTS_SETAASA BIT(0) +/** Device supports I3C v1.0 */ +#define I3C_V1P0_SUPPORT BIT(1) + +/** @} */ + /** * @brief Structure initializer for i3c_device_desc from devicetree * @@ -62,16 +75,16 @@ extern "C" { * @param node_id Devicetree node identifier for the I3C device whose * struct i3c_device_desc to create an initializer for */ -#define I3C_DEVICE_DESC_DT(node_id) \ - { \ - .bus = DEVICE_DT_GET(DT_BUS(node_id)), \ - .dev = DEVICE_DT_GET(node_id), \ - .static_addr = DT_PROP_BY_IDX(node_id, reg, 0), \ - .pid = ((uint64_t)DT_PROP_BY_IDX(node_id, reg, 1) << 32)\ - | 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), \ +#define I3C_DEVICE_DESC_DT(node_id) \ + { \ + .bus = DEVICE_DT_GET(DT_BUS(node_id)), \ + .dev = DEVICE_DT_GET(node_id), \ + .static_addr = DT_PROP_BY_IDX(node_id, reg, 0), \ + .pid = ((uint64_t)DT_PROP_BY_IDX(node_id, reg, 1) << 32) | \ + DT_PROP_BY_IDX(node_id, reg, 2), \ + .init_dynamic_addr = DT_PROP_OR(node_id, assigned_address, 0), \ + .flags = FIELD_PREP(I3C_SUPPORTS_SETAASA, DT_PROP(node_id, supports_setaasa)) | \ + FIELD_PREP(I3C_V1P0_SUPPORT, DT_PROP(node_id, v1p0_support)), \ }, /**