From d7c9533c72568e83af1282254361413c7304fddf Mon Sep 17 00:00:00 2001 From: Josuah Demangeon Date: Fri, 18 Oct 2024 09:38:18 +0000 Subject: [PATCH] devicetree: add macros to deal with endpoints Add macros to access the port/endpoint constructs from drivers and application. Devicetrees currently use "port { endpoint { ... }; };" to describe interconnection between devices. With introduction of the "remote-endpoint-label = string" syntax, it is now possible to describe circular dependencies until #57708 is addressed. Signed-off-by: Josuah Demangeon --- include/zephyr/devicetree.h | 86 +++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index aba28c0ab63255..dc1f543359b4e1 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -3787,6 +3787,92 @@ */ #define DT_ON_BUS(node_id, bus) IS_ENABLED(DT_CAT3(node_id, _BUS_, bus)) +/** + * @} + */ + +/** + * @defgroup devicetree-generic-endpoint Endpoint helpers + * @ingroup devicetree + * @{ + */ + +/** + * @brief Get the remote endpoint node connected to a local endpoint. + * + * Some devices, such as video devices, can be interconnected through port and endpoints. + * + * For a selected node's endpoint, the remote endpoint connected to it can be access through + * @ref DT_REMOTE_ENDPOINT(). + * This remote endpoint node can then be accessed using other macros to read its properties. + * + * Example devicetree overlay: + * + * @code{.dts} + * &sink { + * port { + * sink_in: endpoint@123 { + * remote-endpoint-label = "source_out"; + * }; + * }; + * }; + * + * &source { + * port { + * source_out: endpoint { + * remote-endpoint-label = "sink_in"; + * }; + * }; + * }; + * @endcode + * + * Example usage: starting from the sink, access the source endpoint connected to @c endpoint@123: + * + * @code{.c} + * DT_REMOTE_ENDPOINT(DT_NODELABEL(sink_in), port, endpoint_123) + * @endcode + * + * Example usage, starting from the source, to access the sink endpoint connected to @c endpoint: + * + * @code{.c} + * DT_REMOTE_ENDPOINT(DT_NODELABEL(source_out), port, endpoint) + * @endcode + * + * @note Once circular phandle references are supported, @c remote-endpoint-label (string) may be + * changed into @c remote-endpoint (phandle). + * + * @param node The local node. + * @param port The port to search. + * @param ep The endpoint to search. + * + * @return The remote node of the endpoint connected to @p port, @p ep. + */ +#define DT_REMOTE_ENDPOINT(node, port, ep) \ + DT_NODELABEL(DT_STRING_TOKEN(DT_CHILD(DT_CHILD(node, port), ep), remote_endpoint_label)) + +/** + * @brief Get the remote device node connected to a local endpoint. + * + * For a given node, return the remote endpoint node connected to the specified port and endpoint. + * This permit accessing the remote device properties. + * + * Example usage, starting from the sink, to access the source device connected to @c endpoint@123: + * + * @code{.c} + * DT_REMOTE_ENDPOINT(DT_NODELABEL(sink_in), port, endpoint_123) + * @endcode + * + * @note Once circular phandle references are supported, @c remote-endpoint-label (string) may be + * changed into @c remote-endpoint (phandle). + * + * @param node The local node. + * @param port The port to search. + * @param ep The endpoint to search. + * + * @return The remote node of the device connected to @p port, @p ep. + */ +#define DT_REMOTE_DEVICE(node, port, ep) DT_GPARENT(DT_REMOTE_ENDPOINT(node, port, ep)) + /** * @} */