| /* SPDX-License-Identifier: GPL-2.0-only */ | |
| /* | |
| * Copyright(c) 2023-2024 Intel Corporation | |
| * | |
| * Authors: Cezary Rojewski <cezary.rojewski@intel.com> | |
| * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com> | |
| */ | |
| #ifndef __ACPI_NHLT_H__ | |
| #define __ACPI_NHLT_H__ | |
| #include <linux/acpi.h> | |
| #include <linux/overflow.h> | |
| #include <linux/types.h> | |
| #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__ */ |