projects/linux·blob master · refs

180 lines · 5.3 KiB

1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright(c) 2023-2024 Intel Corporation
4 *
5 * Authors: Cezary Rojewski <[email protected]>
6 * Amadeusz Slawinski <[email protected]>
7 */
8
9#ifndef __ACPI_NHLT_H__
10#define __ACPI_NHLT_H__
11
12#include <linux/acpi.h>
13#include <linux/overflow.h>
14#include <linux/types.h>
15
16#define __acpi_nhlt_endpoint_config(ep) ((void *)((ep) + 1))
17#define __acpi_nhlt_config_caps(cfg) ((void *)((cfg) + 1))
18
19/**
20 * acpi_nhlt_endpoint_fmtscfg - Get the formats configuration space.
21 * @ep: the endpoint to retrieve the space for.
22 *
23 * Return: A pointer to the formats configuration space.
24 */
25static inline struct acpi_nhlt_formats_config *
26acpi_nhlt_endpoint_fmtscfg(const struct acpi_nhlt_endpoint *ep)
27{
28 struct acpi_nhlt_config *cfg = __acpi_nhlt_endpoint_config(ep);
29
30 return (struct acpi_nhlt_formats_config *)((u8 *)(cfg + 1) + cfg->capabilities_size);
31}
32
33#define __acpi_nhlt_first_endpoint(tb) \
34 ((void *)(tb + 1))
35
36#define __acpi_nhlt_next_endpoint(ep) \
37 ((void *)((u8 *)(ep) + (ep)->length))
38
39#define __acpi_nhlt_get_endpoint(tb, ep, i) \
40 ((i) ? __acpi_nhlt_next_endpoint(ep) : __acpi_nhlt_first_endpoint(tb))
41
42#define __acpi_nhlt_first_fmtcfg(fmts) \
43 ((void *)(fmts + 1))
44
45#define __acpi_nhlt_next_fmtcfg(fmt) \
46 ((void *)((u8 *)((fmt) + 1) + (fmt)->config.capabilities_size))
47
48#define __acpi_nhlt_get_fmtcfg(fmts, fmt, i) \
49 ((i) ? __acpi_nhlt_next_fmtcfg(fmt) : __acpi_nhlt_first_fmtcfg(fmts))
50
51/*
52 * The for_each_nhlt_*() macros rely on an iterator to deal with the
53 * variable length of each endpoint structure and the possible presence
54 * of an OED-Config used by Windows only.
55 */
56
57/**
58 * for_each_nhlt_endpoint - Iterate over endpoints in a NHLT table.
59 * @tb: the pointer to a NHLT table.
60 * @ep: the pointer to endpoint to use as loop cursor.
61 */
62#define for_each_nhlt_endpoint(tb, ep) \
63 for (unsigned int __i = 0; \
64 __i < (tb)->endpoints_count && \
65 (ep = __acpi_nhlt_get_endpoint(tb, ep, __i)); \
66 __i++)
67
68/**
69 * for_each_nhlt_fmtcfg - Iterate over format configurations.
70 * @fmts: the pointer to formats configuration space.
71 * @fmt: the pointer to format to use as loop cursor.
72 */
73#define for_each_nhlt_fmtcfg(fmts, fmt) \
74 for (unsigned int __i = 0; \
75 __i < (fmts)->formats_count && \
76 (fmt = __acpi_nhlt_get_fmtcfg(fmts, fmt, __i)); \
77 __i++)
78
79/**
80 * for_each_nhlt_endpoint_fmtcfg - Iterate over format configurations in an endpoint.
81 * @ep: the pointer to an endpoint.
82 * @fmt: the pointer to format to use as loop cursor.
83 */
84#define for_each_nhlt_endpoint_fmtcfg(ep, fmt) \
85 for_each_nhlt_fmtcfg(acpi_nhlt_endpoint_fmtscfg(ep), fmt)
86
87#if IS_ENABLED(CONFIG_ACPI_NHLT)
88
89/*
90 * System-wide pointer to the first NHLT table.
91 *
92 * A sound driver may utilize acpi_nhlt_get/put_gbl_table() on its
93 * initialization and removal respectively to avoid excessive mapping
94 * and unmapping of the memory occupied by the table between streaming
95 * operations.
96 */
97
98acpi_status acpi_nhlt_get_gbl_table(void);
99void acpi_nhlt_put_gbl_table(void);
100
101bool acpi_nhlt_endpoint_match(const struct acpi_nhlt_endpoint *ep,
102 int link_type, int dev_type, int dir, int bus_id);
103struct acpi_nhlt_endpoint *
104acpi_nhlt_tb_find_endpoint(const struct acpi_table_nhlt *tb,
105 int link_type, int dev_type, int dir, int bus_id);
106struct acpi_nhlt_endpoint *
107acpi_nhlt_find_endpoint(int link_type, int dev_type, int dir, int bus_id);
108struct acpi_nhlt_format_config *
109acpi_nhlt_endpoint_find_fmtcfg(const struct acpi_nhlt_endpoint *ep,
110 u16 ch, u32 rate, u16 vbps, u16 bps);
111struct acpi_nhlt_format_config *
112acpi_nhlt_tb_find_fmtcfg(const struct acpi_table_nhlt *tb,
113 int link_type, int dev_type, int dir, int bus_id,
114 u16 ch, u32 rate, u16 vpbs, u16 bps);
115struct acpi_nhlt_format_config *
116acpi_nhlt_find_fmtcfg(int link_type, int dev_type, int dir, int bus_id,
117 u16 ch, u32 rate, u16 vpbs, u16 bps);
118int acpi_nhlt_endpoint_mic_count(const struct acpi_nhlt_endpoint *ep);
119
120#else /* !CONFIG_ACPI_NHLT */
121
122static inline acpi_status acpi_nhlt_get_gbl_table(void)
123{
124 return AE_NOT_FOUND;
125}
126
127static inline void acpi_nhlt_put_gbl_table(void)
128{
129}
130
131static inline bool
132acpi_nhlt_endpoint_match(const struct acpi_nhlt_endpoint *ep,
133 int link_type, int dev_type, int dir, int bus_id)
134{
135 return false;
136}
137
138static inline struct acpi_nhlt_endpoint *
139acpi_nhlt_tb_find_endpoint(const struct acpi_table_nhlt *tb,
140 int link_type, int dev_type, int dir, int bus_id)
141{
142 return NULL;
143}
144
145static inline struct acpi_nhlt_format_config *
146acpi_nhlt_endpoint_find_fmtcfg(const struct acpi_nhlt_endpoint *ep,
147 u16 ch, u32 rate, u16 vbps, u16 bps)
148{
149 return NULL;
150}
151
152static inline struct acpi_nhlt_format_config *
153acpi_nhlt_tb_find_fmtcfg(const struct acpi_table_nhlt *tb,
154 int link_type, int dev_type, int dir, int bus_id,
155 u16 ch, u32 rate, u16 vpbs, u16 bps)
156{
157 return NULL;
158}
159
160static inline int acpi_nhlt_endpoint_mic_count(const struct acpi_nhlt_endpoint *ep)
161{
162 return 0;
163}
164
165static inline struct acpi_nhlt_endpoint *
166acpi_nhlt_find_endpoint(int link_type, int dev_type, int dir, int bus_id)
167{
168 return NULL;
169}
170
171static inline struct acpi_nhlt_format_config *
172acpi_nhlt_find_fmtcfg(int link_type, int dev_type, int dir, int bus_id,
173 u16 ch, u32 rate, u16 vpbs, u16 bps)
174{
175 return NULL;
176}
177
178#endif /* CONFIG_ACPI_NHLT */
179
180#endif /* __ACPI_NHLT_H__ */