1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright(c) 2023-2024 Intel Corporation
5 * Authors: Cezary Rojewski <cezary.rojewski@intel.com>
6 * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
9 #ifndef __ACPI_NHLT_H__
10 #define __ACPI_NHLT_H__
12 #include <linux/acpi.h>
13 #include <linux/kconfig.h>
14 #include <linux/overflow.h>
15 #include <linux/types.h>
17 #define __acpi_nhlt_endpoint_config(ep) ((void *)((ep) + 1))
18 #define __acpi_nhlt_config_caps(cfg) ((void *)((cfg) + 1))
21 * acpi_nhlt_endpoint_fmtscfg - Get the formats configuration space.
22 * @ep: the endpoint to retrieve the space for.
24 * Return: A pointer to the formats configuration space.
26 static inline struct acpi_nhlt_formats_config
*
27 acpi_nhlt_endpoint_fmtscfg(const struct acpi_nhlt_endpoint
*ep
)
29 struct acpi_nhlt_config
*cfg
= __acpi_nhlt_endpoint_config(ep
);
31 return (struct acpi_nhlt_formats_config
*)((u8
*)(cfg
+ 1) + cfg
->capabilities_size
);
34 #define __acpi_nhlt_first_endpoint(tb) \
37 #define __acpi_nhlt_next_endpoint(ep) \
38 ((void *)((u8 *)(ep) + (ep)->length))
40 #define __acpi_nhlt_get_endpoint(tb, ep, i) \
41 ((i) ? __acpi_nhlt_next_endpoint(ep) : __acpi_nhlt_first_endpoint(tb))
43 #define __acpi_nhlt_first_fmtcfg(fmts) \
46 #define __acpi_nhlt_next_fmtcfg(fmt) \
47 ((void *)((u8 *)((fmt) + 1) + (fmt)->config.capabilities_size))
49 #define __acpi_nhlt_get_fmtcfg(fmts, fmt, i) \
50 ((i) ? __acpi_nhlt_next_fmtcfg(fmt) : __acpi_nhlt_first_fmtcfg(fmts))
53 * The for_each_nhlt_*() macros rely on an iterator to deal with the
54 * variable length of each endpoint structure and the possible presence
55 * of an OED-Config used by Windows only.
59 * for_each_nhlt_endpoint - Iterate over endpoints in a NHLT table.
60 * @tb: the pointer to a NHLT table.
61 * @ep: the pointer to endpoint to use as loop cursor.
63 #define for_each_nhlt_endpoint(tb, ep) \
64 for (unsigned int __i = 0; \
65 __i < (tb)->endpoints_count && \
66 (ep = __acpi_nhlt_get_endpoint(tb, ep, __i)); \
70 * for_each_nhlt_fmtcfg - Iterate over format configurations.
71 * @fmts: the pointer to formats configuration space.
72 * @fmt: the pointer to format to use as loop cursor.
74 #define for_each_nhlt_fmtcfg(fmts, fmt) \
75 for (unsigned int __i = 0; \
76 __i < (fmts)->formats_count && \
77 (fmt = __acpi_nhlt_get_fmtcfg(fmts, fmt, __i)); \
81 * for_each_nhlt_endpoint_fmtcfg - Iterate over format configurations in an endpoint.
82 * @ep: the pointer to an endpoint.
83 * @fmt: the pointer to format to use as loop cursor.
85 #define for_each_nhlt_endpoint_fmtcfg(ep, fmt) \
86 for_each_nhlt_fmtcfg(acpi_nhlt_endpoint_fmtscfg(ep), fmt)
88 #if IS_ENABLED(CONFIG_ACPI_NHLT)
91 * System-wide pointer to the first NHLT table.
93 * A sound driver may utilize acpi_nhlt_get/put_gbl_table() on its
94 * initialization and removal respectively to avoid excessive mapping
95 * and unmapping of the memory occupied by the table between streaming
99 acpi_status
acpi_nhlt_get_gbl_table(void);
100 void acpi_nhlt_put_gbl_table(void);
102 bool acpi_nhlt_endpoint_match(const struct acpi_nhlt_endpoint
*ep
,
103 int link_type
, int dev_type
, int dir
, int bus_id
);
104 struct acpi_nhlt_endpoint
*
105 acpi_nhlt_tb_find_endpoint(const struct acpi_table_nhlt
*tb
,
106 int link_type
, int dev_type
, int dir
, int bus_id
);
107 struct acpi_nhlt_endpoint
*
108 acpi_nhlt_find_endpoint(int link_type
, int dev_type
, int dir
, int bus_id
);
109 struct acpi_nhlt_format_config
*
110 acpi_nhlt_endpoint_find_fmtcfg(const struct acpi_nhlt_endpoint
*ep
,
111 u16 ch
, u32 rate
, u16 vbps
, u16 bps
);
112 struct acpi_nhlt_format_config
*
113 acpi_nhlt_tb_find_fmtcfg(const struct acpi_table_nhlt
*tb
,
114 int link_type
, int dev_type
, int dir
, int bus_id
,
115 u16 ch
, u32 rate
, u16 vpbs
, u16 bps
);
116 struct acpi_nhlt_format_config
*
117 acpi_nhlt_find_fmtcfg(int link_type
, int dev_type
, int dir
, int bus_id
,
118 u16 ch
, u32 rate
, u16 vpbs
, u16 bps
);
119 int acpi_nhlt_endpoint_mic_count(const struct acpi_nhlt_endpoint
*ep
);
121 #else /* !CONFIG_ACPI_NHLT */
123 static inline acpi_status
acpi_nhlt_get_gbl_table(void)
128 static inline void acpi_nhlt_put_gbl_table(void)
133 acpi_nhlt_endpoint_match(const struct acpi_nhlt_endpoint
*ep
,
134 int link_type
, int dev_type
, int dir
, int bus_id
)
139 static inline struct acpi_nhlt_endpoint
*
140 acpi_nhlt_tb_find_endpoint(const struct acpi_table_nhlt
*tb
,
141 int link_type
, int dev_type
, int dir
, int bus_id
)
146 static inline struct acpi_nhlt_format_config
*
147 acpi_nhlt_endpoint_find_fmtcfg(const struct acpi_nhlt_endpoint
*ep
,
148 u16 ch
, u32 rate
, u16 vbps
, u16 bps
)
153 static inline struct acpi_nhlt_format_config
*
154 acpi_nhlt_tb_find_fmtcfg(const struct acpi_table_nhlt
*tb
,
155 int link_type
, int dev_type
, int dir
, int bus_id
,
156 u16 ch
, u32 rate
, u16 vpbs
, u16 bps
)
161 static inline int acpi_nhlt_endpoint_mic_count(const struct acpi_nhlt_endpoint
*ep
)
166 static inline struct acpi_nhlt_endpoint
*
167 acpi_nhlt_find_endpoint(int link_type
, int dev_type
, int dir
, int bus_id
)
172 static inline struct acpi_nhlt_format_config
*
173 acpi_nhlt_find_fmtcfg(int link_type
, int dev_type
, int dir
, int bus_id
,
174 u16 ch
, u32 rate
, u16 vpbs
, u16 bps
)
179 #endif /* CONFIG_ACPI_NHLT */
181 #endif /* __ACPI_NHLT_H__ */