blob: 2c44196317b0cfca9fb57b1c73b7b0c53005fcea [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
Simon Glassf6cdb912020-07-07 21:32:16 -0600142 * the table will reside oem_id and oem_table_id and return the address of the
143 * next ACPI table. On error 0 will be returned. The NHLT object is no longer
144 * valid after this function is called.
145 */
146int nhlt_serialise_oem_overrides(struct acpi_ctx *ctx, struct nhlt *nhlt,
147 const char *oem_id, const char *oem_table_id,
148 u32 oem_revision);
149
150int nhlt_setup(struct nhlt *nhlt, ofnode node);
151
152/* Link and device types. */
153enum {
154 NHLT_LINK_HDA,
155 NHLT_LINK_DSP,
156 NHLT_LINK_PDM,
157 NHLT_LINK_SSP,
158 NHLT_MAX_LINK_TYPES,
159};
160
161enum {
162 NHLT_SSP_DEV_BT, /* Bluetooth */
163 NHLT_SSP_DEV_MODEM,
164 NHLT_SSP_DEV_FM,
165 NHLT_SSP_DEV_RESERVED,
166 NHLT_SSP_DEV_I2S = 4,
167};
168
169enum {
170 NHLT_PDM_DEV,
171};
172
173/* Endpoint direction. */
174enum {
175 NHLT_DIR_RENDER,
176 NHLT_DIR_CAPTURE,
177 NHLT_DIR_BIDIRECTIONAL,
178};
179
180/*
181 * Channel mask for an endpoint. While they are prefixed with 'SPEAKER' the
182 * channel masks are also used for capture devices
183 */
184enum {
185 SPEAKER_FRONT_LEFT = BIT(0),
186 SPEAKER_FRONT_RIGHT = BIT(1),
187 SPEAKER_FRONT_CENTER = BIT(2),
188 SPEAKER_LOW_FREQUENCY = BIT(3),
189 SPEAKER_BACK_LEFT = BIT(4),
190 SPEAKER_BACK_RIGHT = BIT(5),
191 SPEAKER_FRONT_LEFT_OF_CENTER = BIT(6),
192 SPEAKER_FRONT_RIGHT_OF_CENTER = BIT(7),
193 SPEAKER_BACK_CENTER = BIT(8),
194 SPEAKER_SIDE_LEFT = BIT(9),
195 SPEAKER_SIDE_RIGHT = BIT(10),
196 SPEAKER_TOP_CENTER = BIT(11),
197 SPEAKER_TOP_FRONT_LEFT = BIT(12),
198 SPEAKER_TOP_FRONT_CENTER = BIT(13),
199 SPEAKER_TOP_FRONT_RIGHT = BIT(14),
200 SPEAKER_TOP_BACK_LEFT = BIT(15),
201 SPEAKER_TOP_BACK_CENTER = BIT(16),
202 SPEAKER_TOP_BACK_RIGHT = BIT(17),
203};
204
205/*
206 * Supporting structures. Only SoC/chipset and the library code directly should
207 * be manipulating these structures
208 */
209struct sub_format {
210 u32 data1;
211 u16 data2;
212 u16 data3;
213 u8 data4[8];
214};
215
216struct nhlt_specific_config {
217 u32 size;
218 void *capabilities;
219};
220
221struct nhlt_waveform {
222 u16 tag;
223 u16 num_channels;
224 u32 samples_per_second;
225 u32 bytes_per_second;
226 u16 block_align;
227 u16 bits_per_sample;
228 u16 extra_size;
229 u16 valid_bits_per_sample;
230 u32 channel_mask;
231 struct sub_format sub_format;
232};
233
234struct nhlt_format {
235 struct nhlt_waveform waveform;
236 struct nhlt_specific_config config;
237};
238
239/*
240 * This struct is used by nhlt_endpoint_add_formats() for easily adding
241 * waveform formats with associated settings file.
242 */
243struct nhlt_format_config {
244 int num_channels;
245 int sample_freq_khz;
246 int container_bits_per_sample;
247 int valid_bits_per_sample;
248 u32 speaker_mask;
249 const char *settings_file;
250};
251
252/* Arbitrary max number of formats per endpoint. */
253#define MAX_FORMATS 2
254struct nhlt_endpoint {
255 u32 length;
256 u8 link_type;
257 u8 instance_id;
258 u16 vendor_id;
259 u16 device_id;
260 u16 revision_id;
261 u32 subsystem_id;
262 u8 device_type;
263 u8 direction;
264 u8 virtual_bus_id;
265 struct nhlt_specific_config config;
266 u8 num_formats;
267 struct nhlt_format formats[MAX_FORMATS];
268};
269
270#define MAX_ENDPOINTS 8
271struct nhlt {
272 u32 subsystem_id;
273 u8 num_endpoints;
274 struct nhlt_endpoint endpoints[MAX_ENDPOINTS];
275 u8 current_instance_id[NHLT_MAX_LINK_TYPES];
276};
277
278struct nhlt_tdm_config {
279 u8 virtual_slot;
280 u8 config_type;
281};
282
283enum {
284 NHLT_TDM_BASIC,
285 NHLT_TDM_MIC_ARRAY,
286};
287
288struct nhlt_dmic_array_config {
289 struct nhlt_tdm_config tdm_config;
290 u8 array_type;
291};
292
293/*
294 * Microphone array definitions may be found here:
295 * https://msdn.microsoft.com/en-us/library/windows/hardware/dn613960%28v=vs.85%29.aspx
296 */
297enum {
298 NHLT_MIC_ARRAY_2CH_SMALL = 0xa,
299 NHLT_MIC_ARRAY_2CH_BIG = 0xb,
300 NHLT_MIC_ARRAY_4CH_1ST_GEOM = 0xc,
301 NHLT_MIC_ARRAY_4CH_L_SHAPED = 0xd,
302 NHLT_MIC_ARRAY_4CH_2ND_GEOM = 0xe,
303 NHLT_MIC_ARRAY_VENDOR_DEFINED = 0xf,
304};
305
306#endif