drivers: i3c: add v1.0 support flag
This adds a v1.0 support dts flag for devices. This also makes it so it doesn't try to send a GETCAPS (GETHDRCAP) ccc if this flag is set and it doesn't support any HDR modes. Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
This commit is contained in:
parent
2f9faa0a93
commit
2e8c911fa3
5 changed files with 52 additions and 31 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)), \
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue