1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
/* 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__ */
|