Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions drivers/i3c/i3c_ccc.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,41 @@ int i3c_ccc_do_rstact_all(const struct device *controller,
return i3c_do_ccc(controller, &ccc_payload);
}

int i3c_ccc_do_rstact(const struct i3c_device_desc *target,
enum i3c_ccc_rstact_defining_byte action,
bool get,
uint8_t *data)
{
struct i3c_ccc_payload ccc_payload;
struct i3c_ccc_target_payload ccc_tgt_payload;
uint8_t def_byte;

__ASSERT_NO_MSG(target != NULL);
__ASSERT_NO_MSG(target->bus != NULL);

memset(&ccc_payload, 0, sizeof(ccc_payload));

ccc_tgt_payload.addr = target->dynamic_addr;
if (get) {
__ASSERT_NO_MSG(data != NULL);

ccc_tgt_payload.rnw = 1;
ccc_tgt_payload.data = data;
ccc_tgt_payload.data_len = sizeof(*data);
} else {
ccc_tgt_payload.rnw = 0;
}

ccc_payload.ccc.id = I3C_CCC_RSTACT(false);
def_byte = (uint8_t)action;
ccc_payload.ccc.data = &def_byte;
ccc_payload.ccc.data_len = 1U;
ccc_payload.targets.payloads = &ccc_tgt_payload;
ccc_payload.targets.num_targets = 1;

return i3c_do_ccc(target->bus, &ccc_payload);
}

int i3c_ccc_do_rstdaa_all(const struct device *controller)
{
struct i3c_ccc_payload ccc_payload;
Expand Down
54 changes: 54 additions & 0 deletions drivers/i3c/i3c_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,56 @@ static int cmd_i3c_ccc_rstact_bc(const struct shell *sh, size_t argc, char **arg
return ret;
}

/* i3c ccc rstact <device> <target> <defining byte> */
static int cmd_i3c_ccc_rstact(const struct shell *sh, size_t argc, char **argv)
{
const struct device *dev, *tdev;
struct i3c_device_desc *desc;
enum i3c_ccc_rstact_defining_byte action;
int ret;
uint8_t data;

dev = device_get_binding(argv[ARGV_DEV]);
if (!dev) {
shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]);
return -ENODEV;
}

tdev = device_get_binding(argv[ARGV_TDEV]);
if (!tdev) {
shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_TDEV]);
return -ENODEV;
}
desc = get_i3c_attached_desc_from_dev_name(dev, tdev->name);
if (!desc) {
shell_error(sh, "I3C: Device %s not attached to bus.", tdev->name);
return -ENODEV;
}

action = strtol(argv[5], NULL, 16);

if (strcmp(argv[4], "get") == 0) {
ret = i3c_ccc_do_rstact_fmt3(tdev, action, &data);
} else if (strcmp(argv[4], "set") == 0) {
ret = i3c_ccc_do_rstact_fmt2(tdev, action);
} else {
shell_error(sh, "I3C: invalid parameter");
return -EINVAL;
}

if (ret < 0) {
shell_error(sh, "I3C: unable to send CCC RSTACT BC.");
return ret;
}

if (action >= 0x80) {
shell_print("RSTACT Returned Data: 0x%02x", data);
}

return ret;
}


/* i3c ccc enec_bc <device> <defining byte> */
static int cmd_i3c_ccc_enec_bc(const struct shell *sh, size_t argc, char **argv)
{
Expand Down Expand Up @@ -2369,6 +2419,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
"Send CCC ENTTM\n"
"Usage: ccc enttm <device> <defining byte>",
cmd_i3c_ccc_enttm, 3, 0),
SHELL_CMD_ARG(rstact, &dsub_i3c_device_attached_name,
"Send CCC RSTACT\n"
"Usage: ccc rstact <device> <target> <\"set\"/\"get\"> <defining byte>",
cmd_i3c_ccc_rstact, 5, 0),
SHELL_CMD_ARG(rstact_bc, &dsub_i3c_device_name,
"Send CCC RSTACT BC\n"
"Usage: ccc rstact_bc <device> <defining byte>",
Expand Down
70 changes: 68 additions & 2 deletions include/zephyr/drivers/i3c/ccc.h
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,18 @@ enum i3c_ccc_rstact_defining_byte {

/** Virtual Target Detect. */
I3C_CCC_RSTACT_VIRTUAL_TARGET_DETECT = 0x04U,

/** Return Time to Reset Peripheral */
I3C_CCC_RSTACT_RETURN_TIME_TO_RESET_PERIPHERAL = 0x81U,

/** Return Time to Reset Whole Target */
I3C_CCC_RSTACT_RETURN_TIME_TO_WHOLE_TARGET = 0x82U,

/** Return Time for Debug Network Adapter Reset */
I3C_CCC_RSTACT_RETURN_TIME_FOR_DEBUG_NETWORK_ADAPTER_RESET = 0x83U,

/** Return Virtual Target Indication */
I3C_CCC_RSTACT_RETURN_VIRTUAL_TARGET_INDICATION = 0x84U,
};

/**
Expand Down Expand Up @@ -1317,10 +1329,10 @@ int i3c_ccc_do_getpid(struct i3c_device_desc *target,
struct i3c_ccc_getpid *pid);

/**
* @brief Broadcast RSTACT to reset I3C Peripheral.
* @brief Broadcast RSTACT to reset I3C Peripheral (Format 1).
*
* Helper function to broadcast Target Reset Action (RSTACT) to
* all connected targets to Reset the I3C Peripheral Only (0x01).
* all connected targets.
*
* @param[in] controller Pointer to the controller device driver instance.
* @param[in] action What reset action to perform.
Expand All @@ -1330,6 +1342,60 @@ int i3c_ccc_do_getpid(struct i3c_device_desc *target,
int i3c_ccc_do_rstact_all(const struct device *controller,
enum i3c_ccc_rstact_defining_byte action);

/**
* @brief Single target RSTACT to reset I3C Peripheral.
*
* Helper function to do Target Reset Action (RSTACT) to
* one target.
*
* @param[in] target Pointer to the target device descriptor.
* @param[in] action What reset action to perform.
* @param[in] get True if a get, False if set
* @param[out] data Pointer to RSTACT payload received.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_rstact(const struct i3c_device_desc *target,
enum i3c_ccc_rstact_defining_byte action,
bool get,
uint8_t *data);

/**
* @brief Single target RSTACT to reset I3C Peripheral (Format 2).
*
* Helper function to do Target Reset Action (RSTACT, format 2) to
* one target. This is a Direct Write.
*
* @param[in] target Pointer to the target device descriptor.
* @param[in] action What reset action to perform.
*
* @return @see i3c_do_ccc
*/
static inline int i3c_ccc_do_rstact_fmt2(const struct i3c_device_desc *target,
enum i3c_ccc_rstact_defining_byte action)
{
return i3c_ccc_do_rstact(target, action, false, NULL);
}

/**
* @brief Single target RSTACT to reset I3C Peripheral (Format 3).
*
* Helper function to do Target Reset Action (RSTACT, format 3) to
* one target. This is a Direct Read.
*
* @param[in] target Pointer to the target device descriptor.
* @param[in] action What reset action to perform.
* @param[out] data Pointer to RSTACT payload received.
*
* @return @see i3c_do_ccc
*/
static inline int i3c_ccc_do_rstact_fmt3(const struct i3c_device_desc *target,
enum i3c_ccc_rstact_defining_byte action,
uint8_t *data)
{
return i3c_ccc_do_rstact(target, action, true, data);
}

/**
* @brief Broadcast RSTDAA to reset dynamic addresses for all targets.
*
Expand Down