drivers: i3c: split up i3c_device_basic_info_get
For ENTDAA, BCR and DCR is always transmitted back up to the controller. When `i3c_bus_init` is done, it does the ENTDAA then it would get the basic info would get the BCR and DCR again. This was rather reduntant. This now splits it up so there is a function called `i3c_device_adv_info_get` which gets the mrl, mwl, getcaps, and the mxds. `i3c_device_basic_info_get` now only just gets the bcr and dcr. There is also an inline function called `i3c_device_info_get` which will get everything. Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
This commit is contained in:
parent
eb7ab85fd8
commit
b5f447ced2
2 changed files with 90 additions and 37 deletions
|
|
@ -453,37 +453,35 @@ err:
|
|||
int i3c_device_basic_info_get(struct i3c_device_desc *target)
|
||||
{
|
||||
int ret;
|
||||
uint8_t tmp_bcr;
|
||||
|
||||
struct i3c_ccc_getbcr bcr = {0};
|
||||
struct i3c_ccc_getdcr dcr = {0};
|
||||
struct i3c_ccc_mrl mrl = {0};
|
||||
struct i3c_ccc_mwl mwl = {0};
|
||||
union i3c_ccc_getcaps caps = {0};
|
||||
union i3c_ccc_getmxds mxds = {0};
|
||||
|
||||
/*
|
||||
* Since some CCC functions requires BCR to function
|
||||
* correctly, we save the BCR here and update the BCR
|
||||
* in the descriptor. If any following operations fails,
|
||||
* we can restore the BCR.
|
||||
*/
|
||||
tmp_bcr = target->bcr;
|
||||
|
||||
/* GETBCR */
|
||||
ret = i3c_ccc_do_getbcr(target, &bcr);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
target->bcr = bcr.bcr;
|
||||
|
||||
/* GETDCR */
|
||||
ret = i3c_ccc_do_getdcr(target, &dcr);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
target->bcr = bcr.bcr;
|
||||
target->dcr = dcr.dcr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i3c_device_adv_info_get(struct i3c_device_desc *target)
|
||||
{
|
||||
struct i3c_ccc_mrl mrl = {0};
|
||||
struct i3c_ccc_mwl mwl = {0};
|
||||
union i3c_ccc_getcaps caps = {0};
|
||||
union i3c_ccc_getmxds mxds = {0};
|
||||
int ret;
|
||||
|
||||
/* GETMRL */
|
||||
if (i3c_ccc_do_getmrl(target, &mrl) != 0) {
|
||||
/* GETMRL may be optionally supported if no settable limit */
|
||||
|
|
@ -505,10 +503,8 @@ int i3c_device_basic_info_get(struct i3c_device_desc *target)
|
|||
* 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) {
|
||||
memcpy(&target->getcaps, &caps, sizeof(target->getcaps));
|
||||
} else if ((ret != 0) && (target->bcr & I3C_BCR_ADV_CAPABILITIES)) {
|
||||
goto out;
|
||||
if ((ret != 0) && (target->bcr & I3C_BCR_ADV_CAPABILITIES)) {
|
||||
return ret;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
|
@ -517,24 +513,21 @@ int i3c_device_basic_info_get(struct i3c_device_desc *target)
|
|||
if (target->bcr & I3C_BCR_MAX_DATA_SPEED_LIMIT) {
|
||||
ret = i3c_ccc_do_getmxds_fmt2(target, &mxds);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
target->data_speed.maxrd = mxds.fmt2.maxrd;
|
||||
target->data_speed.maxwr = mxds.fmt2.maxwr;
|
||||
target->data_speed.max_read_turnaround = sys_get_le24(mxds.fmt2.maxrdturn);
|
||||
}
|
||||
|
||||
target->dcr = dcr.dcr;
|
||||
/* Some values may not have been read, but set them back to 0 */
|
||||
memcpy(&target->getcaps, &caps, sizeof(target->getcaps));
|
||||
|
||||
target->data_speed.maxrd = mxds.fmt2.maxrd;
|
||||
target->data_speed.maxwr = mxds.fmt2.maxwr;
|
||||
target->data_speed.max_read_turnaround = sys_get_le24(mxds.fmt2.maxrdturn);
|
||||
|
||||
target->data_length.mrl = mrl.len;
|
||||
target->data_length.mwl = mwl.len;
|
||||
target->data_length.max_ibi = mrl.ibi_len;
|
||||
|
||||
out:
|
||||
if (ret != 0) {
|
||||
/* Restore BCR is any CCC fails. */
|
||||
target->bcr = tmp_bcr;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -824,9 +817,14 @@ int i3c_bus_init(const struct device *dev, const struct i3c_dev_list *dev_list)
|
|||
continue;
|
||||
}
|
||||
|
||||
ret = i3c_device_basic_info_get(desc);
|
||||
/*
|
||||
* If static address is 0, then it is assumed that BCR
|
||||
* and DCR were already read through ENTDAA
|
||||
*/
|
||||
ret = (desc->static_addr == 0) ? i3c_device_adv_info_get(desc)
|
||||
: i3c_device_info_get(desc);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Error getting basic device info for 0x%02x",
|
||||
LOG_ERR("Error getting device info for 0x%02x",
|
||||
desc->static_addr);
|
||||
} else {
|
||||
LOG_DBG("Target 0x%02x, BCR 0x%02x, DCR 0x%02x, MRL %d, MWL %d, IBI %d",
|
||||
|
|
|
|||
|
|
@ -2106,8 +2106,6 @@ int i3c_bus_init(const struct device *dev,
|
|||
* This retrieves some basic information:
|
||||
* * Bus Characteristics Register (GETBCR)
|
||||
* * Device Characteristics Register (GETDCR)
|
||||
* * Max Read Length (GETMRL)
|
||||
* * Max Write Length (GETMWL)
|
||||
* from the device and update the corresponding fields of the device
|
||||
* descriptor.
|
||||
*
|
||||
|
|
@ -2121,6 +2119,63 @@ int i3c_bus_init(const struct device *dev,
|
|||
*/
|
||||
int i3c_device_basic_info_get(struct i3c_device_desc *target);
|
||||
|
||||
/**
|
||||
* @brief Get advanced information from device and update device descriptor.
|
||||
*
|
||||
* This retrieves some information:
|
||||
* * Max Read Length (GETMRL)
|
||||
* * Max Write Length (GETMWL)
|
||||
* * Get Capabilities (GETCAPS)
|
||||
* * Max Device Speed (GETMXDS) (if applicable)
|
||||
* from the device and update the corresponding fields of the device
|
||||
* descriptor.
|
||||
*
|
||||
* This only updates the field(s) in device descriptor
|
||||
* only if CCC operations succeed.
|
||||
*
|
||||
* @note This should only be called after i3c_device_basic_info_get() or
|
||||
* if the BCR was already obtained through ENTDAA, DEFTGTS, or GETBCR.
|
||||
*
|
||||
* @param[in,out] target I3C target device descriptor.
|
||||
*
|
||||
* @retval 0 if successful.
|
||||
* @retval -EIO General Input/Output error.
|
||||
*/
|
||||
int i3c_device_adv_info_get(struct i3c_device_desc *target);
|
||||
|
||||
/**
|
||||
* @brief Get all information from device and update device descriptor.
|
||||
*
|
||||
* This retrieves all information:
|
||||
* * Bus Characteristics Register (GETBCR)
|
||||
* * Device Characteristics Register (GETDCR)
|
||||
* * Max Read Length (GETMRL)
|
||||
* * Max Write Length (GETMWL)
|
||||
* * Get Capabilities (GETCAPS)
|
||||
* * Max Device Speed (GETMXDS) (if applicable)
|
||||
* from the device and update the corresponding fields of the device
|
||||
* descriptor.
|
||||
*
|
||||
* This only updates the field(s) in device descriptor
|
||||
* only if CCC operations succeed.
|
||||
*
|
||||
* @param[in,out] target I3C target device descriptor.
|
||||
*
|
||||
* @retval 0 if successful.
|
||||
* @retval -EIO General Input/Output error.
|
||||
*/
|
||||
static inline int i3c_device_info_get(struct i3c_device_desc *target)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = i3c_device_basic_info_get(target);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return i3c_device_adv_info_get(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the bus has a secondary controller.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue