blob: 47203213818ff59d1a9fd0454869a340416b11f4 [file] [log] [blame]
Simon Glassf6cdb912020-07-07 21:32:16 -06001/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright 2020 Google LLC
4 *
5 * Modified from coreboot nhlt.h
6 */
7
8#ifndef _NHLT_H_
9#define _NHLT_H_
10
11struct acpi_ctx;
12struct nhlt;
13struct nhlt_endpoint;
14struct nhlt_format;
15struct nhlt_format_config;
16
17/*
18 * Non HD Audio ACPI support. This table is typically used for Intel Smart
19 * Sound Technology DSP. It provides a way to encode opaque settings in
20 * the ACPI tables.
21 *
22 * While the structure fields of the NHLT structs are exposed below
23 * the SoC/chipset code should be the only other user manipulating the
24 * fields directly aside from the library itself.
25 *
26 * The NHLT table consists of endpoints which in turn contain different
27 * supporting stream formats. Each endpoint may contain a device specific
28 * configuration payload as well as each stream format.
29 *
30 * Most code should use the SoC variants of the functions because
31 * there is required logic needed to be performed by the SoC. The SoC
32 * code should be abstracting the inner details of these functions that
33 * specically apply to NHLT objects for that SoC.
34 *
35 * An example sequence:
36 *
37 * nhlt = nhlt_init()
38 * ep = nhlt_add_endpoint()
39 * nhlt_endpoint_append_config(ep)
40 * nhlt_endpoint_add_formats(ep)
41 * nhlt_soc_serialise()
42 */
43
44/* Obtain an nhlt object for adding endpoints. Returns NULL on error. */
45struct nhlt *nhlt_init(void);
46
47/* Return the size of the NHLT table including ACPI header. */
48size_t nhlt_current_size(struct nhlt *nhlt);
49
50/*
51 * Helper functions for adding NHLT devices utilizing an nhlt_endp_descriptor
52 * to drive the logic.
53 */
54
55struct nhlt_endp_descriptor {
56 /* NHLT endpoint types. */
57 int link;
58 int device;
59 int direction;
60 u16 vid;
61 u16 did;
62 /* Optional endpoint specific configuration data. */
63 const void *cfg;
64 size_t cfg_size;
65 /* Formats supported for endpoint. */
66 const struct nhlt_format_config *formats;
67 size_t num_formats;
68};
69
70/*
71 * Add the number of endpoints described by each descriptor. The virtual bus
72 * id for each descriptor is the default value of 0.
73 * Returns < 0 on error, 0 on success.
74 */
75int nhlt_add_endpoints(struct nhlt *nhlt,
76 const struct nhlt_endp_descriptor *epds,
77 size_t num_epds);
78
79/*
80 * Add the number of endpoints associated with a single NHLT SSP instance id.
81 * Each endpoint described in the endpoint descriptor array uses the provided
82 * virtual bus id. Returns < 0 on error, 0 on success.
83 */
84int nhlt_add_ssp_endpoints(struct nhlt *nhlt, int virtual_bus_id,
85 const struct nhlt_endp_descriptor *epds,
86 size_t num_epds);
87
88/*
89 * Add endpoint to NHLT object. Returns NULL on error.
90 *
91 * generic nhlt_add_endpoint() is called by the SoC code to provide
92 * the specific assumptions/uses for NHLT for that platform. All fields
93 * are the NHLT enumerations found within this header file.
94 */
95struct nhlt_endpoint *nhlt_add_endpoint(struct nhlt *nhlt, int link_type,
96 int device_type, int dir,
97 u16 vid, u16 did);
98
99/*
100 * Append blob of configuration to the endpoint proper. Returns 0 on
101 * success, < 0 on error. A copy of the configuration is made so any
102 * resources pointed to by config can be freed after the call.
103 */
104int nhlt_endpoint_append_config(struct nhlt_endpoint *endpoint,
105 const void *config, size_t config_sz);
106
107/* Add a format type to the provided endpoint. Returns NULL on error. */
108struct nhlt_format *nhlt_add_format(struct nhlt_endpoint *endpoint,
109 int num_channels, int sample_freq_khz,
110 int container_bits_per_sample,
111 int valid_bits_per_sample,
112 u32 speaker_mask);
113
114/*
115 * Append blob of configuration to the format proper. Returns 0 on
116 * success, < 0 on error. A copy of the configuration is made so any
117 * resources pointed to by config can be freed after the call.
118 */
119int nhlt_format_append_config(struct nhlt_format *format, const void *config,
120 size_t config_sz);
121
122/*
123 * Add num_formats described by formats to the endpoint. This function
124 * effectively wraps nhlt_add_format() and nhlt_format_config() using the
125 * data found in each nhlt_format_config object. Returns 0 on success, < 0
126 * on error.
127 */
128int nhlt_endpoint_add_formats(struct nhlt_endpoint *endpoint,
129 const struct nhlt_format_config *formats,
130 size_t num_formats);
131
132/*
133 * Increment the instance id for a given link type. This function is
134 * used for marking a device being completely added to the NHLT object.
135 * Subsequent endpoints added to the nhlt object with the same link type
136 * will use incremented instance id.
137 */
138void nhlt_next_instance(struct nhlt *nhlt, int link_type);
139
140/*
141 * Serialize NHLT object to ACPI table. Take in the beginning address of where
142 * the table will reside and return the address of the next ACPI table. On
143 * error 0 will be returned. The NHLT object is no longer valid after this
144 * function is called.
145 */
146uintptr_t nhlt_serialise(struct nhlt *nhlt, uintptr_t acpi_addr);
147
148/*
149 * Serialize NHLT object to ACPI table. Take in the beginning address of where
150 * the table will reside oem_id and oem_table_id and return the address of the
151 * next ACPI table. On error 0 will be returned. The NHLT object is no longer
152 * valid after this function is called.
153 */
154int nhlt_serialise_oem_overrides(struct acpi_ctx *ctx, struct nhlt *nhlt,
155 const char *oem_id, const char *oem_table_id,
156 u32 oem_revision);
157
158int nhlt_setup(struct nhlt *nhlt, ofnode node);
159
160/* Link and device types. */
161enum {
162 NHLT_LINK_HDA,
163 NHLT_LINK_DSP,
164 NHLT_LINK_PDM,
165 NHLT_LINK_SSP,
166 NHLT_MAX_LINK_TYPES,
167};
168
169enum {
170 NHLT_SSP_DEV_BT, /* Bluetooth */
171 NHLT_SSP_DEV_MODEM,
172 NHLT_SSP_DEV_FM,
173 NHLT_SSP_DEV_RESERVED,
174 NHLT_SSP_DEV_I2S = 4,
175};
176
177enum {
178 NHLT_PDM_DEV,
179};
180
181/* Endpoint direction. */
182enum {
183 NHLT_DIR_RENDER,
184 NHLT_DIR_CAPTURE,
185 NHLT_DIR_BIDIRECTIONAL,
186};
187
188/*
189 * Channel mask for an endpoint. While they are prefixed with 'SPEAKER' the
190 * channel masks are also used for capture devices
191 */
192enum {
193 SPEAKER_FRONT_LEFT = BIT(0),
194 SPEAKER_FRONT_RIGHT = BIT(1),
195 SPEAKER_FRONT_CENTER = BIT(2),
196 SPEAKER_LOW_FREQUENCY = BIT(3),
197 SPEAKER_BACK_LEFT = BIT(4),
198 SPEAKER_BACK_RIGHT = BIT(5),
199 SPEAKER_FRONT_LEFT_OF_CENTER = BIT(6),
200 SPEAKER_FRONT_RIGHT_OF_CENTER = BIT(7),
201 SPEAKER_BACK_CENTER = BIT(8),
202 SPEAKER_SIDE_LEFT = BIT(9),
203 SPEAKER_SIDE_RIGHT = BIT(10),
204 SPEAKER_TOP_CENTER = BIT(11),
205 SPEAKER_TOP_FRONT_LEFT = BIT(12),
206 SPEAKER_TOP_FRONT_CENTER = BIT(13),
207 SPEAKER_TOP_FRONT_RIGHT = BIT(14),
208 SPEAKER_TOP_BACK_LEFT = BIT(15),
209 SPEAKER_TOP_BACK_CENTER = BIT(16),
210 SPEAKER_TOP_BACK_RIGHT = BIT(17),
211};
212
213/*
214 * Supporting structures. Only SoC/chipset and the library code directly should
215 * be manipulating these structures
216 */
217struct sub_format {
218 u32 data1;
219 u16 data2;
220 u16 data3;
221 u8 data4[8];
222};
223
224struct nhlt_specific_config {
225 u32 size;
226 void *capabilities;
227};
228
229struct nhlt_waveform {
230 u16 tag;
231 u16 num_channels;
232 u32 samples_per_second;
233 u32 bytes_per_second;
234 u16 block_align;
235 u16 bits_per_sample;
236 u16 extra_size;
237 u16 valid_bits_per_sample;
238 u32 channel_mask;
239 struct sub_format sub_format;
240};
241
242struct nhlt_format {
243 struct nhlt_waveform waveform;
244 struct nhlt_specific_config config;
245};
246
247/*
248 * This struct is used by nhlt_endpoint_add_formats() for easily adding
249 * waveform formats with associated settings file.
250 */
251struct nhlt_format_config {
252 int num_channels;
253 int sample_freq_khz;
254 int container_bits_per_sample;
255 int valid_bits_per_sample;
256 u32 speaker_mask;
257 const char *settings_file;
258};
259
260/* Arbitrary max number of formats per endpoint. */
261#define MAX_FORMATS 2
262struct nhlt_endpoint {
263 u32 length;
264 u8 link_type;
265 u8 instance_id;
266 u16 vendor_id;
267 u16 device_id;
268 u16 revision_id;
269 u32 subsystem_id;
270 u8 device_type;
271 u8 direction;
272 u8 virtual_bus_id;
273 struct nhlt_specific_config config;
274 u8 num_formats;
275 struct nhlt_format formats[MAX_FORMATS];
276};
277
278#define MAX_ENDPOINTS 8
279struct nhlt {
280 u32 subsystem_id;
281 u8 num_endpoints;
282 struct nhlt_endpoint endpoints[MAX_ENDPOINTS];
283 u8 current_instance_id[NHLT_MAX_LINK_TYPES];
284};
285
286struct nhlt_tdm_config {
287 u8 virtual_slot;
288 u8 config_type;
289};
290
291enum {
292 NHLT_TDM_BASIC,
293 NHLT_TDM_MIC_ARRAY,
294};
295
296struct nhlt_dmic_array_config {
297 struct nhlt_tdm_config tdm_config;
298 u8 array_type;
299};
300
301/*
302 * Microphone array definitions may be found here:
303 * https://msdn.microsoft.com/en-us/library/windows/hardware/dn613960%28v=vs.85%29.aspx
304 */
305enum {
306 NHLT_MIC_ARRAY_2CH_SMALL = 0xa,
307 NHLT_MIC_ARRAY_2CH_BIG = 0xb,
308 NHLT_MIC_ARRAY_4CH_1ST_GEOM = 0xc,
309 NHLT_MIC_ARRAY_4CH_L_SHAPED = 0xd,
310 NHLT_MIC_ARRAY_4CH_2ND_GEOM = 0xe,
311 NHLT_MIC_ARRAY_VENDOR_DEFINED = 0xf,
312};
313
314#endif