From e5395764e044dac3a231f734c4f3146b699b012c Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Sun, 22 Sep 2024 16:01:06 -0700 Subject: [PATCH 1/2] drivers: i3c: add rstact format 2 and 3 helpers Add rstact direct write and direct read formats helper functions. Signed-off-by: Ryan McClelland --- drivers/i3c/i3c_ccc.c | 35 ++++++++++++++++ include/zephyr/drivers/i3c/ccc.h | 70 +++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/drivers/i3c/i3c_ccc.c b/drivers/i3c/i3c_ccc.c index c7473e9e28091..432ec47ce32c0 100644 --- a/drivers/i3c/i3c_ccc.c +++ b/drivers/i3c/i3c_ccc.c @@ -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; diff --git a/include/zephyr/drivers/i3c/ccc.h b/include/zephyr/drivers/i3c/ccc.h index 93b2e7a4a88e1..68b2bf726a104 100644 --- a/include/zephyr/drivers/i3c/ccc.h +++ b/include/zephyr/drivers/i3c/ccc.h @@ -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, }; /** @@ -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. @@ -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. * From 0970f7ce4e641485f73c2a14632ab128c63c7519 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Sun, 22 Sep 2024 16:34:12 -0700 Subject: [PATCH 2/2] drivers: i3c: shell: add ccc rstact shell command Add a shell command for rstact format 2 and 3. Signed-off-by: Ryan McClelland --- drivers/i3c/i3c_shell.c | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/drivers/i3c/i3c_shell.c b/drivers/i3c/i3c_shell.c index f9e58483560a4..2e0e61ea51c0b 100644 --- a/drivers/i3c/i3c_shell.c +++ b/drivers/i3c/i3c_shell.c @@ -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 */ +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 */ static int cmd_i3c_ccc_enec_bc(const struct shell *sh, size_t argc, char **argv) { @@ -2369,6 +2419,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE( "Send CCC ENTTM\n" "Usage: ccc enttm ", cmd_i3c_ccc_enttm, 3, 0), + SHELL_CMD_ARG(rstact, &dsub_i3c_device_attached_name, + "Send CCC RSTACT\n" + "Usage: ccc rstact <\"set\"/\"get\"> ", + cmd_i3c_ccc_rstact, 5, 0), SHELL_CMD_ARG(rstact_bc, &dsub_i3c_device_name, "Send CCC RSTACT BC\n" "Usage: ccc rstact_bc ",