Skip to content

Commit

Permalink
drivers: i3c: add iterate through i3c/i2c devices macros
Browse files Browse the repository at this point in the history
Add i3c_bus_for_each_i3cdev and i3c_bus_for_each_i2cdev to more easily
iterate through each i3c or i2c device on the bus.

Signed-off-by: Ryan McClelland <[email protected]>
  • Loading branch information
XenuIsWatching authored and nashif committed Sep 25, 2024
1 parent ffb60c0 commit e602590
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 153 deletions.
2 changes: 2 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ ForEachMacros:
- 'HTTP_SERVER_CONTENT_TYPE_FOREACH'
- 'HTTP_SERVICE_FOREACH'
- 'HTTP_SERVICE_FOREACH_RESOURCE'
- 'I3C_BUS_FOR_EACH_I3CDEV'
- 'I3C_BUS_FOR_EACH_I2CDEV'
IfMacros:
- 'CHECKIF'
# Disabled for now, see bug https://github.com/zephyrproject-rtos/zephyr/issues/48520
Expand Down
9 changes: 2 additions & 7 deletions drivers/i3c/i3c_cdns.c
Original file line number Diff line number Diff line change
Expand Up @@ -2294,8 +2294,6 @@ static int cdns_i3c_read_ibi_fifo(const struct cdns_i3c_config *config, void *bu
static void cdns_i3c_handle_ibi(const struct device *dev, uint32_t ibir)
{
const struct cdns_i3c_config *config = dev->config;
struct cdns_i3c_data *data = dev->data;

uint8_t ibi_data[CONFIG_I3C_IBI_MAX_PAYLOAD_SIZE];

/* The slave ID returned here is the device ID in the SIR map NOT the device ID
Expand All @@ -2310,8 +2308,7 @@ static void cdns_i3c_handle_ibi(const struct device *dev, uint32_t ibir)

uint32_t dev_id_rr0 = sys_read32(config->base + DEV_ID_RR0(slave_id + 1));
uint8_t dyn_addr = DEV_ID_RR0_GET_DEV_ADDR(dev_id_rr0);
struct i3c_device_desc *desc =
i3c_dev_list_i3c_addr_find(&data->common.attached_dev, dyn_addr);
struct i3c_device_desc *desc = i3c_dev_list_i3c_addr_find(dev, dyn_addr);

/*
* Check for NAK or error conditions.
Expand Down Expand Up @@ -2989,9 +2986,7 @@ static struct i3c_device_desc *cdns_i3c_device_find(const struct device *dev,
*/
static struct i3c_i2c_device_desc *cdns_i3c_i2c_device_find(const struct device *dev, uint16_t addr)
{
struct cdns_i3c_data *data = dev->data;

return i3c_dev_list_i2c_addr_find(&data->common.attached_dev, addr);
return i3c_dev_list_i2c_addr_find(dev, addr);
}

/**
Expand Down
39 changes: 14 additions & 25 deletions drivers/i3c/i3c_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,15 @@ struct i3c_device_desc *i3c_dev_list_find(const struct i3c_dev_list *dev_list,
return ret;
}

struct i3c_device_desc *i3c_dev_list_i3c_addr_find(struct i3c_dev_attached_list *dev_list,
struct i3c_device_desc *i3c_dev_list_i3c_addr_find(const struct device *dev,
uint8_t addr)
{
sys_snode_t *node;
struct i3c_device_desc *ret = NULL;
struct i3c_device_desc *desc;

__ASSERT_NO_MSG(dev_list != NULL);

SYS_SLIST_FOR_EACH_NODE(&dev_list->devices.i3c, node) {
struct i3c_device_desc *desc = (void *)node;
__ASSERT_NO_MSG(dev != NULL);

I3C_BUS_FOR_EACH_I3CDEV(dev, desc) {
if (desc->dynamic_addr == addr) {
ret = desc;
break;
Expand All @@ -218,17 +216,15 @@ struct i3c_device_desc *i3c_dev_list_i3c_addr_find(struct i3c_dev_attached_list
return ret;
}

struct i3c_i2c_device_desc *i3c_dev_list_i2c_addr_find(struct i3c_dev_attached_list *dev_list,
struct i3c_i2c_device_desc *i3c_dev_list_i2c_addr_find(const struct device *dev,
uint16_t addr)
{
sys_snode_t *node;
struct i3c_i2c_device_desc *ret = NULL;
struct i3c_i2c_device_desc *desc;

__ASSERT_NO_MSG(dev_list != NULL);

SYS_SLIST_FOR_EACH_NODE(&dev_list->devices.i2c, node) {
struct i3c_i2c_device_desc *desc = (void *)node;
__ASSERT_NO_MSG(dev != NULL);

I3C_BUS_FOR_EACH_I2CDEV(dev, desc) {
if (desc->addr == addr) {
ret = desc;
break;
Expand Down Expand Up @@ -664,12 +660,9 @@ static int i3c_bus_setdasa(const struct device *dev,

bool i3c_bus_has_sec_controller(const struct device *dev)
{
struct i3c_driver_data *data = (struct i3c_driver_data *)dev->data;
sys_snode_t *node;

SYS_SLIST_FOR_EACH_NODE(&data->attached_dev.devices.i3c, node) {
struct i3c_device_desc *i3c_desc = CONTAINER_OF(node, struct i3c_device_desc, node);
struct i3c_device_desc *i3c_desc;

I3C_BUS_FOR_EACH_I3CDEV(dev, i3c_desc) {
if (i3c_device_is_controller_capable(i3c_desc)) {
return true;
}
Expand All @@ -683,7 +676,8 @@ int i3c_bus_deftgts(const struct device *dev)
struct i3c_driver_data *data = (struct i3c_driver_data *)dev->data;
struct i3c_config_target config_target;
struct i3c_ccc_deftgts *deftgts;
sys_snode_t *node;
struct i3c_device_desc *i3c_desc;
struct i3c_i2c_device_desc *i3c_i2c_desc;
int ret;
uint8_t n = 0;
size_t num_of_targets = sys_slist_len(&data->attached_dev.devices.i3c) +
Expand Down Expand Up @@ -723,9 +717,7 @@ int i3c_bus_deftgts(const struct device *dev)
/*
* Loop through each attached I3C device and add it to the payload
*/
SYS_SLIST_FOR_EACH_NODE(&data->attached_dev.devices.i3c, node) {
struct i3c_device_desc *i3c_desc = CONTAINER_OF(node, struct i3c_device_desc, node);

I3C_BUS_FOR_EACH_I3CDEV(dev, i3c_desc) {
deftgts->targets[n].addr = i3c_desc->dynamic_addr << 1;
deftgts->targets[n].dcr = i3c_desc->dcr;
deftgts->targets[n].bcr = i3c_desc->bcr;
Expand All @@ -736,10 +728,7 @@ int i3c_bus_deftgts(const struct device *dev)
/*
* Loop through each attached I2C device and add it to the payload
*/
SYS_SLIST_FOR_EACH_NODE(&data->attached_dev.devices.i2c, node) {
struct i3c_i2c_device_desc *i3c_i2c_desc =
CONTAINER_OF(node, struct i3c_i2c_device_desc, node);

I3C_BUS_FOR_EACH_I2CDEV(dev, i3c_i2c_desc) {
deftgts->targets[n].addr = 0;
deftgts->targets[n].lvr = i3c_i2c_desc->lvr;
deftgts->targets[n].bcr = 0;
Expand Down
3 changes: 1 addition & 2 deletions drivers/i3c/i3c_mcux.c
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,6 @@ static void mcux_i3c_ibi_work(struct k_work *work)
const struct device *dev = i3c_ibi_work->controller;
const struct mcux_i3c_config *config = dev->config;
struct mcux_i3c_data *data = dev->data;
struct i3c_dev_attached_list *dev_list = &data->common.attached_dev;
I3C_Type *base = config->base;
struct i3c_device_desc *target = NULL;
uint32_t mstatus, ibitype, ibiaddr;
Expand Down Expand Up @@ -1517,7 +1516,7 @@ static void mcux_i3c_ibi_work(struct k_work *work)

switch (ibitype) {
case I3C_MSTATUS_IBITYPE_IBI:
target = i3c_dev_list_i3c_addr_find(dev_list, (uint8_t)ibiaddr);
target = i3c_dev_list_i3c_addr_find(dev, (uint8_t)ibiaddr);
if (target != NULL) {
ret = mcux_i3c_do_one_xfer_read(base, &payload[0],
sizeof(payload), true);
Expand Down
3 changes: 1 addition & 2 deletions drivers/i3c/i3c_npcx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1455,7 +1455,6 @@ static void npcx_i3c_ibi_work(struct k_work *work)
const struct device *dev = i3c_ibi_work->controller;
const struct npcx_i3c_config *config = dev->config;
struct npcx_i3c_data *data = dev->data;
struct i3c_dev_attached_list *dev_list = &data->common.attached_dev;
struct i3c_reg *inst = config->base;
struct i3c_device_desc *target = NULL;
uint32_t ibitype, ibiaddr;
Expand Down Expand Up @@ -1530,7 +1529,7 @@ static void npcx_i3c_ibi_work(struct k_work *work)

switch (ibitype) {
case MSTATUS_IBITYPE_IBI:
target = i3c_dev_list_i3c_addr_find(dev_list, (uint8_t)ibiaddr);
target = i3c_dev_list_i3c_addr_find(dev, (uint8_t)ibiaddr);
if (target != NULL) {
if (i3c_ibi_work_enqueue_target_irq(target, &payload[0], payload_sz) != 0) {
LOG_ERR("Error enqueue IBI IRQ work");
Expand Down
Loading

0 comments on commit e602590

Please sign in to comment.