/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright(c) 2023-2024 Intel Corporation * * Authors: Cezary Rojewski * Amadeusz Slawinski */ #ifndef __ACPI_NHLT_H__ #define __ACPI_NHLT_H__ #include #include #include #include #define __acpi_nhlt_endpoint_config(ep) ((void *)((ep) + 1)) #define __acpi_nhlt_config_caps(cfg) ((void *)((cfg) + 1)) /** * acpi_nhlt_endpoint_fmtscfg - Get the formats configuration space. * @ep: the endpoint to retrieve the space for. * * Return: A pointer to the formats configuration space. */ static inline struct acpi_nhlt_formats_config * acpi_nhlt_endpoint_fmtscfg(const struct acpi_nhlt_endpoint *ep) { struct acpi_nhlt_config *cfg = __acpi_nhlt_endpoint_config(ep); return (struct acpi_nhlt_formats_config *)((u8 *)(cfg + 1) + cfg->capabilities_size); } #define __acpi_nhlt_first_endpoint(tb) \ ((void *)(tb + 1)) #define __acpi_nhlt_next_endpoint(ep) \ ((void *)((u8 *)(ep) + (ep)->length)) #define __acpi_nhlt_get_endpoint(tb, ep, i) \ ((i) ? __acpi_nhlt_next_endpoint(ep) : __acpi_nhlt_first_endpoint(tb)) #define __acpi_nhlt_first_fmtcfg(fmts) \ ((void *)(fmts + 1)) #define __acpi_nhlt_next_fmtcfg(fmt) \ ((void *)((u8 *)((fmt) + 1) + (fmt)->config.capabilities_size)) #define __acpi_nhlt_get_fmtcfg(fmts, fmt, i) \ ((i) ? __acpi_nhlt_next_fmtcfg(fmt) : __acpi_nhlt_first_fmtcfg(fmts)) /* * The for_each_nhlt_*() macros rely on an iterator to deal with the * variable length of each endpoint structure and the possible presence * of an OED-Config used by Windows only. */ /** * for_each_nhlt_endpoint - Iterate over endpoints in a NHLT table. * @tb: the pointer to a NHLT table. * @ep: the pointer to endpoint to use as loop cursor. */ #define for_each_nhlt_endpoint(tb, ep) \ for (unsigned int __i = 0; \ __i < (tb)->endpoints_count && \ (ep = __acpi_nhlt_get_endpoint(tb, ep, __i)); \ __i++) /** * for_each_nhlt_fmtcfg - Iterate over format configurations. * @fmts: the pointer to formats configuration space. * @fmt: the pointer to format to use as loop cursor. */ #define for_each_nhlt_fmtcfg(fmts, fmt) \ for (unsigned int __i = 0; \ __i < (fmts)->formats_count && \ (fmt = __acpi_nhlt_get_fmtcfg(fmts, fmt, __i)); \ __i++) /** * for_each_nhlt_endpoint_fmtcfg - Iterate over format configurations in an endpoint. * @ep: the pointer to an endpoint. * @fmt: the pointer to format to use as loop cursor. */ #define for_each_nhlt_endpoint_fmtcfg(ep, fmt) \ for_each_nhlt_fmtcfg(acpi_nhlt_endpoint_fmtscfg(ep), fmt) #if IS_ENABLED(CONFIG_ACPI_NHLT) /* * System-wide pointer to the first NHLT table. * * A sound driver may utilize acpi_nhlt_get/put_gbl_table() on its * initialization and removal respectively to avoid excessive mapping * and unmapping of the memory occupied by the table between streaming * operations. */ acpi_status acpi_nhlt_get_gbl_table(void); void acpi_nhlt_put_gbl_table(void); bool acpi_nhlt_endpoint_match(const struct acpi_nhlt_endpoint *ep, int link_type, int dev_type, int dir, int bus_id); struct acpi_nhlt_endpoint * acpi_nhlt_tb_find_endpoint(const struct acpi_table_nhlt *tb, int link_type, int dev_type, int dir, int bus_id); struct acpi_nhlt_endpoint * acpi_nhlt_find_endpoint(int link_type, int dev_type, int dir, int bus_id); struct acpi_nhlt_format_config * acpi_nhlt_endpoint_find_fmtcfg(const struct acpi_nhlt_endpoint *ep, u16 ch, u32 rate, u16 vbps, u16 bps); struct acpi_nhlt_format_config * acpi_nhlt_tb_find_fmtcfg(const struct acpi_table_nhlt *tb, int link_type, int dev_type, int dir, int bus_id, u16 ch, u32 rate, u16 vpbs, u16 bps); struct acpi_nhlt_format_config * acpi_nhlt_find_fmtcfg(int link_type, int dev_type, int dir, int bus_id, u16 ch, u32 rate, u16 vpbs, u16 bps); int acpi_nhlt_endpoint_mic_count(const struct acpi_nhlt_endpoint *ep); #else /* !CONFIG_ACPI_NHLT */ static inline acpi_status acpi_nhlt_get_gbl_table(void) { return AE_NOT_FOUND; } static inline void acpi_nhlt_put_gbl_table(void) { } static inline bool acpi_nhlt_endpoint_match(const struct acpi_nhlt_endpoint *ep, int link_type, int dev_type, int dir, int bus_id) { return false; } static inline struct acpi_nhlt_endpoint * acpi_nhlt_tb_find_endpoint(const struct acpi_table_nhlt *tb, int link_type, int dev_type, int dir, int bus_id) { return NULL; } static inline struct acpi_nhlt_format_config * acpi_nhlt_endpoint_find_fmtcfg(const struct acpi_nhlt_endpoint *ep, u16 ch, u32 rate, u16 vbps, u16 bps) { return NULL; } static inline struct acpi_nhlt_format_config * acpi_nhlt_tb_find_fmtcfg(const struct acpi_table_nhlt *tb, int link_type, int dev_type, int dir, int bus_id, u16 ch, u32 rate, u16 vpbs, u16 bps) { return NULL; } static inline int acpi_nhlt_endpoint_mic_count(const struct acpi_nhlt_endpoint *ep) { return 0; } static inline struct acpi_nhlt_endpoint * acpi_nhlt_find_endpoint(int link_type, int dev_type, int dir, int bus_id) { return NULL; } static inline struct acpi_nhlt_format_config * acpi_nhlt_find_fmtcfg(int link_type, int dev_type, int dir, int bus_id, u16 ch, u32 rate, u16 vpbs, u16 bps) { return NULL; } #endif /* CONFIG_ACPI_NHLT */ #endif /* __ACPI_NHLT_H__ */