1 /* 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 
11 struct acpi_ctx;
12 struct nhlt;
13 struct nhlt_endpoint;
14 struct nhlt_format;
15 struct 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. */
45 struct nhlt *nhlt_init(void);
46 
47 /* Return the size of the NHLT table including ACPI header. */
48 size_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 
55 struct 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  */
75 int 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  */
84 int 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  */
95 struct 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  */
104 int 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. */
108 struct 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  */
119 int 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  */
128 int 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  */
138 void 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 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  */
146 int 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 
150 int nhlt_setup(struct nhlt *nhlt, ofnode node);
151 
152 /* Link and device types. */
153 enum {
154 	NHLT_LINK_HDA,
155 	NHLT_LINK_DSP,
156 	NHLT_LINK_PDM,
157 	NHLT_LINK_SSP,
158 	NHLT_MAX_LINK_TYPES,
159 };
160 
161 enum {
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 
169 enum {
170 	NHLT_PDM_DEV,
171 };
172 
173 /* Endpoint direction. */
174 enum {
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  */
184 enum {
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  */
209 struct sub_format {
210 	u32 data1;
211 	u16 data2;
212 	u16 data3;
213 	u8 data4[8];
214 };
215 
216 struct nhlt_specific_config {
217 	u32 size;
218 	void *capabilities;
219 };
220 
221 struct 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 
234 struct 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  */
243 struct 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
254 struct 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
271 struct 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 
278 struct nhlt_tdm_config {
279 	u8 virtual_slot;
280 	u8 config_type;
281 };
282 
283 enum {
284 	NHLT_TDM_BASIC,
285 	NHLT_TDM_MIC_ARRAY,
286 };
287 
288 struct 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  */
297 enum {
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
307