diff options
Diffstat (limited to 'zephyr/shim/include/usbc/usb_muxes.h')
-rw-r--r-- | zephyr/shim/include/usbc/usb_muxes.h | 441 |
1 files changed, 266 insertions, 175 deletions
diff --git a/zephyr/shim/include/usbc/usb_muxes.h b/zephyr/shim/include/usbc/usb_muxes.h index f7cfd7159b..9dce1a3aa5 100644 --- a/zephyr/shim/include/usbc/usb_muxes.h +++ b/zephyr/shim/include/usbc/usb_muxes.h @@ -1,4 +1,4 @@ -/* Copyright 2022 The Chromium OS Authors. All rights reserved. +/* Copyright 2022 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -16,6 +16,7 @@ #include "usbc/ps8743_usb_mux.h" #include "usbc/tcpci_usb_mux.h" #include "usbc/tusb1064_usb_mux.h" +#include "usbc/utils.h" #include "usbc/virtual_usb_mux.h" /** @@ -48,15 +49,28 @@ #define USB_MUX_DRIVER_GET_CONFIG(driver) GET_ARG_N(2, __DEBRACKET driver) /** - * @brief USB mux port number based on parent node in DTS + * @brief Name of USB mux chain structure for given port and place in chain. + * Note, that root of chain is not referred by this name, but + * usb_muxes[@p port_id]. * - * @param port_id USBC node ID + * @param idx Place in chain + * @param port_id USBC port id */ -#define USB_MUX_PORT(port_id) DT_REG_ADDR(port_id) +#define USB_MUX_CHAIN_STRUCT_NAME(idx, port_id) \ + DT_CAT4(USB_MUX_chain_port_, port_id, _mux_, idx) /** - * @brief Name of USB mux structure if node is not EMPTY. Note, that root of - * chain is not referred by this name, but usb_muxes[USB_MUX_PORT(id)]. + * @brief Declaration of USB mux chain structure for @p idx mux in @p port_id + * USB-C port's chain + * + * @param port_id USBC port ID (number) + * @param idx Place in chain + */ +#define USB_MUX_CHAIN_STRUCT_DECLARE(port_id, idx) \ + MAYBE_CONST struct usb_mux_chain USB_MUX_CHAIN_STRUCT_NAME(idx, port_id) + +/** + * @brief Name of USB mux structure if node @p mux_id is not EMPTY. * * @param mux_id USB mux node ID */ @@ -82,22 +96,16 @@ * @brief Declaration of USB mux board_init function * * @param mux_id USB mux node ID - * @param port_id USBC node ID - * @param idx Position of USB mux in chain - * @param conf Driver configuration function */ -#define USB_MUX_CB_BOARD_INIT_DECLARE(mux_id, port_id, idx, conf) \ +#define USB_MUX_CB_BOARD_INIT_DECLARE(mux_id) \ int DT_STRING_TOKEN(mux_id, board_init)(const struct usb_mux *); /** * @brief Declaration of USB mux board_set function * * @param mux_id USB mux node ID - * @param port_id USBC node ID - * @param idx Position of USB mux in chain - * @param conf Driver configuration function */ -#define USB_MUX_CB_BOARD_SET_DECLARE(mux_id, port_id, idx, conf) \ +#define USB_MUX_CB_BOARD_SET_DECLARE(mux_id) \ int DT_STRING_TOKEN(mux_id, board_set)(const struct usb_mux *, \ mux_state_t); @@ -112,33 +120,43 @@ /** * @brief Get node id of @p idx USB mux in chain * + * @param chain_id USB mux chain node ID * @param idx Position of USB mux in chain - * @param port_id USBC node ID */ -#define USB_MUX_GET_CHAIN_N(idx, port_id) \ - DT_PHANDLE_BY_IDX(port_id, usb_muxes, idx) +#define USB_MUX_GET_CHAIN_N(chain_id, idx) \ + DT_PHANDLE_BY_IDX(chain_id, usb_muxes, idx) /** - * @brief Get node id of next USB mux in chain or EMPTY if it is last mux + * @brief Get next USB mux chain structure name or EMPTY if it is last mux * - * @param port_id USBC node ID + * @param chain_id USB mux chain node ID * @param idx Position of USB mux in chain */ -#define USB_MUX_NEXT(port_id, idx) \ - GET_ARG_N(2, \ - GET_ARGS_LESS_N( \ - idx, LISTIFY(DT_PROP_LEN(port_id, usb_muxes), \ - USB_MUX_GET_CHAIN_N, (, ), port_id)), \ +#define USB_MUX_CHAIN_NEXT_NAME(chain_id, idx) \ + GET_ARG_N(2, \ + GET_ARGS_LESS_N(idx, \ + LISTIFY(DT_PROP_LEN(chain_id, usb_muxes), \ + USB_MUX_CHAIN_STRUCT_NAME, (, ), \ + USBC_PORT(chain_id))), \ EMPTY) /** * @brief Get pointer to next USB mux in chain or NULL if it is last mux * - * @param port_id USBC node ID + * @param chain_id USB mux chain node ID + * @param idx Position of USB mux in chain + */ +#define USB_MUX_CHAIN_NEXT_POINTER(chain_id, idx) \ + USB_MUX_POINTER_OR_NULL(USB_MUX_CHAIN_NEXT_NAME(chain_id, idx)) + +/** + * @brief Get pointer to USB mux that is @p idx in chain @p chain_id + * + * @param chain_id USB mux chain node ID * @param idx Position of USB mux in chain */ -#define USB_MUX_NEXT_POINTER(port_id, idx) \ - USB_MUX_POINTER_OR_NULL(USB_MUX_STRUCT_NAME(USB_MUX_NEXT(port_id, idx))) +#define USB_MUX_POINTER(chain_id, idx) \ + &USB_MUX_STRUCT_NAME(USB_MUX_GET_CHAIN_N(chain_id, idx)) /** * @brief Generate pointer to function from @p cb_name property or NULL @@ -154,255 +172,328 @@ * @brief Set struct usb_mux fields common for all USB muxes and alter flags * * @param mux_id USB mux node ID - * @param port_id USBC node ID - * @param idx Position of USB mux in chain * @param flags_mask Mask for bits that should be igonred in flags property * @param flags_val Value that should be used instead for masked bits */ -#define USB_MUX_COMMON_FIELDS_WITH_FLAGS(mux_id, port_id, idx, flags_mask, \ - flags_val) \ - .usb_port = USB_MUX_PORT(port_id), \ - .next_mux = USB_MUX_NEXT_POINTER(port_id, idx), \ - .board_init = USB_MUX_CALLBACK_OR_NULL(mux_id, board_init), \ - .board_set = USB_MUX_CALLBACK_OR_NULL(mux_id, board_set), \ +#define USB_MUX_COMMON_FIELDS_WITH_FLAGS(mux_id, flags_mask, flags_val) \ + .usb_port = USB_MUX_PORT(mux_id), \ + .board_init = USB_MUX_CALLBACK_OR_NULL(mux_id, board_init), \ + .board_set = USB_MUX_CALLBACK_OR_NULL(mux_id, board_set), \ .flags = (DT_PROP(mux_id, flags) & ~(flags_mask)) | (flags_val) /** * @brief Set struct usb_mux fields common for all USB muxes * * @param mux_id USB mux node ID - * @param port_id USBC node ID - * @param idx Position of USB mux in chain */ -#define USB_MUX_COMMON_FIELDS(mux_id, port_id, idx) \ - USB_MUX_COMMON_FIELDS_WITH_FLAGS(mux_id, port_id, idx, 0, 0) +#define USB_MUX_COMMON_FIELDS(mux_id) \ + USB_MUX_COMMON_FIELDS_WITH_FLAGS(mux_id, 0, 0) /** - * @brief Expands to 1 if @p mux_id has @p compat compatible. It is required - * to makes sure that @p compat is expanded before DT_NODE_HAS_COMPAT + * @brief Declare USB mux structure * * @param mux_id USB mux node ID - * @param compat USB mux driver compatible + * @param conf Driver configuration function */ -#define USB_MUX_IS_COMPATIBLE(mux_id, compat) DT_NODE_HAS_COMPAT(mux_id, compat) +#define USB_MUX_DECLARE(mux_id, conf) extern USB_MUX_STRUCT_DECLARE(mux_id); /** - * @brief Expands to @p driver config if @p mux_id is compatible with @p driver + * @brief Define USB mux structure using driver USB_MUX_CONFIG_* macro * - * @param driver USB mux driver description in format (compatible, config) * @param mux_id USB mux node ID + * @param conf Driver configuration function */ -#define USB_MUX_DRIVER_CONFIG_IF_COMPAT(driver, mux_id) \ - COND_CODE_1(USB_MUX_IS_COMPATIBLE(mux_id, \ - USB_MUX_DRIVER_GET_COMPAT(driver)), \ - (USB_MUX_DRIVER_GET_CONFIG(driver)), ()) +#define USB_MUX_DEFINE(mux_id, conf) \ + USB_MUX_STRUCT_DECLARE(mux_id) = conf(mux_id); /** - * @brief Find driver from USB_MUX_DRIVERS that is compatible with @p mux_id + * @brief Call @p cb_op if @p mux_id has @p cb_prop property * * @param mux_id USB mux node ID + * @param cb_prop The callback property name + * @param cb_op Operation to perform on USB muxes */ -#define USB_MUX_FIND_DRIVER_CONFIG(mux_id) \ - FOR_EACH_FIXED_ARG(USB_MUX_DRIVER_CONFIG_IF_COMPAT, (), mux_id, \ - USB_MUX_DRIVERS) +#define USB_MUX_CB_DECLARE_IF_EXIST(mux_id, cb_prop, cb_op) \ + COND_CODE_1(DT_NODE_HAS_PROP(mux_id, cb_prop), (cb_op(mux_id)), ()) /** - * @brief Get driver configuration macro for @p mux_id and call @p op + * @brief Declare USB mux board_set function @p mux_id has board_set property * * @param mux_id USB mux node ID - * @param port_id USBC node ID - * @param idx Position of USB mux in chain - * @param op Operation to perform on USB muxes + * @param conf Driver configuration function */ -#define USB_MUX_CALL_OP(mux_id, port_id, idx, op) \ - op(mux_id, port_id, idx, USB_MUX_FIND_DRIVER_CONFIG(mux_id)) +#define USB_MUX_CB_BOARD_SET_DECLARE_IF_EXISTS(mux_id, conf) \ + USB_MUX_CB_DECLARE_IF_EXIST(mux_id, board_set, \ + USB_MUX_CB_BOARD_SET_DECLARE) /** - * @brief Get USB mux node ID and call USB_MUX_CALL_OP + * @brief Declare USB mux board_init function @p mux_id has board_init property * - * @param port_id USBC node ID - * @param idx Position of USB mux in chain - * @param op Operation to perform on USB muxes + * @param mux_id USB mux node ID + * @param conf Driver configuration function */ -#define USB_MUX_DO(port_id, idx, op) \ - USB_MUX_CALL_OP(USB_MUX_GET_CHAIN_N(idx, port_id), port_id, idx, op) +#define USB_MUX_CB_BOARD_INIT_DECLARE_IF_EXISTS(mux_id, conf) \ + USB_MUX_CB_DECLARE_IF_EXIST(mux_id, board_init, \ + USB_MUX_CB_BOARD_INIT_DECLARE) /** - * @brief Declare USB mux structure + * @brief Call @p op operation for each node that is compatible with @p driver * - * @param mux_id USB mux node ID - * @param port_id USBC node ID - * @param idx Position of USB mux in chain - * @param conf Driver configuration function + * @param driver USB mux driver description in format (compatible, config) + * @param op Operation to perform on each USB mux. Should accept mux node ID and + * driver config as arguments. */ -#define USB_MUX_DECLARE(mux_id, port_id, idx, conf) \ - extern USB_MUX_STRUCT_DECLARE(mux_id); +#define USB_MUX_DRIVER_CONFIG(driver, op) \ + DT_FOREACH_STATUS_OKAY_VARGS(USB_MUX_DRIVER_GET_COMPAT(driver), op, \ + USB_MUX_DRIVER_GET_CONFIG(driver)) /** - * @brief Define USB mux structure using driver USB_MUX_CONFIG_* macro + * @brief Call @p op operation for each USB mux node that is compatible with + * any driver from the USB_MUX_DRIVERS list. + * DT_FOREACH_STATUS_OKAY_VARGS() macro can not be used in @p op * - * @param mux_id USB mux node ID - * @param port_id USBC node ID - * @param idx Position of USB mux in chain - * @param conf Driver configuration function + * @param op Operation to perform on each USB mux. Should accept mux node ID and + * driver config as arguments. */ -#define USB_MUX_DEFINE(mux_id, port_id, idx, conf) \ - USB_MUX_STRUCT_DECLARE(mux_id) = conf(mux_id, port_id, idx); +#define USB_MUX_FOREACH_MUX_DT_VARGS(op) \ + FOR_EACH_FIXED_ARG(USB_MUX_DRIVER_CONFIG, (), op, USB_MUX_DRIVERS) /** - * @brief Define entry of usb_muxes array using driver USB_MUX_CONFIG_* macro + * @brief Convert @p mux_id and @p conf pair into USB_MUX_LIST entry * * @param mux_id USB mux node ID - * @param port_id USBC node ID - * @param idx Position of USB mux in chain * @param conf Driver configuration function */ -#define USB_MUX_ARRAY(mux_id, port_id, idx, conf) \ - [USB_MUX_PORT(port_id)] = conf(mux_id, port_id, idx), +#define USB_MUX_TO_LIST(mux_id, conf) , (mux_id, conf) + +/** + * @brief List of all USB muxes with config matched by compatible. List is in + * format (mux1_id, conf1) , (mux2_id, conf2) ... + */ +#define USB_MUX_LIST \ + LIST_DROP_EMPTY(USB_MUX_FOREACH_MUX_DT_VARGS(USB_MUX_TO_LIST)) /** - * @brief Call @p op with first mux in chain + * @brief Call @p op with @p args arguments * - * @param port_id USBC node ID - * @param op Operation to perform on USB mux first in chain. Needs to accept - * USB mux node ID, USBC port node ID, position in chain, and driver - * config as arguments. + * @param op Operation to perform on USB mux. Should accept mux node ID and + * driver config as arguments. + * @param args Arguments for @p op. Should be in format (mux_id, conf). */ -#define USB_MUX_FIRST(port_id, op) USB_MUX_DO(port_id, 0, op) +#define USB_MUX_CALL_OP(args, op) op args /** - * @brief Call USB_MUX_DO if @p idx is not 0 (is not first mux in chain) + * @brief Call @p op operation for each USB mux node from USB_MUX_LIST. This is + * like USB_MUX_FOREACH_MUX_DT_VARGS(), except + * DT_FOREACH_STATUS_OKAY_VARGS() macro can be used in @p op * - * @param port_id USBC node ID + * @param op Operation to perform on each USB mux. Should accept mux node ID and + * driver config as arguments. + */ +#define USB_MUX_FOREACH_MUX(op) \ + COND_CODE_0( \ + IS_EMPTY(USB_MUX_LIST), \ + (FOR_EACH_FIXED_ARG(USB_MUX_CALL_OP, (), op, USB_MUX_LIST)), \ + (EMPTY)) + +/** + * @brief Initialise chain structure for @p idx mux + * + * @param chain_id Chain DTS node ID + * @param idx USB mux index + */ +#define USB_MUX_CHAIN_STRUCT_INIT(chain_id, idx) \ + { \ + .mux = USB_MUX_POINTER(chain_id, idx), \ + .next = USB_MUX_CHAIN_NEXT_POINTER(chain_id, idx), \ + } + +/** + * @brief Helper macro to set chain structure value for @p idx mux + * + * @param chain_id Chain DTS node ID + * @param idx USB mux index + */ +#define USB_MUX_CHAIN_STRUCT_SET(chain_id, idx) \ + (struct usb_mux_chain) USB_MUX_CHAIN_STRUCT_INIT(chain_id, idx) + +/** + * @brief Declaration of USB mux chain extern structure for @p idx mux in + * @p chain_id chain + * + * @param chain_id USB mux chain node ID + * @param idx Place in chain + */ +#define USB_MUX_CHAIN_STRUCT_DECLARE_EXTERN_OP(chain_id, idx) \ + extern USB_MUX_CHAIN_STRUCT_DECLARE(USBC_PORT(chain_id), idx); + +/** + * @brief Declaration of USB mux chain structure for @p idx mux in @p chain_id + * chain + * + * @param chain_id USB mux chain node ID + * @param idx Place in chain + */ +#define USB_MUX_CHAIN_STRUCT_DECLARE_OP(chain_id, idx) \ + USB_MUX_CHAIN_STRUCT_DECLARE(USBC_PORT(chain_id), idx); + +/** + * @brief Definition of USB mux chain structure for @p idx mux in @p chain_id + * chain + * + * @param chain_id USB mux chain node ID + * @param idx Place in chain + */ +#define USB_MUX_CHAIN_STRUCT_DEFINE_OP(chain_id, idx) \ + USB_MUX_CHAIN_STRUCT_DECLARE(USBC_PORT(chain_id), idx) = \ + USB_MUX_CHAIN_STRUCT_INIT(chain_id, idx); + +/** + * @brief Call @p op if @p idx is not 0 (is not the root mux of chain) + * + * @param chain_id Chain DTS node ID * @param unused2 This argument is expected by DT_FOREACH_PROP_ELEM_VARGS * @param idx Position of USB mux in chain * @param op Operation to perform on USB muxes */ -#define USB_MUX_DO_SKIP_FIRST(port_id, unused2, idx, op) \ - COND_CODE_1(UTIL_BOOL(idx), (USB_MUX_DO(port_id, idx, op)), ()) +#define USB_MUX_SKIP_ROOT(chain_id, unused2, idx, op) \ + COND_CODE_1(UTIL_BOOL(idx), (op(chain_id, idx)), ()) /** - * @brief Call @p op with every mux in chain expect the first one + * @brief Call @p op for each mux in @p chain_id chain except the root mux * - * @param port_id USBC node ID - * @param op Operation to perform on USB muxes. Needs to accept USB mux node - * ID, USBC port node ID, position in chain, and driver config as - * arguments. + * @param chain_id Chain DTS node ID + * @param op Operation to perform on USB muxes */ -#define USB_MUX_NO_FIRST(port_id, op) \ - DT_FOREACH_PROP_ELEM_VARGS(port_id, usb_muxes, USB_MUX_DO_SKIP_FIRST, \ - op) +#define USB_MUX_FOREACH_NO_ROOT_MUX(chain_id, op) \ + DT_FOREACH_PROP_ELEM_VARGS(chain_id, usb_muxes, USB_MUX_SKIP_ROOT, op) /** - * @brief Call USB_MUX_DO if @p cb is not empty + * @brief Create usb_muxes array entry for @p chain_id chain * - * @param port_id USBC node ID - * @param mux_id USB mux node ID - * @param idx Position of USB mux in chain - * @param cb The callback name - * @param op Operation to perform on USB muxes + * @param chain_id Chain DTS node ID */ -#define USB_MUX_DO_SKIP_NO_CB(port_id, mux_id, idx, cb, op) \ - COND_CODE_0(IS_EMPTY(DT_STRING_TOKEN(mux_id, cb)), \ - (USB_MUX_DO(port_id, idx, op)), ()) +#define USB_MUX_DEFINE_ROOT_MUX(chain_id) \ + [USBC_PORT(chain_id)] = USB_MUX_CHAIN_STRUCT_INIT(chain_id, 0), /** - * @brief If usb_muxes property of @p port_id has callback property @p cb + * @brief Call @p op only if chain @p chain_id is not alternative * - * @param port_id USBC node ID - * @param cb The callback name - * @param op Operation to perform on USB muxes. Needs to accept USB mux node - * ID, USBC port node ID, position in chain, and driver config as - * arguments. + * @param chain_id Chain DTS node ID + * @param op Operation to perform on main USB mux chain + * @param ... Arguments to pass to the @p op operation */ -#define USB_MUX_HAS_CB(port_id, cb, op) \ - DT_FOREACH_PROP_ELEM_VARGS(port_id, usb_muxes, USB_MUX_DO_SKIP_NO_CB, \ - cb, op) +#define USB_MUX_FOR_MAIN_CHAIN(chain_id, op, ...) \ + COND_CODE_0(DT_PROP(chain_id, alternative_chain), \ + (op(chain_id, ##__VA_ARGS__)), ()) /** - * @brief If usb_muxes property of @p port_id has callback board_init + * @brief Call @p op for each USB mux chain * - * @param port_id USBC node ID - * @param op Operation to perform on USB muxes. Needs to accept USB mux node - * ID, USBC port node ID, position in chain, and driver config as - * arguments. + * @param op Operation to perform on USB mux chain */ -#define USB_MUX_HAS_CB_BOARD_INIT(port_id, op) \ - USB_MUX_HAS_CB(port_id, board_init, op) +#define USB_MUX_FOREACH_CHAIN(op) \ + DT_FOREACH_STATUS_OKAY(cros_ec_usb_mux_chain, op) /** - * @brief If usb_muxes property of @p port_id has callback board_set + * @brief Call @p op for each USB mux chain with arguments * - * @param port_id USBC node ID - * @param op Operation to perform on USB muxes. Needs to accept USB mux node - * ID, USBC port node ID, position in chain, and driver config as - * arguments. + * @param op Operation to perform on USB mux chain + * @param ... Arguments to pass to the @p op operation */ -#define USB_MUX_HAS_CB_BOARD_SET(port_id, op) \ - USB_MUX_HAS_CB(port_id, board_set, op) +#define USB_MUX_FOREACH_CHAIN_VARGS(op, ...) \ + DT_FOREACH_STATUS_OKAY_VARGS(cros_ec_usb_mux_chain, op, __VA_ARGS__) /** - * @brief Call @p op if @p idx mux in chain has BB retimer compatible + * @brief Construct first half of conditional expression (?:) that evaluates to + * @p chain_id USB port if @p idx mux in @p chain_id is the same as + * @p mux_id * - * @param port_id USBC node ID + * @param chain_id USB mux chain node ID * @param unused2 This argument is expected by DT_FOREACH_PROP_ELEM_VARGS * @param idx Position of USB mux in chain - * @param op Operation to perform on BB retimer + * @param mux_id USB mux node ID to compare with @p idx mux */ -#define USB_MUX_ONLY_BB_RETIMER(port_id, unused2, idx, op) \ - COND_CODE_1(USB_MUX_IS_COMPATIBLE(USB_MUX_GET_CHAIN_N(idx, port_id), \ - BB_RETIMER_USB_MUX_COMPAT), \ - (op(USB_MUX_GET_CHAIN_N(idx, port_id), port_id, idx, \ - BB_RETIMER_CONTROLS_CONFIG)), \ - ()) +#define USB_MUX_PORT_IF_SAME_NODES(chain_id, unused2, idx, mux_id) \ + DT_SAME_NODE(mux_id, USB_MUX_GET_CHAIN_N(chain_id, idx)) ? \ + USBC_PORT(chain_id): /** - * @brief Call @p op with every BB retimer in chain + * @brief Compare @p mux_id with all muxes in @p chain_id * - * @param port_id USBC node ID - * @param op Operation to perform on BB retimers. Needs to accept USB mux node - * ID, USBC port node ID, position in chain, and driver config as - * arguments. + * @param chain_id USB mux chain node ID + * @param mux_id USB mux node ID */ -#define USB_MUX_BB_RETIMERS(port_id, op) \ - DT_FOREACH_PROP_ELEM_VARGS(port_id, usb_muxes, \ - USB_MUX_ONLY_BB_RETIMER, op) +#define USB_MUX_FIND_PORT(chain_id, mux_id) \ + DT_FOREACH_PROP_ELEM_VARGS(chain_id, usb_muxes, \ + USB_MUX_PORT_IF_SAME_NODES, mux_id) + +/** + * @brief Get port for @p mux_id by looking for an usb mux chain where @p mux_id + * is present. If the mux is not present in any chain, this macro + * evaluate to -1. + * + * This expands to: + * (DT_DEP_ORD(mux_id) == DT_DEP_ORD(USB_MUX_GET_CHAIN_N(chain1_id, 0))) ? + * USBC_PORT(chain1_id) : + * (DT_DEP_ORD(mux_id) == DT_DEP_ORD(USB_MUX_GET_CHAIN_N(chain1_id, 1))) ? + * USBC_PORT(chain1_id) : + * ... + * (DT_DEP_ORD(mux_id) == DT_DEP_ORD(USB_MUX_GET_CHAIN_N(chain1_id, n))) ? + * USBC_PORT(chain1_id) : + * (DT_DEP_ORD(mux_id) == DT_DEP_ORD(USB_MUX_GET_CHAIN_N(chain2_id, 0))) ? + * USBC_PORT(chain2_id) : + * ... + * (DT_DEP_ORD(mux_id) == DT_DEP_ORD(USB_MUX_GET_CHAIN_N(chainm_id, k))) ? + * USBC_PORT(chainm_id) : (-1) + * + * @param mux_id USB mux node ID + */ +#define USB_MUX_PORT(mux_id) \ + (USB_MUX_FOREACH_CHAIN_VARGS(USB_MUX_FIND_PORT, mux_id)(-1)) /** - * @brief If @p port_id has usb_muxes property, call @p op with every mux in - * chain that passes @p filter + * @brief Set usb_mux_chain structure for mux @p idx in chain @p chain_id * - * @param port_id USBC node ID - * @param filter Macro that should filter USB muxes and call @p op on them. - * It has @p port_id and @p op as arguments. It is called - * only for @p port_id that has usb_muxes property. - * @param op Operation to perform on USB muxes. Needs to accept USB mux node - * ID, USBC port node ID, position in chain, and driver config as - * arguments. + * @param chain_id Alternative USB mux chain node ID + * @param idx Position of the mux in chain */ -#define USB_MUX_USBC_PORT_HAS_MUXES(port_id, filter, op) \ - COND_CODE_1(DT_NODE_HAS_PROP(port_id, usb_muxes), \ - (filter(port_id, op)), ()) +#define USB_MUX_SET_ALTERNATIVE(chain_id, idx) \ + USB_MUX_CHAIN_STRUCT_NAME(idx, USBC_PORT(chain_id)) = \ + USB_MUX_CHAIN_STRUCT_SET(chain_id, idx); /** - * @brief For every USBC port that has muxes, call @p op with every mux in chain - * that passes @p filter + * @brief Enable alternative USB mux chain * - * @param filter Macro that should filter USB muxes and call @p op on them. - * It has USBC port node ID and @p op as arguments. It is called - * only for USBC ports that have usb_muxes property. - * @param op Operation to perform on USB muxes. Needs to accept USB mux node - * ID, USBC port node ID, position in chain, and driver config as - * arguments. + * @param chain_id Alternative USB mux chain node ID */ -#define USB_MUX_FOREACH_USBC_PORT(filter, op) \ - DT_FOREACH_STATUS_OKAY_VARGS(named_usbc_port, \ - USB_MUX_USBC_PORT_HAS_MUXES, filter, op) +#define USB_MUX_ENABLE_ALTERNATIVE_NODE(chain_id) \ + do { \ + usb_muxes[USBC_PORT(chain_id)] = \ + USB_MUX_CHAIN_STRUCT_SET(chain_id, 0); \ + USB_MUX_FOREACH_NO_ROOT_MUX(chain_id, USB_MUX_SET_ALTERNATIVE) \ + } while (0) + +/** + * @brief Enable alternative USB mux chain + * + * @param nodelabel Label of alternative USB mux chain + */ +#define USB_MUX_ENABLE_ALTERNATIVE(nodelabel) \ + USB_MUX_ENABLE_ALTERNATIVE_NODE(DT_NODELABEL(nodelabel)) /** * Forward declare all usb_mux structures e.g. * MAYBE_CONST struct usb_mux USB_MUX_NODE_<node_id>; */ -USB_MUX_FOREACH_USBC_PORT(USB_MUX_NO_FIRST, USB_MUX_DECLARE) +USB_MUX_FOREACH_MUX(USB_MUX_DECLARE) + +/** + * Forward declare all usb_mux_chain structures e.g. + * extern MAYBE_CONST struct usb_mux_chain + * USB_MUX_chain_port_<node_id>_mux_<position_id>; + */ +USB_MUX_FOREACH_CHAIN_VARGS(USB_MUX_FOREACH_NO_ROOT_MUX, + USB_MUX_CHAIN_STRUCT_DECLARE_EXTERN_OP) #endif /* ZEPHYR_CHROME_USBC_USB_MUXES_H */ |