182 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			182 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* 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/kconfig.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__ */
 |