1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /* The macros in this file are not public, applications should not use them.
8  * The macros are used to translate devicetree zephyr,uac2 compatible nodes
9  * into uint8_t array initializer. The output should be treated as a binary blob
10  * for the USB host to use (and parse).
11  */
12 
13 #include <zephyr/sys/util.h>
14 #include <zephyr/usb/usb_ch9.h>
15 
16 #ifndef ZEPHYR_INCLUDE_USBD_UAC2_MACROS_H_
17 #define ZEPHYR_INCLUDE_USBD_UAC2_MACROS_H_
18 
19 #define ARRAY_BIT(idx, value) (value##ull << idx)
20 
21 #define U16_LE(value) ((value) & 0xFF), (((value) & 0xFF00) >> 8)
22 #define U32_LE(value)								\
23 	((value) & 0xFF),							\
24 	(((value) & 0xFF00) >> 8),						\
25 	(((value) & 0xFF0000) >> 16),						\
26 	(((value) & 0xFF000000) >> 24)
27 
28 #define ARRAY_ELEMENT_LESS_THAN_NEXT(node, prop, idx)				\
29 	COND_CODE_1(IS_EQ(idx, UTIL_DEC(DT_PROP_LEN(node, prop))),		\
30 		(1 /* nothing to compare the last element against */),		\
31 		((DT_PROP_BY_IDX(node, prop, idx) <				\
32 		  DT_PROP_BY_IDX(node, prop, UTIL_INC(idx)))))
33 #define IS_ARRAY_SORTED(node, prop)						\
34 	DT_FOREACH_PROP_ELEM_SEP(node, prop, ARRAY_ELEMENT_LESS_THAN_NEXT, (&&))
35 
36 #define FIRST_INTERFACE_NUMBER			0x00
37 #define FIRST_IN_EP_ADDR			0x81
38 #define FIRST_OUT_EP_ADDR			0x01
39 
40 /* A.1 Audio Function Class Code */
41 #define AUDIO_FUNCTION				AUDIO
42 
43 /* A.2 Audio Function Subclass Codes */
44 #define FUNCTION_SUBCLASS_UNDEFINED		0x00
45 
46 /* A.3 Audio Function Protocol Codes */
47 #define FUNCTION_PROTOCOL_UNDEFINED		0x00
48 #define AF_VERSION_02_00			IP_VERSION_02_00
49 
50 /* A.4 Audio Interface Class Code */
51 #define AUDIO					0x01
52 
53 /* A.5 Audio Interface Subclass Codes */
54 #define INTERFACE_SUBCLASS_UNDEFINED		0x00
55 #define AUDIOCONTROL				0x01
56 #define AUDIOSTREAMING				0x02
57 #define MIDISTREAMING				0x03
58 
59 /* A.6 Audio Interface Protocol Codes */
60 #define INTERFACE_PROTOCOL_UNDEFINED		0x00
61 #define IP_VERSION_02_00			0x20
62 
63 /* A.8 Audio Class-Specific Descriptor Types */
64 #define CS_UNDEFINED		0x20
65 #define CS_DEVICE		0x21
66 #define CS_CONFIGURATION	0x22
67 #define CS_STRING		0x23
68 #define CS_INTERFACE		0x24
69 #define CS_ENDPOINT		0x25
70 
71 /* A.9 Audio Class-Specific AC Interface Descriptor Subtypes */
72 #define AC_DESCRIPTOR_UNDEFINED			0x00
73 #define AC_DESCRIPTOR_HEADER			0x01
74 #define AC_DESCRIPTOR_INPUT_TERMINAL		0x02
75 #define AC_DESCRIPTOR_OUTPUT_TERMINAL		0x03
76 #define AC_DESCRIPTOR_MIXER_UNIT		0x04
77 #define AC_DESCRIPTOR_SELECTOR_UNIT		0x05
78 #define AC_DESCRIPTOR_FEATURE_UNIT		0x06
79 #define AC_DESCRIPTOR_EFFECT_UNIT		0x07
80 #define AC_DESCRIPTOR_PROCESSING_UNIT		0x08
81 #define AC_DESCRIPTOR_EXTENSION_UNIT		0x09
82 #define AC_DESCRIPTOR_CLOCK_SOURCE		0x0A
83 #define AC_DESCRIPTOR_CLOCK_SELECTOR		0x0B
84 #define AC_DESCRIPTOR_CLOCK_MULTIPLIER		0x0C
85 #define AC_DESCRIPTOR_SAMPLE_RATE_CONVERTER	0x0D
86 
87 /* A.10 Audio Class-Specific AS Interface Descriptor Subtypes */
88 #define AS_DESCRIPTOR_UNDEFINED			0x00
89 #define AS_DESCRIPTOR_GENERAL			0x01
90 #define AS_DESCRIPTOR_FORMAT_TYPE		0x02
91 #define AS_DESCRIPTOR_ENCODER			0x03
92 #define AS_DESCRIPTOR_DECODER			0x04
93 
94 /* A.13 Audio Class-Specific Endpoint Descriptor Subtypes */
95 #define DESCRIPTOR_UNDEFINED			0x00
96 #define EP_GENERAL				0x01
97 
98 /* Universal Serial Bus Device Class Definition for Audio Data Formats
99  * Release 2.0, May 31, 2006. A.1 Format Type Codes
100  * Values are in decimal to facilitate use with IS_EQ() macro.
101  */
102 #define FORMAT_TYPE_UNDEFINED			0
103 #define FORMAT_TYPE_I				1
104 #define FORMAT_TYPE_II				2
105 #define FORMAT_TYPE_III				3
106 #define FORMAT_TYPE_IV				4
107 #define EXT_FORMAT_TYPE_I			129
108 #define EXT_FORMAT_TYPE_II			130
109 #define EXT_FORMAT_TYPE_III			131
110 
111 /* Convert 0 to empty and everything else to itself */
112 #define EMPTY_ON_ZERO(value) COND_CODE_0(value, (), (value))
113 
114 /* Automatically assign Entity IDs based on entities order in devicetree */
115 #define ENTITY_ID(e) UTIL_INC(DT_NODE_CHILD_IDX(e))
116 
117 /* Name of uint8_t array holding descriptor data */
118 #define DESCRIPTOR_NAME(prefix, node) uac2_## prefix ## _ ## node
119 
120 /* Connected Entity ID or 0 if property is not defined. Rely on devicetree
121  * "required: true" to fail compilation if mandatory handle (e.g. clock source)
122  * is absent.
123  */
124 #define CONNECTED_ENTITY_ID(entity, phandle)					\
125 	COND_CODE_1(DT_NODE_HAS_PROP(entity, phandle),				\
126 		(ENTITY_ID(DT_PHANDLE_BY_IDX(entity, phandle, 0))), (0))
127 
128 #define ID_IF_TERMINAL_ASSOCIATES_WITH_TARGET(entity, target_id)		\
129 	IF_ENABLED(UTIL_AND(IS_EQ(						\
130 		CONNECTED_ENTITY_ID(entity, assoc_terminal), target_id),	\
131 		UTIL_OR(							\
132 			DT_NODE_HAS_COMPAT(entity, zephyr_uac2_input_terminal),	\
133 			DT_NODE_HAS_COMPAT(entity, zephyr_uac2_output_terminal)	\
134 		)), (ENTITY_ID(entity)))
135 
136 /* Find ID of terminal entity associated with given terminal entity. This macro
137  * evaluates to "+ 0" if there isn't any terminal entity associated. If there
138  * are terminal entities associated with given terminal, then the macro evalues
139  * to "IDs + 0" where IDs are the terminal entities ID separated by spaces.
140  *
141  * If there is exactly one ID then compiler will compute correct value.
142  * If there is more than one associated entity, then it will fail at build time
143  * (as it should) because the caller expects single integer.
144  */
145 #define FIND_ASSOCIATED_TERMINAL(entity)					\
146 	DT_FOREACH_CHILD_VARGS(DT_PARENT(entity),				\
147 		ID_IF_TERMINAL_ASSOCIATES_WITH_TARGET, ENTITY_ID(entity)) + 0
148 
149 /* If entity has assoc_terminal property, return the entity ID of associated
150  * terminal. Otherwise, search if any other terminal entity points to us and
151  * use its ID. If search yields no results then this evaluates to "+ 0" which
152  * matches the value USB Audio Class expects in bAssocTerminal if no association
153  * exists.
154  *
155  * This is a workaround for lack of cyclic dependencies support in devicetree.
156  */
157 #define ASSOCIATED_TERMINAL_ID(entity)						\
158 	COND_CODE_1(DT_NODE_HAS_PROP(entity, assoc_terminal),			\
159 		(CONNECTED_ENTITY_ID(entity, assoc_terminal)),			\
160 		(FIND_ASSOCIATED_TERMINAL(entity)))
161 
162 
163 #define CLOCK_SOURCE_ATTRIBUTES(entity)						\
164 	(DT_ENUM_IDX(entity, clock_type)) |					\
165 	(DT_PROP(entity, sof_synchronized) << 2)
166 
167 /* Control properties are optional enums in devicetree that can either be
168  * "read-only" or "host-programmable". If the property is missing, then it means
169  * that control is not present. Convert the control property into actual values
170  * used by USB Audio Class, i.e. 0b00 when control is not present, 0b01 when
171  * control is present but read-only and 0b11 when control can be programmed by
172  * host. Value 0b10 is not allowed by the specification.
173  */
174 #define CONTROL_NOT_PRESENT		0x0
175 #define CONTROL_READ_ONLY		0x1
176 #define CONTROL_HOST_PROGRAMMABLE	0x3
177 
178 #define CONTROL_TOKEN(entity, control_name)					\
179 	COND_CODE_1(DT_NODE_HAS_PROP(entity, control_name),			\
180 		(DT_STRING_UPPER_TOKEN(entity, control_name)),			\
181 		(NOT_PRESENT))
182 
183 #define CONTROL_BITS(entity, control_name, bitshift)				\
184 	(UTIL_CAT(CONTROL_, CONTROL_TOKEN(entity, control_name)) << bitshift)
185 
186 #define CONTROL_TOKEN_BY_IDX(entity, control_name, idx)				\
187 	COND_CODE_1(DT_PROP_HAS_IDX(entity, control_name, idx),			\
188 		(DT_STRING_UPPER_TOKEN_BY_IDX(entity, control_name, idx)),	\
189 		(NOT_PRESENT))
190 
191 #define CONTROL_BITS_BY_IDX(entity, control_name, idx, bitshift)		\
192 	(UTIL_CAT(CONTROL_, CONTROL_TOKEN_BY_IDX(entity, control_name, idx))	\
193 		<< bitshift)
194 
195 #define CLOCK_SOURCE_CONTROLS(entity)						\
196 	CONTROL_BITS(entity, frequency_control, 0)	|			\
197 	CONTROL_BITS(entity, validity_control, 2)
198 
199 #define INPUT_TERMINAL_CONTROLS(entity)						\
200 	CONTROL_BITS(entity, copy_protect_control, 0)	|			\
201 	CONTROL_BITS(entity, connector_control, 2)	|			\
202 	CONTROL_BITS(entity, overload_control, 4)	|			\
203 	CONTROL_BITS(entity, cluster_control, 6)	|			\
204 	CONTROL_BITS(entity, underflow_control, 8)	|			\
205 	CONTROL_BITS(entity, overflow_control, 10)
206 
207 #define OUTPUT_TERMINAL_CONTROLS(entity)					\
208 	CONTROL_BITS(entity, copy_protect_control, 0)	|			\
209 	CONTROL_BITS(entity, connector_control, 2)	|			\
210 	CONTROL_BITS(entity, overload_control, 4)	|			\
211 	CONTROL_BITS(entity, underflow_control, 6)	|			\
212 	CONTROL_BITS(entity, overflow_control, 8)
213 
214 #define FEATURE_UNIT_CHANNEL_CONTROLS(entity, ch)				\
215 	CONTROL_BITS_BY_IDX(entity, mute_control, ch, 0)		|	\
216 	CONTROL_BITS_BY_IDX(entity, volume_control, ch, 2)		|	\
217 	CONTROL_BITS_BY_IDX(entity, bass_control, ch, 4)		|	\
218 	CONTROL_BITS_BY_IDX(entity, mid_control, ch, 6)			|	\
219 	CONTROL_BITS_BY_IDX(entity, treble_control, ch, 8)		|	\
220 	CONTROL_BITS_BY_IDX(entity, graphic_equalizer_control, ch, 10)	|	\
221 	CONTROL_BITS_BY_IDX(entity, automatic_gain_control, ch, 12)	|	\
222 	CONTROL_BITS_BY_IDX(entity, delay_control, ch, 14)		|	\
223 	CONTROL_BITS_BY_IDX(entity, bass_boost_control, ch, 16)		|	\
224 	CONTROL_BITS_BY_IDX(entity, loudness_control, ch, 18)		|	\
225 	CONTROL_BITS_BY_IDX(entity, input_gain_control, ch, 20)		|	\
226 	CONTROL_BITS_BY_IDX(entity, input_gain_pad_control, ch, 22)	|	\
227 	CONTROL_BITS_BY_IDX(entity, phase_inverter_control, ch, 24)	|	\
228 	CONTROL_BITS_BY_IDX(entity, underflow_control, ch, 26)		|	\
229 	CONTROL_BITS_BY_IDX(entity, overflow_control, ch, 28)
230 
231 #define AUDIO_STREAMING_DATA_ENDPOINT_CONTROLS(node)				\
232 	CONTROL_BITS(node, pitch_control, 0)		|			\
233 	CONTROL_BITS(node, data_overrun_control, 2)	|			\
234 	CONTROL_BITS(node, data_underrun_control, 4)
235 
236 /* 4.1 Audio Channel Cluster Descriptor */
237 #define SPATIAL_LOCATIONS_ARRAY(cluster)					\
238 	DT_PROP(cluster, front_left),						\
239 	DT_PROP(cluster, front_right),						\
240 	DT_PROP(cluster, front_center),						\
241 	DT_PROP(cluster, low_frequency_effects),				\
242 	DT_PROP(cluster, back_left),						\
243 	DT_PROP(cluster, back_right),						\
244 	DT_PROP(cluster, front_left_of_center),					\
245 	DT_PROP(cluster, front_right_of_center),				\
246 	DT_PROP(cluster, back_center),						\
247 	DT_PROP(cluster, side_left),						\
248 	DT_PROP(cluster, side_right),						\
249 	DT_PROP(cluster, top_center),						\
250 	DT_PROP(cluster, top_front_left),					\
251 	DT_PROP(cluster, top_front_center),					\
252 	DT_PROP(cluster, top_front_right),					\
253 	DT_PROP(cluster, top_back_left),					\
254 	DT_PROP(cluster, top_back_center),					\
255 	DT_PROP(cluster, top_back_right),					\
256 	DT_PROP(cluster, top_front_left_of_center),				\
257 	DT_PROP(cluster, top_front_right_of_center),				\
258 	DT_PROP(cluster, left_low_frequency_effects),				\
259 	DT_PROP(cluster, right_low_frequency_effects),				\
260 	DT_PROP(cluster, top_side_left),					\
261 	DT_PROP(cluster, top_side_right),					\
262 	DT_PROP(cluster, bottom_center),					\
263 	DT_PROP(cluster, back_left_of_center),					\
264 	DT_PROP(cluster, back_right_of_center),					\
265 	0, 0, 0, 0, /* D27..D30: Reserved */					\
266 	DT_PROP(cluster, raw_data)
267 
268 #define SPATIAL_LOCATIONS_U32(entity) \
269 	(FOR_EACH_IDX(ARRAY_BIT, (|), SPATIAL_LOCATIONS_ARRAY(entity)))
270 #define NUM_SPATIAL_LOCATIONS(entity)						\
271 	NUM_VA_ARGS(LIST_DROP_EMPTY(						\
272 		FOR_EACH(EMPTY_ON_ZERO, (,), SPATIAL_LOCATIONS_ARRAY(entity))	\
273 	))
274 #define SPATIAL_LOCATIONS(entity) U32_LE(SPATIAL_LOCATIONS_U32(entity))
275 
276 #define FEATURE_UNIT_NUM_CHANNELS(entity)					\
277 	NUM_SPATIAL_LOCATIONS(DT_PHANDLE_BY_IDX(entity, data_source, 0))
278 
279 #define FEATURE_UNIT_CONTROLS_BY_IDX(i, entity)					\
280 	U32_LE(FEATURE_UNIT_CHANNEL_CONTROLS(entity, i))
281 
282 #define FEATURE_UNIT_CONTROLS_ARRAYS(entity)					\
283 	LISTIFY(UTIL_INC(FEATURE_UNIT_NUM_CHANNELS(entity)),			\
284 		FEATURE_UNIT_CONTROLS_BY_IDX, (,), entity)
285 
286 #define FEATURE_UNIT_DESCRIPTOR_LENGTH(entity)					\
287 	(6 + (FEATURE_UNIT_NUM_CHANNELS(entity) + 1) * 4)
288 
289 /* 4.7.2.1 Clock Source Descriptor */
290 #define CLOCK_SOURCE_DESCRIPTOR(entity)						\
291 	0x08,						/* bLength */		\
292 	CS_INTERFACE,					/* bDescriptorType */	\
293 	AC_DESCRIPTOR_CLOCK_SOURCE,			/* bDescriptorSubtype */\
294 	ENTITY_ID(entity),				/* bClockID */		\
295 	CLOCK_SOURCE_ATTRIBUTES(entity),		/* bmAttributes */	\
296 	CLOCK_SOURCE_CONTROLS(entity),			/* bmControls */	\
297 	CONNECTED_ENTITY_ID(entity, assoc_terminal),	/* bAssocTerminal */	\
298 	0x00,						/* iClockSource */
299 
300 /* 4.7.2.4 Input Terminal Descriptor */
301 #define INPUT_TERMINAL_DESCRIPTOR(entity)					\
302 	0x11,						/* bLength */		\
303 	CS_INTERFACE,					/* bDescriptorType */	\
304 	AC_DESCRIPTOR_INPUT_TERMINAL,			/* bDescriptorSubtype */\
305 	ENTITY_ID(entity),				/* bTerminalID */	\
306 	U16_LE(DT_PROP(entity, terminal_type)),		/* wTerminalType */	\
307 	ASSOCIATED_TERMINAL_ID(entity),			/* bAssocTerminal */	\
308 	CONNECTED_ENTITY_ID(entity, clock_source),	/* bCSourceID */	\
309 	NUM_SPATIAL_LOCATIONS(entity),			/* bNrChannels */	\
310 	SPATIAL_LOCATIONS(entity),			/* bmChannelConfig */	\
311 	0x00,						/* iChannelNames */	\
312 	U16_LE(INPUT_TERMINAL_CONTROLS(entity)),	/* bmControls */	\
313 	0x00,						/* iTerminal */
314 
315 /* 4.7.2.5 Output Terminal Descriptor */
316 #define OUTPUT_TERMINAL_DESCRIPTOR(entity)					\
317 	0x0C,						/* bLength */		\
318 	CS_INTERFACE,					/* bDescriptorType */	\
319 	AC_DESCRIPTOR_OUTPUT_TERMINAL,			/* bDescriptorSubtype */\
320 	ENTITY_ID(entity),				/* bTerminalID */	\
321 	U16_LE(DT_PROP(entity, terminal_type)),		/* wTerminalType */	\
322 	ASSOCIATED_TERMINAL_ID(entity),			/* bAssocTerminal */	\
323 	CONNECTED_ENTITY_ID(entity, data_source),	/* bSourceID */		\
324 	CONNECTED_ENTITY_ID(entity, clock_source),	/* bCSourceID */	\
325 	U16_LE(OUTPUT_TERMINAL_CONTROLS(entity)),	/* bmControls */	\
326 	0x00,						/* iTerminal */
327 
328 /* 4.7.2.8 Feature Unit Descriptor */
329 #define FEATURE_UNIT_DESCRIPTOR(entity)						\
330 	FEATURE_UNIT_DESCRIPTOR_LENGTH(entity),		/* bLength */		\
331 	CS_INTERFACE,					/* bDescriptorType */	\
332 	AC_DESCRIPTOR_FEATURE_UNIT,			/* bDescriptorSubtype */\
333 	ENTITY_ID(entity),				/* bUnitID */		\
334 	CONNECTED_ENTITY_ID(entity, data_source),	/* bSourceID */		\
335 	FEATURE_UNIT_CONTROLS_ARRAYS(entity),		/* bmaControls 0..ch */	\
336 	0x00,						/* iFeature */
337 
338 #define ENTITY_HEADER(entity)							\
339 	IF_ENABLED(DT_NODE_HAS_COMPAT(entity, zephyr_uac2_clock_source), (	\
340 		CLOCK_SOURCE_DESCRIPTOR(entity)					\
341 	))									\
342 	IF_ENABLED(DT_NODE_HAS_COMPAT(entity, zephyr_uac2_input_terminal), (	\
343 		INPUT_TERMINAL_DESCRIPTOR(entity)				\
344 	))									\
345 	IF_ENABLED(DT_NODE_HAS_COMPAT(entity, zephyr_uac2_output_terminal), (	\
346 		OUTPUT_TERMINAL_DESCRIPTOR(entity)				\
347 	))									\
348 	IF_ENABLED(DT_NODE_HAS_COMPAT(entity, zephyr_uac2_feature_unit), (	\
349 		FEATURE_UNIT_DESCRIPTOR(entity)					\
350 	))
351 
352 #define ENTITY_HEADER_ARRAYS(entity)						\
353 	IF_ENABLED(UTIL_NOT(IS_EMPTY(ENTITY_HEADER(entity))), (			\
354 		static uint8_t DESCRIPTOR_NAME(ac_entity, entity)[] = {		\
355 			ENTITY_HEADER(entity)					\
356 		};								\
357 	))
358 
359 #define ENTITY_HEADER_PTRS(entity)						\
360 	IF_ENABLED(UTIL_NOT(IS_EMPTY(ENTITY_HEADER(entity))), (			\
361 		(struct usb_desc_header *) &DESCRIPTOR_NAME(ac_entity, entity),	\
362 	))
363 
364 #define ENTITY_HEADERS(node) DT_FOREACH_CHILD(node, ENTITY_HEADER)
365 #define ENTITY_HEADERS_ARRAYS(node) DT_FOREACH_CHILD(node, ENTITY_HEADER_ARRAYS)
366 #define ENTITY_HEADERS_PTRS(node) DT_FOREACH_CHILD(node, ENTITY_HEADER_PTRS)
367 #define ENTITY_HEADERS_LENGTH(node) sizeof((uint8_t []){ENTITY_HEADERS(node)})
368 
369 #define AUDIO_STREAMING_CONTROLS(node)						\
370 	CONTROL_BITS(entity, active_alternate_setting_control, 0)	|	\
371 	CONTROL_BITS(entity, valid_alternate_settings_control, 2)
372 
373 /* TODO: Support other format types. Currently the PCM format (0x00000001) is
374  * hardcoded and format type is either I or IV depending on whether the
375  * interface has isochronous endpoint or not.
376  */
377 #define AUDIO_STREAMING_FORMAT_TYPE(node)					\
378 	COND_CODE_0(DT_PROP(node, external_interface),				\
379 		(FORMAT_TYPE_I), (FORMAT_TYPE_IV))
380 #define AUDIO_STREAMING_FORMATS(node) U32_LE(0x00000001)
381 
382 #define FEATURE_UNIT_CHANNEL_CLUSTER(node)					\
383 	IF_ENABLED(DT_NODE_HAS_COMPAT(DT_PROP(node, data_source),		\
384 		zephyr_uac2_input_terminal), (					\
385 			DT_PROP(node, data_source)				\
386 	))
387 
388 /* Track back Output Terminal data source to entity that has channel cluster */
389 #define OUTPUT_TERMINAL_CHANNEL_CLUSTER(node)					\
390 	IF_ENABLED(DT_NODE_HAS_COMPAT(DT_PROP(node, data_source),		\
391 		zephyr_uac2_input_terminal), (					\
392 			DT_PROP(node, data_source)				\
393 	))									\
394 	IF_ENABLED(DT_NODE_HAS_COMPAT(DT_PROP(node, data_source),		\
395 		zephyr_uac2_feature_unit), (					\
396 			FEATURE_UNIT_CHANNEL_CLUSTER(DT_PROP(node, data_source))\
397 	))
398 
399 /* If AudioStreaming is linked to input terminal, obtain the channel cluster
400  * configuration from the linked terminal. Otherwise (it has to be connected
401  * to output terminal) obtain the channel cluster configuration from data source
402  * entity.
403  */
404 #define AUDIO_STREAMING_CHANNEL_CLUSTER(node)					\
405 	IF_ENABLED(DT_NODE_HAS_COMPAT(DT_PROP(node, linked_terminal),		\
406 		zephyr_uac2_input_terminal), (					\
407 			DT_PROP(node, linked_terminal)				\
408 	))									\
409 	IF_ENABLED(DT_NODE_HAS_COMPAT(DT_PROP(node, linked_terminal),		\
410 		zephyr_uac2_output_terminal), (OUTPUT_TERMINAL_CHANNEL_CLUSTER(	\
411 			DT_PROP(node, linked_terminal))				\
412 	))
413 
414 #define AUDIO_STREAMING_NUM_SPATIAL_LOCATIONS(node)				\
415 	NUM_SPATIAL_LOCATIONS(AUDIO_STREAMING_CHANNEL_CLUSTER(node))
416 #define AUDIO_STREAMING_SPATIAL_LOCATIONS(node)					\
417 	SPATIAL_LOCATIONS(AUDIO_STREAMING_CHANNEL_CLUSTER(node))
418 
419 /* 4.9.2 Class-Specific AS Interface Descriptor */
420 #define AUDIO_STREAMING_GENERAL_DESCRIPTOR(node)				\
421 	0x10,						/* bLength */		\
422 	CS_INTERFACE,					/* bDescriptorType */	\
423 	AS_DESCRIPTOR_GENERAL,				/* bDescriptorSubtype */\
424 	CONNECTED_ENTITY_ID(node, linked_terminal),	/* bTerminalLink */	\
425 	AUDIO_STREAMING_CONTROLS(node),			/* bmControls*/		\
426 	AUDIO_STREAMING_FORMAT_TYPE(node),		/* bFormatType */	\
427 	AUDIO_STREAMING_FORMATS(node),			/* bmFormats */		\
428 	AUDIO_STREAMING_NUM_SPATIAL_LOCATIONS(node),    /* bNrChannels */	\
429 	AUDIO_STREAMING_SPATIAL_LOCATIONS(node),	/* bmChannelConfig */	\
430 	0x00,						/* iChannelNames */
431 
432 /* Universal Serial Bus Device Class Definition for Audio Data Formats
433  * Release 2.0, May 31, 2006. 2.3.1.6 Type I Format Type Descriptor
434  */
435 #define AUDIO_STREAMING_FORMAT_I_TYPE_DESCRIPTOR(node)				\
436 	0x06,						/* bLength */		\
437 	CS_INTERFACE,					/* bDescriptorType */	\
438 	AS_DESCRIPTOR_FORMAT_TYPE,			/* bDescriptorSubtype */\
439 	FORMAT_TYPE_I,					/* bFormatType */	\
440 	DT_PROP(node, subslot_size),			/* bSubslotSize */	\
441 	DT_PROP(node, bit_resolution),			/* bBitResolution */
442 
443 /* Universal Serial Bus Device Class Definition for Audio Data Formats
444  * Release 2.0, May 31, 2006. 2.3.4.1 Type IV Format Type Descriptor
445  */
446 #define AUDIO_STREAMING_FORMAT_IV_TYPE_DESCRIPTOR(node)				\
447 	0x04,						/* bLength */		\
448 	CS_INTERFACE,					/* bDescriptorType */	\
449 	AS_DESCRIPTOR_FORMAT_TYPE,			/* bDescriptorSubtype */\
450 	FORMAT_TYPE_IV,					/* bFormatType */
451 
452 /* 4.9.3 Class-Specific AS Format Type Descriptor */
453 #define AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR(node)				\
454 	IF_ENABLED(IS_EQ(AUDIO_STREAMING_FORMAT_TYPE(node), FORMAT_TYPE_I), (	\
455 		AUDIO_STREAMING_FORMAT_I_TYPE_DESCRIPTOR(node)))		\
456 	IF_ENABLED(IS_EQ(AUDIO_STREAMING_FORMAT_TYPE(node), FORMAT_TYPE_IV), (	\
457 		AUDIO_STREAMING_FORMAT_IV_TYPE_DESCRIPTOR(node)))
458 
459 #define AUDIO_STREAMING_INTERFACE_DESCRIPTORS_ARRAYS(node)			\
460 	static uint8_t DESCRIPTOR_NAME(as_general_desc, node)[] = {		\
461 		AUDIO_STREAMING_GENERAL_DESCRIPTOR(node)			\
462 	};									\
463 	static uint8_t DESCRIPTOR_NAME(as_format_desc, node)[] = {		\
464 		AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR(node)			\
465 	};
466 
467 /* Full and High speed share common class-specific interface descriptors */
468 #define AUDIO_STREAMING_INTERFACE_DESCRIPTORS_PTRS(node)			\
469 	(struct usb_desc_header *) &DESCRIPTOR_NAME(as_general_desc, node),	\
470 	(struct usb_desc_header *) &DESCRIPTOR_NAME(as_format_desc, node),
471 
472 /* 4.7.2 Class-Specific AC Interface Descriptor */
473 #define AC_INTERFACE_HEADER_DESCRIPTOR(node)					\
474 	0x09,						/* bLength */		\
475 	CS_INTERFACE,					/* bDescriptorType */	\
476 	AC_DESCRIPTOR_HEADER,				/* bDescriptorSubtype */\
477 	U16_LE(0x0200),					/* bcdADC */		\
478 	DT_PROP(node, audio_function),			/* bCategory */		\
479 	U16_LE(9 + ENTITY_HEADERS_LENGTH(node)),	/* wTotalLength */	\
480 	0x00,						/* bmControls */	\
481 
482 #define AC_INTERFACE_HEADER_DESCRIPTOR_ARRAY(node)				\
483 	static uint8_t DESCRIPTOR_NAME(ac_header, node)[] = {			\
484 		AC_INTERFACE_HEADER_DESCRIPTOR(node)				\
485 	};
486 
487 #define AC_INTERFACE_HEADER_DESCRIPTOR_PTR(node)				\
488 	(struct usb_desc_header *) &DESCRIPTOR_NAME(ac_header, node),
489 
490 #define IS_AUDIOSTREAMING_INTERFACE(node)					\
491 	DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming)
492 
493 #define UAC2_NUM_INTERFACES(node)						\
494 	1 /* AudioControl interface */ +					\
495 	DT_FOREACH_CHILD_SEP(node, IS_AUDIOSTREAMING_INTERFACE, (+))
496 
497 #define UAC2_ALLOWED_AT_FULL_SPEED(node)					\
498 	DT_PROP(node, full_speed)
499 
500 #define UAC2_ALLOWED_AT_HIGH_SPEED(node)					\
501 	DT_PROP(node, high_speed)
502 
503 /* 4.6 Interface Association Descriptor */
504 #define UAC2_INTERFACE_ASSOCIATION_DESCRIPTOR(node)				\
505 	0x08,						/* bLength */		\
506 	USB_DESC_INTERFACE_ASSOC,			/* bDescriptorType */	\
507 	FIRST_INTERFACE_NUMBER,				/* bFirstInterface */	\
508 	UAC2_NUM_INTERFACES(node),			/* bInterfaceCount */	\
509 	AUDIO_FUNCTION,					/* bFunctionClass */	\
510 	FUNCTION_SUBCLASS_UNDEFINED,			/* bFunctionSubclass */ \
511 	AF_VERSION_02_00,				/* bFunctionProtocol */	\
512 	0x00,						/* iFunction */
513 
514 #define UAC2_INTERFACE_ASSOCIATION_DESCRIPTOR_ARRAY(node)			\
515 	IF_ENABLED(UAC2_ALLOWED_AT_FULL_SPEED(node), (				\
516 		static uint8_t DESCRIPTOR_NAME(fs_iad, node)[] = {		\
517 			UAC2_INTERFACE_ASSOCIATION_DESCRIPTOR(node)		\
518 		};								\
519 	))									\
520 	IF_ENABLED(UAC2_ALLOWED_AT_HIGH_SPEED(node), (				\
521 		static uint8_t DESCRIPTOR_NAME(hs_iad, node)[] = {		\
522 			UAC2_INTERFACE_ASSOCIATION_DESCRIPTOR(node)		\
523 		};								\
524 	))
525 
526 #define UAC2_INTERFACE_ASSOCIATION_FS_DESCRIPTOR_PTR(node)			\
527 	(struct usb_desc_header *) &DESCRIPTOR_NAME(fs_iad, node),
528 
529 #define UAC2_INTERFACE_ASSOCIATION_HS_DESCRIPTOR_PTR(node)			\
530 	(struct usb_desc_header *) &DESCRIPTOR_NAME(hs_iad, node),
531 
532 /* 4.7.1 Standard AC Interface Descriptor */
533 #define AC_INTERFACE_DESCRIPTOR(node)						\
534 	0x09,						/* bLength */		\
535 	USB_DESC_INTERFACE,				/* bDescriptorType */	\
536 	FIRST_INTERFACE_NUMBER,				/* bInterfaceNumber */	\
537 	0x00,						/* bAlternateSetting */ \
538 	DT_PROP(node, interrupt_endpoint),		/* bNumEndpoints */	\
539 	AUDIO,						/* bInterfaceClass */	\
540 	AUDIOCONTROL,					/* bInterfaceSubClass */\
541 	IP_VERSION_02_00,				/* bInterfaceProtocol */\
542 	0x00,						/* iInterface */
543 
544 #define AC_INTERFACE_DESCRIPTOR_ARRAY(node)					\
545 	IF_ENABLED(UAC2_ALLOWED_AT_FULL_SPEED(node), (				\
546 		static uint8_t DESCRIPTOR_NAME(fs_ac_interface, node)[] = {	\
547 			AC_INTERFACE_DESCRIPTOR(node)				\
548 		};								\
549 	))									\
550 	IF_ENABLED(UAC2_ALLOWED_AT_HIGH_SPEED(node), (				\
551 		static uint8_t DESCRIPTOR_NAME(hs_ac_interface, node)[] = {	\
552 			AC_INTERFACE_DESCRIPTOR(node)				\
553 		};								\
554 	))
555 
556 #define AC_INTERFACE_FS_DESCRIPTOR_PTR(node)					\
557 	(struct usb_desc_header *) &DESCRIPTOR_NAME(fs_ac_interface, node),
558 
559 #define AC_INTERFACE_HS_DESCRIPTOR_PTR(node)					\
560 	(struct usb_desc_header *) &DESCRIPTOR_NAME(hs_ac_interface, node),
561 
562 /* 4.8.2.1 Standard AC Interrupt Endpoint Descriptor */
563 #define AC_ENDPOINT_DESCRIPTOR(node)						\
564 	0x07,						/* bLength */		\
565 	USB_DESC_ENDPOINT,				/* bDescriptorType */	\
566 	FIRST_IN_EP_ADDR,				/* bEndpointAddress */	\
567 	USB_EP_TYPE_INTERRUPT,				/* bmAttributes */	\
568 	U16_LE(0x06),					/* wMaxPacketSize */	\
569 	0x01,						/* bInterval */		\
570 
571 #define AC_ENDPOINT_DESCRIPTOR_ARRAY(node)					\
572 	static uint8_t DESCRIPTOR_NAME(ac_endpoint, node)[] = {			\
573 		AC_ENDPOINT_DESCRIPTOR(node)					\
574 	};
575 
576 #define AC_ENDPOINT_DESCRIPTOR_PTR(node)					\
577 	(struct usb_desc_header *) &DESCRIPTOR_NAME(ac_endpoint, node),
578 
579 #define FIND_AUDIOSTREAMING(node, fn, ...)					\
580 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
581 		fn(node, __VA_ARGS__)))
582 
583 #define FOR_EACH_AUDIOSTREAMING_INTERFACE(node, fn, ...)			\
584 	DT_FOREACH_CHILD_VARGS(node, FIND_AUDIOSTREAMING, fn, __VA_ARGS__)
585 
586 #define COUNT_AS_INTERFACES_BEFORE_IDX(node, idx)				\
587 	+ 1 * (DT_NODE_CHILD_IDX(node) < idx)
588 
589 #define AS_INTERFACE_NUMBER(node)						\
590 	FIRST_INTERFACE_NUMBER + 1 /* AudioControl interface */	+		\
591 	FOR_EACH_AUDIOSTREAMING_INTERFACE(DT_PARENT(node),			\
592 		COUNT_AS_INTERFACES_BEFORE_IDX, DT_NODE_CHILD_IDX(node))
593 
594 #define AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node)					\
595 	UTIL_NOT(DT_PROP(node, external_interface))
596 
597 #define AS_IS_USB_ISO_IN(node)							\
598 	UTIL_AND(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node),			\
599 		DT_NODE_HAS_COMPAT(DT_PROP(node, linked_terminal),		\
600 			zephyr_uac2_output_terminal))
601 
602 #define AS_IS_USB_ISO_OUT(node)							\
603 	UTIL_AND(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node),			\
604 		DT_NODE_HAS_COMPAT(DT_PROP(node, linked_terminal),		\
605 			zephyr_uac2_input_terminal))
606 
607 #define CLK_IS_SOF_SYNCHRONIZED(entity)						\
608 	IF_ENABLED(DT_NODE_HAS_COMPAT(entity, zephyr_uac2_clock_source), (	\
609 		DT_PROP(entity, sof_synchronized)				\
610 	))
611 
612 /* Sampling frequencies are sorted (asserted at compile time), so just grab
613  * last sampling frequency.
614  */
615 #define CLK_MAX_FREQUENCY(entity)						\
616 	IF_ENABLED(DT_NODE_HAS_COMPAT(entity, zephyr_uac2_clock_source), (	\
617 		DT_PROP_BY_IDX(entity, sampling_frequencies,			\
618 			UTIL_DEC(DT_PROP_LEN(entity, sampling_frequencies)))	\
619 	))
620 
621 #define AS_CLK_SOURCE(node)							\
622 	DT_PROP(DT_PROP(node, linked_terminal), clock_source)
623 
624 #define AS_CLK_MAX_FREQUENCY(node)						\
625 	CLK_MAX_FREQUENCY(AS_CLK_SOURCE(node))
626 
627 #define AS_IS_SOF_SYNCHRONIZED(node)						\
628 	CLK_IS_SOF_SYNCHRONIZED(AS_CLK_SOURCE(node))
629 
630 #define AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node)					\
631 	UTIL_AND(UTIL_AND(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node),		\
632 			UTIL_NOT(DT_PROP(node, implicit_feedback))),		\
633 		UTIL_AND(UTIL_NOT(AS_IS_SOF_SYNCHRONIZED(node)),		\
634 			AS_IS_USB_ISO_OUT(node)))
635 
636 #define AS_INTERFACE_NUM_ENDPOINTS(node)					\
637 	(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node) +				\
638 	AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node))
639 
640 /* 4.9.1 Standard AS Interface Descriptor */
641 #define AS_INTERFACE_DESCRIPTOR(node, alternate, numendpoints)			\
642 	0x09,						/* bLength */		\
643 	USB_DESC_INTERFACE,				/* bDescriptorType */	\
644 	AS_INTERFACE_NUMBER(node),			/* bInterfaceNumber */	\
645 	alternate,					/* bAlternateSetting */	\
646 	numendpoints,					/* bNumEndpoints */	\
647 	AUDIO,						/* bInterfaceClass */	\
648 	AUDIOSTREAMING,					/* bInterfaceSubClass */\
649 	IP_VERSION_02_00,				/* bInterfaceProtocol */\
650 	0x00,						/* iInterface */
651 
652 #define AS_INTERFACE_FS_DESCRIPTOR_ARRAY(node, alternate, numendpoints)		\
653 	static uint8_t DESCRIPTOR_NAME(fs_as_if_alt##alternate, node)[] = {	\
654 		AS_INTERFACE_DESCRIPTOR(node, alternate, numendpoints)		\
655 	};
656 
657 #define AS_INTERFACE_HS_DESCRIPTOR_ARRAY(node, alternate, numendpoints)		\
658 	static uint8_t DESCRIPTOR_NAME(hs_as_if_alt##alternate, node)[] = {	\
659 		AS_INTERFACE_DESCRIPTOR(node, alternate, numendpoints)		\
660 	};
661 
662 #define AS_INTERFACE_DESCRIPTOR_ARRAY(node, alternate, numendpoints)		\
663 	IF_ENABLED(UAC2_ALLOWED_AT_FULL_SPEED(DT_PARENT(node)), (		\
664 		AS_INTERFACE_FS_DESCRIPTOR_ARRAY(node, alternate, numendpoints)	\
665 	))									\
666 	IF_ENABLED(UAC2_ALLOWED_AT_HIGH_SPEED(DT_PARENT(node)), (		\
667 		AS_INTERFACE_HS_DESCRIPTOR_ARRAY(node, alternate, numendpoints)	\
668 	))
669 
670 #define AS_INTERFACE_FS_DESCRIPTOR_PTR(node, altnum)				\
671 	(struct usb_desc_header *) &DESCRIPTOR_NAME(fs_as_if_alt##altnum, node),
672 
673 #define AS_INTERFACE_HS_DESCRIPTOR_PTR(node, altnum)				\
674 	(struct usb_desc_header *) &DESCRIPTOR_NAME(hs_as_if_alt##altnum, node),
675 
676 #define COUNT_AS_OUT_ENDPOINTS_BEFORE_IDX(node, idx)				\
677 	+ AS_IS_USB_ISO_OUT(node) * (DT_NODE_CHILD_IDX(node) < idx)
678 
679 #define COUNT_AS_IN_ENDPOINTS_BEFORE_IDX(node, idx)				\
680 	+ (AS_IS_USB_ISO_IN(node) + AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node))	\
681 		* (DT_NODE_CHILD_IDX(node) < idx)
682 
683 /* FIXME: Ensure that the explicit feedback endpoints assignments match
684  * numbering requirements from Universal Serial Bus Specification Revision 2.0
685  * 9.6.6 Endpoint. This FIXME is not limited to the macros here but also to
686  * actual USB stack endpoint fixup (so the fixup does not break the numbering).
687  *
688  * This FIXME does not affect nRF52 and nRF53 when implicit feedback is used
689  * because the endpoints after fixup will be 0x08 and 0x88 because there are
690  * only two isochronous endpoints on these devices (one IN, one OUT).
691  */
692 #define AS_NEXT_OUT_EP_ADDR(node)						\
693 	FIRST_OUT_EP_ADDR +							\
694 	FOR_EACH_AUDIOSTREAMING_INTERFACE(DT_PARENT(node),			\
695 		COUNT_AS_OUT_ENDPOINTS_BEFORE_IDX, DT_NODE_CHILD_IDX(node))
696 
697 #define AS_NEXT_IN_EP_ADDR(node)						\
698 	FIRST_IN_EP_ADDR + DT_PROP(DT_PARENT(node), interrupt_endpoint) +	\
699 	FOR_EACH_AUDIOSTREAMING_INTERFACE(DT_PARENT(node),			\
700 		COUNT_AS_IN_ENDPOINTS_BEFORE_IDX, DT_NODE_CHILD_IDX(node))
701 
702 #define AS_DATA_EP_ADDR(node)							\
703 	COND_CODE_1(AS_IS_USB_ISO_OUT(node),					\
704 		(AS_NEXT_OUT_EP_ADDR(node)),					\
705 		(AS_NEXT_IN_EP_ADDR(node)))
706 
707 #define AS_BYTES_PER_SAMPLE(node)						\
708 	DT_PROP(node, subslot_size)
709 
710 /* Asynchronous endpoints needs space for 1 extra sample */
711 #define AS_SAMPLES_PER_FRAME(node)						\
712 	((ROUND_UP(AS_CLK_MAX_FREQUENCY(node), 1000) / 1000) +			\
713 	  UTIL_NOT(AS_IS_SOF_SYNCHRONIZED(node)))
714 
715 #define AS_SAMPLES_PER_MICROFRAME(node)						\
716 	((ROUND_UP(AS_CLK_MAX_FREQUENCY(node), 8000) / 8000) +			\
717 	  UTIL_NOT(AS_IS_SOF_SYNCHRONIZED(node)))
718 
719 #define AS_DATA_EP_SYNC_TYPE(node)						\
720 	COND_CODE_1(AS_IS_SOF_SYNCHRONIZED(node), (0x3 << 2), (0x1 << 2))
721 
722 #define AS_DATA_EP_USAGE_TYPE(node)						\
723 	COND_CODE_1(UTIL_AND(DT_PROP(node, implicit_feedback),			\
724 		UTIL_NOT(AS_IS_USB_ISO_OUT(node))), (0x2 << 4), (0x0 << 4))
725 
726 #define AS_DATA_EP_ATTR(node)							\
727 	USB_EP_TYPE_ISO | AS_DATA_EP_SYNC_TYPE(node) |				\
728 	AS_DATA_EP_USAGE_TYPE(node)
729 
730 #define AS_FS_DATA_EP_MAX_PACKET_SIZE(node)					\
731 	AUDIO_STREAMING_NUM_SPATIAL_LOCATIONS(node) *				\
732 	AS_BYTES_PER_SAMPLE(node) * AS_SAMPLES_PER_FRAME(node)
733 
734 #define AS_HS_DATA_EP_TPL(node)							\
735 	USB_TPL_ROUND_UP(AUDIO_STREAMING_NUM_SPATIAL_LOCATIONS(node) *		\
736 		AS_BYTES_PER_SAMPLE(node) * AS_SAMPLES_PER_MICROFRAME(node))
737 
738 #define AS_HS_DATA_EP_MAX_PACKET_SIZE(node)					\
739 	USB_TPL_TO_MPS(AS_HS_DATA_EP_TPL(node))
740 
741 /* 4.10.1.1 Standard AS Isochronous Audio Data Endpoint Descriptor */
742 #define STANDARD_AS_ISOCHRONOUS_DATA_ENDPOINT_FS_DESCRIPTOR(node)		\
743 	0x07,						/* bLength */		\
744 	USB_DESC_ENDPOINT,				/* bDescriptorType */	\
745 	AS_DATA_EP_ADDR(node),				/* bEndpointAddress */	\
746 	AS_DATA_EP_ATTR(node),				/* bmAttributes */	\
747 	U16_LE(AS_FS_DATA_EP_MAX_PACKET_SIZE(node)),	/* wMaxPacketSize */	\
748 	0x01,						/* bInterval */
749 
750 #define AS_ISOCHRONOUS_DATA_ENDPOINT_FS_DESCRIPTORS_ARRAYS(node)		\
751 	static uint8_t DESCRIPTOR_NAME(fs_std_data_ep, node)[] = {		\
752 		STANDARD_AS_ISOCHRONOUS_DATA_ENDPOINT_FS_DESCRIPTOR(node)	\
753 	};
754 
755 #define STANDARD_AS_ISOCHRONOUS_DATA_ENDPOINT_HS_DESCRIPTOR(node)		\
756 	0x07,						/* bLength */		\
757 	USB_DESC_ENDPOINT,				/* bDescriptorType */	\
758 	AS_DATA_EP_ADDR(node),				/* bEndpointAddress */	\
759 	AS_DATA_EP_ATTR(node),				/* bmAttributes */	\
760 	U16_LE(AS_HS_DATA_EP_MAX_PACKET_SIZE(node)),	/* wMaxPacketSize */	\
761 	0x01,						/* bInterval */
762 
763 #define AS_ISOCHRONOUS_DATA_ENDPOINT_HS_DESCRIPTORS_ARRAYS(node)		\
764 	static uint8_t DESCRIPTOR_NAME(hs_std_data_ep, node)[] = {		\
765 		STANDARD_AS_ISOCHRONOUS_DATA_ENDPOINT_HS_DESCRIPTOR(node)	\
766 	};
767 
768 #define LOCK_DELAY_UNITS(node)							\
769 	COND_CODE_1(DT_NODE_HAS_PROP(node, lock_delay_units),			\
770 		(1 + DT_ENUM_IDX(node, lock_delay_units)),			\
771 		(0 /* Undefined */))
772 
773 /* 4.10.1.2 Class-Specific AS Isochronous Audio Data Endpoint Descriptor */
774 #define CLASS_SPECIFIC_AS_ISOCHRONOUS_DATA_ENDPOINT_DESCRIPTOR(node)		\
775 	0x08,						/* bLength */		\
776 	CS_ENDPOINT,					/* bDescriptorType */	\
777 	EP_GENERAL,					/* bDescriptorSubtype */\
778 	0x00,						/* bmAttributes */	\
779 	AUDIO_STREAMING_DATA_ENDPOINT_CONTROLS(node),	/* bmControls */	\
780 	LOCK_DELAY_UNITS(node),				/* bLockDelayUnits */	\
781 	U16_LE(DT_PROP_OR(node, lock_delay, 0)),	/* wLockDelay */
782 
783 /* Full and High speed share common class-specific descriptor */
784 #define AS_ISOCHRONOUS_DATA_ENDPOINT_CS_DESCRIPTORS_ARRAYS(node)		\
785 	static uint8_t DESCRIPTOR_NAME(cs_data_ep, node)[] = {			\
786 		CLASS_SPECIFIC_AS_ISOCHRONOUS_DATA_ENDPOINT_DESCRIPTOR(node)	\
787 	};
788 
789 #define AS_ISOCHRONOUS_DATA_ENDPOINT_FS_DESCRIPTORS_PTRS(node)			\
790 	(struct usb_desc_header *) &DESCRIPTOR_NAME(fs_std_data_ep, node),	\
791 	(struct usb_desc_header *) &DESCRIPTOR_NAME(cs_data_ep, node),
792 
793 #define AS_ISOCHRONOUS_DATA_ENDPOINT_HS_DESCRIPTORS_PTRS(node)			\
794 	(struct usb_desc_header *) &DESCRIPTOR_NAME(hs_std_data_ep, node),	\
795 	(struct usb_desc_header *) &DESCRIPTOR_NAME(cs_data_ep, node),
796 
797 #define AS_EXPLICIT_FEEDBACK_ENDPOINT_FS_DESCRIPTOR(node)			\
798 	0x07,						/* bLength */		\
799 	USB_DESC_ENDPOINT,				/* bDescriptorType */	\
800 	AS_NEXT_IN_EP_ADDR(node),			/* bEndpointAddress */	\
801 	0x11,						/* bmAttributes */	\
802 	U16_LE(0x03),					/* wMaxPacketSize */	\
803 	0x01, /* TODO: adjust to P 5.12.4.2 Feedback */	/* bInterval */
804 
805 #define AS_EXPLICIT_FEEDBACK_FS_DESCRIPTOR_ARRAY(node)				\
806 	static uint8_t DESCRIPTOR_NAME(fs_feedback_ep, node)[] = {		\
807 		AS_EXPLICIT_FEEDBACK_ENDPOINT_FS_DESCRIPTOR(node)		\
808 	};
809 
810 #define AS_EXPLICIT_FEEDBACK_ENDPOINT_FS_DESCRIPTOR_PTR(node)			\
811 	(struct usb_desc_header *) &DESCRIPTOR_NAME(fs_feedback_ep, node),
812 
813 #define AS_EXPLICIT_FEEDBACK_ENDPOINT_HS_DESCRIPTOR(node)			\
814 	0x07,						/* bLength */		\
815 	USB_DESC_ENDPOINT,				/* bDescriptorType */	\
816 	AS_NEXT_IN_EP_ADDR(node),			/* bEndpointAddress */	\
817 	0x11,						/* bmAttributes */	\
818 	U16_LE(0x04),					/* wMaxPacketSize */	\
819 	0x01, /* TODO: adjust to P 5.12.4.2 Feedback */	/* bInterval */
820 
821 #define AS_EXPLICIT_FEEDBACK_HS_DESCRIPTOR_ARRAY(node)				\
822 	static uint8_t DESCRIPTOR_NAME(hs_feedback_ep, node)[] = {		\
823 		AS_EXPLICIT_FEEDBACK_ENDPOINT_HS_DESCRIPTOR(node)		\
824 	};
825 
826 #define AS_EXPLICIT_FEEDBACK_ENDPOINT_HS_DESCRIPTOR_PTR(node)			\
827 	(struct usb_desc_header *) &DESCRIPTOR_NAME(hs_feedback_ep, node),
828 
829 #define AS_FS_DESCRIPTORS_ARRAYS(node)						\
830 	IF_ENABLED(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node), (			\
831 		AS_ISOCHRONOUS_DATA_ENDPOINT_FS_DESCRIPTORS_ARRAYS(node)	\
832 		IF_ENABLED(AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node), (		\
833 			AS_EXPLICIT_FEEDBACK_FS_DESCRIPTOR_ARRAY(node)))	\
834 	))
835 
836 #define AS_HS_DESCRIPTORS_ARRAYS(node)						\
837 	IF_ENABLED(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node), (			\
838 		AS_ISOCHRONOUS_DATA_ENDPOINT_HS_DESCRIPTORS_ARRAYS(node)	\
839 		IF_ENABLED(AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node), (		\
840 			AS_EXPLICIT_FEEDBACK_HS_DESCRIPTOR_ARRAY(node)))	\
841 	))
842 
843 #define AS_DESCRIPTORS_ARRAYS(node)						\
844 	AS_INTERFACE_DESCRIPTOR_ARRAY(node, 0, 0)				\
845 	IF_ENABLED(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node), (			\
846 		AS_INTERFACE_DESCRIPTOR_ARRAY(node, 1,				\
847 			AS_INTERFACE_NUM_ENDPOINTS(node))))			\
848 	AUDIO_STREAMING_INTERFACE_DESCRIPTORS_ARRAYS(node)			\
849 	IF_ENABLED(UAC2_ALLOWED_AT_FULL_SPEED(DT_PARENT(node)), (		\
850 		AS_FS_DESCRIPTORS_ARRAYS(node)))				\
851 	IF_ENABLED(UAC2_ALLOWED_AT_HIGH_SPEED(DT_PARENT(node)), (		\
852 		AS_HS_DESCRIPTORS_ARRAYS(node)))				\
853 	IF_ENABLED(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node), (			\
854 		AS_ISOCHRONOUS_DATA_ENDPOINT_CS_DESCRIPTORS_ARRAYS(node)))
855 
856 #define AS_FS_DESCRIPTORS_PTRS(node)						\
857 	AS_INTERFACE_FS_DESCRIPTOR_PTR(node, 0)					\
858 	IF_ENABLED(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node), (			\
859 		AS_INTERFACE_FS_DESCRIPTOR_PTR(node, 1)))			\
860 	AUDIO_STREAMING_INTERFACE_DESCRIPTORS_PTRS(node)			\
861 	IF_ENABLED(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node), (			\
862 		AS_ISOCHRONOUS_DATA_ENDPOINT_FS_DESCRIPTORS_PTRS(node)		\
863 		IF_ENABLED(AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node), (		\
864 			AS_EXPLICIT_FEEDBACK_ENDPOINT_FS_DESCRIPTOR_PTR(node)))	\
865 	))
866 
867 #define AS_HS_DESCRIPTORS_PTRS(node)						\
868 	AS_INTERFACE_HS_DESCRIPTOR_PTR(node, 0)					\
869 	IF_ENABLED(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node), (			\
870 		AS_INTERFACE_HS_DESCRIPTOR_PTR(node, 1)))			\
871 	AUDIO_STREAMING_INTERFACE_DESCRIPTORS_PTRS(node)			\
872 	IF_ENABLED(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node), (			\
873 		AS_ISOCHRONOUS_DATA_ENDPOINT_HS_DESCRIPTORS_PTRS(node)		\
874 		IF_ENABLED(AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node), (		\
875 			AS_EXPLICIT_FEEDBACK_ENDPOINT_HS_DESCRIPTOR_PTR(node)))	\
876 	))
877 
878 #define AS_DESCRIPTORS_ARRAYS_IF_AUDIOSTREAMING(node)				\
879 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
880 		AS_DESCRIPTORS_ARRAYS(node)))
881 
882 #define AS_FS_DESCRIPTORS_PTRS_IF_AUDIOSTREAMING(node)				\
883 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
884 		AS_FS_DESCRIPTORS_PTRS(node)))
885 
886 #define AS_HS_DESCRIPTORS_PTRS_IF_AUDIOSTREAMING(node)				\
887 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
888 		AS_HS_DESCRIPTORS_PTRS(node)))
889 
890 #define UAC2_AUDIO_CONTROL_DESCRIPTOR_ARRAYS(node)				\
891 	AC_INTERFACE_DESCRIPTOR_ARRAY(node)					\
892 	AC_INTERFACE_HEADER_DESCRIPTOR_ARRAY(node)				\
893 	ENTITY_HEADERS_ARRAYS(node)						\
894 	IF_ENABLED(DT_PROP(node, interrupt_endpoint), (				\
895 		AC_ENDPOINT_DESCRIPTOR_ARRAY(node)))
896 
897 #define UAC2_AUDIO_CONTROL_COMMON_DESCRIPTOR_PTRS(node)				\
898 	AC_INTERFACE_HEADER_DESCRIPTOR_PTR(node)				\
899 	ENTITY_HEADERS_PTRS(node)						\
900 	IF_ENABLED(DT_PROP(node, interrupt_endpoint), (				\
901 		AC_ENDPOINT_DESCRIPTOR_PTR(node)))
902 
903 #define UAC2_AUDIO_CONTROL_FS_DESCRIPTOR_PTRS(node)				\
904 	AC_INTERFACE_FS_DESCRIPTOR_PTR(node)					\
905 	UAC2_AUDIO_CONTROL_COMMON_DESCRIPTOR_PTRS(node)
906 
907 #define UAC2_AUDIO_CONTROL_HS_DESCRIPTOR_PTRS(node)				\
908 	AC_INTERFACE_HS_DESCRIPTOR_PTR(node)					\
909 	UAC2_AUDIO_CONTROL_COMMON_DESCRIPTOR_PTRS(node)
910 
911 #define UAC2_DESCRIPTOR_ARRAYS(node)						\
912 	UAC2_INTERFACE_ASSOCIATION_DESCRIPTOR_ARRAY(node)			\
913 	UAC2_AUDIO_CONTROL_DESCRIPTOR_ARRAYS(node)				\
914 	DT_FOREACH_CHILD(node, AS_DESCRIPTORS_ARRAYS_IF_AUDIOSTREAMING)
915 
916 #define UAC2_FS_DESCRIPTOR_PTRS(node)						\
917 	UAC2_INTERFACE_ASSOCIATION_FS_DESCRIPTOR_PTR(node)			\
918 	UAC2_AUDIO_CONTROL_FS_DESCRIPTOR_PTRS(node)				\
919 	DT_FOREACH_CHILD(node, AS_FS_DESCRIPTORS_PTRS_IF_AUDIOSTREAMING)	\
920 	NULL
921 
922 #define UAC2_HS_DESCRIPTOR_PTRS(node)						\
923 	UAC2_INTERFACE_ASSOCIATION_HS_DESCRIPTOR_PTR(node)			\
924 	UAC2_AUDIO_CONTROL_HS_DESCRIPTOR_PTRS(node)				\
925 	DT_FOREACH_CHILD(node, AS_HS_DESCRIPTORS_PTRS_IF_AUDIOSTREAMING)	\
926 	NULL
927 
928 #define UAC2_FS_DESCRIPTOR_PTRS_ARRAY(node)					\
929 	COND_CODE_1(UAC2_ALLOWED_AT_FULL_SPEED(node),				\
930 		({UAC2_FS_DESCRIPTOR_PTRS(node)}), ({NULL}))
931 
932 #define UAC2_HS_DESCRIPTOR_PTRS_ARRAY(node)					\
933 	COND_CODE_1(UAC2_ALLOWED_AT_HIGH_SPEED(node),				\
934 		({UAC2_HS_DESCRIPTOR_PTRS(node)}), ({NULL}))
935 
936 /* Helper macros to determine endpoint descriptor offset within descriptor set */
937 #define COUNT_PTRS(...) sizeof((struct usb_desc_header *[]){__VA_ARGS__})	\
938 	/ sizeof(struct usb_desc_header *)
939 
940 #define COUNT_AS_DESCRIPTORS_UP_TO_IDX(node, idx)				\
941 	(COUNT_PTRS(COND_CODE_1(UAC2_ALLOWED_AT_FULL_SPEED(DT_PARENT(node)),	\
942 		(AS_FS_DESCRIPTORS_PTRS_IF_AUDIOSTREAMING(node)),		\
943 		(AS_HS_DESCRIPTORS_PTRS_IF_AUDIOSTREAMING(node))))) *		\
944 	(DT_NODE_CHILD_IDX(node) <= idx)
945 
946 #define UAC2_DESCRIPTOR_AS_DESC_END_COUNT(node)					\
947 	(COUNT_PTRS(COND_CODE_1(UAC2_ALLOWED_AT_FULL_SPEED(DT_PARENT(node)), (	\
948 		UAC2_INTERFACE_ASSOCIATION_FS_DESCRIPTOR_PTR(DT_PARENT(node))	\
949 		UAC2_AUDIO_CONTROL_FS_DESCRIPTOR_PTRS(DT_PARENT(node))		\
950 	), (									\
951 		UAC2_INTERFACE_ASSOCIATION_HS_DESCRIPTOR_PTR(DT_PARENT(node))	\
952 		UAC2_AUDIO_CONTROL_HS_DESCRIPTOR_PTRS(DT_PARENT(node))		\
953 	)))) + DT_FOREACH_CHILD_SEP_VARGS(DT_PARENT(node),			\
954 		COUNT_AS_DESCRIPTORS_UP_TO_IDX, (+),				\
955 		DT_NODE_CHILD_IDX(node))
956 
957 #define AS_ISOCHRONOUS_DATA_ENDPOINT_DESCRIPTORS_COUNT(node)			\
958 	COUNT_PTRS(COND_CODE_1(UAC2_ALLOWED_AT_FULL_SPEED(DT_PARENT(node)), (	\
959 		AS_ISOCHRONOUS_DATA_ENDPOINT_FS_DESCRIPTORS_PTRS(node)		\
960 	), (									\
961 		AS_ISOCHRONOUS_DATA_ENDPOINT_HS_DESCRIPTORS_PTRS(node)		\
962 	)))
963 
964 #define AS_EXPLICIT_FEEDBACK_ENDPOINT_DESCRIPTOR_COUNT(node)			\
965 	COND_CODE_1(AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node), (COUNT_PTRS(	\
966 		COND_CODE_1(UAC2_ALLOWED_AT_FULL_SPEED(DT_PARENT(node)), (	\
967 			AS_EXPLICIT_FEEDBACK_ENDPOINT_FS_DESCRIPTOR_PTR(node)	\
968 		), (								\
969 			AS_EXPLICIT_FEEDBACK_ENDPOINT_HS_DESCRIPTOR_PTR(node)	\
970 		))								\
971 	)), (0))
972 
973 /* Return index inside UAC2_FS_DESCRIPTOR_PTRS(DT_PARENT(node)) and/or
974  * UAC2_HS_DESCRIPTOR_PTRS(DT_PARENT(node)) pointing to data endpoint
975  * descriptor belonging to given AudioStreaming interface node.
976  *
977  * It is programmer error to call this macro with node other than AudioStreaming
978  * or when AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node) is 0.
979  */
980 #define UAC2_DESCRIPTOR_AS_DATA_EP_INDEX(node)					\
981 	UAC2_DESCRIPTOR_AS_DESC_END_COUNT(node)					\
982 	- AS_EXPLICIT_FEEDBACK_ENDPOINT_DESCRIPTOR_COUNT(node)			\
983 	- AS_ISOCHRONOUS_DATA_ENDPOINT_DESCRIPTORS_COUNT(node)
984 
985 /* Return index inside UAC2_FS_DESCRIPTOR_PTRS(DT_PARENT(node)) and/or
986  * UAC2_HS_DESCRIPTOR_PTRS(DT_PARENT(node)) pointing to feedback endpoint
987  * descriptor belonging to given AudioStreaming interface node.
988  *
989  * It is programmer error to call this macro with node other than AudioStreaming
990  * or when AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node) is 0.
991  */
992 #define UAC2_DESCRIPTOR_AS_FEEDBACK_EP_INDEX(node)				\
993 	UAC2_DESCRIPTOR_AS_DESC_END_COUNT(node)					\
994 	- AS_EXPLICIT_FEEDBACK_ENDPOINT_DESCRIPTOR_COUNT(node)
995 
996 /* Helper macros to validate USB Audio Class 2 devicetree entries.
997  * Macros above do rely on the assumptions checked below.
998  */
999 #define VALIDATE_INPUT_TERMINAL_ASSOCIATION(entity)				\
1000 	UTIL_OR(UTIL_NOT(DT_NODE_HAS_PROP(entity, assoc_terminal)),		\
1001 		DT_NODE_HAS_COMPAT(DT_PROP(entity, assoc_terminal),		\
1002 			zephyr_uac2_output_terminal))
1003 
1004 #define VALIDATE_OUTPUT_TERMINAL_ASSOCIATION(entity)				\
1005 	UTIL_OR(UTIL_NOT(DT_NODE_HAS_PROP(entity, assoc_terminal)),		\
1006 		DT_NODE_HAS_COMPAT(DT_PROP(entity, assoc_terminal),		\
1007 			zephyr_uac2_input_terminal))
1008 
1009 #define VALIDATE_OUTPUT_TERMINAL_DATA_SOURCE(entity)				\
1010 	UTIL_OR(DT_NODE_HAS_COMPAT(DT_PROP(entity, data_source),		\
1011 			zephyr_uac2_input_terminal),				\
1012 		DT_NODE_HAS_COMPAT(DT_PROP(entity, data_source),		\
1013 			zephyr_uac2_feature_unit))
1014 
1015 #define VALIDATE_FEATURE_UNIT_DATA_SOURCE(entity)				\
1016 	DT_NODE_HAS_COMPAT(DT_PROP(entity, data_source),			\
1017 		zephyr_uac2_input_terminal)
1018 
1019 #define BUILD_ASSERT_FEATURE_UNIT_CONTROL(fu, control)				\
1020 	BUILD_ASSERT(UTIL_OR(UTIL_NOT(DT_NODE_HAS_PROP(fu, control)),		\
1021 		DT_PROP_LEN(fu, control) <= 1 + FEATURE_UNIT_NUM_CHANNELS(fu)),	\
1022 		"Feature Unit " DT_NODE_PATH(fu) " has "			\
1023 		STRINGIFY(FEATURE_UNIT_NUM_CHANNELS(fu)) " logical channel(s) "	\
1024 		"but its property " #control " has "				\
1025 		STRINGIFY(DT_PROP_LEN(fu, control)) " values"			\
1026 	);
1027 
1028 #define BUILD_ASSERT_FEATURE_UNIT_CONTROLS_LENGTH(entity)			\
1029 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, mute_control)			\
1030 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, volume_control)		\
1031 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, bass_control)			\
1032 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, mid_control)			\
1033 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, treble_control)		\
1034 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, graphic_equalizer_control)	\
1035 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, automatic_gain_control)	\
1036 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, delay_control)		\
1037 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, bass_boost_control)		\
1038 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, loudness_control)		\
1039 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, input_gain_control)		\
1040 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, input_gain_pad_control)	\
1041 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, phase_inverter_control)	\
1042 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, underflow_control)		\
1043 	BUILD_ASSERT_FEATURE_UNIT_CONTROL(entity, overflow_control)
1044 
1045 #define NEEDS_SUBSLOT_SIZE_AND_BIT_RESOLUTION(node) UTIL_OR(			\
1046 	UTIL_OR(IS_EQ(AUDIO_STREAMING_FORMAT_TYPE(node), FORMAT_TYPE_I),	\
1047 		IS_EQ(AUDIO_STREAMING_FORMAT_TYPE(node), FORMAT_TYPE_III)),	\
1048 	UTIL_OR(IS_EQ(AUDIO_STREAMING_FORMAT_TYPE(node), EXT_FORMAT_TYPE_I),	\
1049 		IS_EQ(AUDIO_STREAMING_FORMAT_TYPE(node), EXT_FORMAT_TYPE_III)))
1050 
1051 #define VALIDATE_SUBSLOT_SIZE(node)						\
1052 	(DT_PROP(node, subslot_size) >= 1 && DT_PROP(node, subslot_size) <= 4)
1053 
1054 #define VALIDATE_BIT_RESOLUTION(node)						\
1055 	(DT_PROP(node, bit_resolution) <= (DT_PROP(node, subslot_size) * 8))
1056 
1057 #define VALIDATE_LINKED_TERMINAL(node)						\
1058 	UTIL_OR(DT_NODE_HAS_COMPAT(DT_PROP(node, linked_terminal),		\
1059 		zephyr_uac2_input_terminal),					\
1060 		DT_NODE_HAS_COMPAT(DT_PROP(node, linked_terminal),		\
1061 		zephyr_uac2_output_terminal))
1062 
1063 #define VALIDATE_AS_BANDWIDTH(node)						\
1064 	IF_ENABLED(UAC2_ALLOWED_AT_FULL_SPEED(DT_PARENT(node)),	(		\
1065 		BUILD_ASSERT(AS_FS_DATA_EP_MAX_PACKET_SIZE(node) <= 1023,	\
1066 			"Full-Speed bandwidth exceeded");			\
1067 	))									\
1068 	IF_ENABLED(UAC2_ALLOWED_AT_HIGH_SPEED(DT_PARENT(node)), (		\
1069 		BUILD_ASSERT(USB_TPL_IS_VALID(AS_HS_DATA_EP_TPL(node)),		\
1070 			"High-Speed bandwidth exceeded");			\
1071 	))
1072 
1073 #define VALIDATE_NODE(node)							\
1074 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_clock_source), (	\
1075 		BUILD_ASSERT(DT_PROP_LEN(node, sampling_frequencies),		\
1076 			"Sampling frequencies array must not be empty");	\
1077 		BUILD_ASSERT(IS_ARRAY_SORTED(node, sampling_frequencies),	\
1078 			"Sampling frequencies array must be sorted ascending");	\
1079 	))									\
1080 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_input_terminal), (	\
1081 		BUILD_ASSERT(!((SPATIAL_LOCATIONS_U32(node) & BIT(31))) ||	\
1082 			SPATIAL_LOCATIONS_U32(node) == BIT(31),			\
1083 			"Raw Data set alongside other spatial locations");	\
1084 		BUILD_ASSERT(VALIDATE_INPUT_TERMINAL_ASSOCIATION(node),		\
1085 			"Terminals associations must be Input<->Output");	\
1086 	))									\
1087 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_output_terminal), (	\
1088 		BUILD_ASSERT(VALIDATE_OUTPUT_TERMINAL_ASSOCIATION(node),	\
1089 			"Terminals associations must be Input<->Output");	\
1090 		BUILD_ASSERT(VALIDATE_OUTPUT_TERMINAL_DATA_SOURCE(node),	\
1091 			"Unsupported Output Terminal data source");		\
1092 	))									\
1093 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_feature_unit), (	\
1094 		BUILD_ASSERT(VALIDATE_FEATURE_UNIT_DATA_SOURCE(node),		\
1095 			"Unsupported Feature Unit data source");		\
1096 		BUILD_ASSERT_FEATURE_UNIT_CONTROLS_LENGTH(node);		\
1097 	))									\
1098 	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
1099 		BUILD_ASSERT(VALIDATE_LINKED_TERMINAL(node),			\
1100 			"Linked Terminal must be Input or Output Terminal");	\
1101 		BUILD_ASSERT(!NEEDS_SUBSLOT_SIZE_AND_BIT_RESOLUTION(node) ||	\
1102 			VALIDATE_SUBSLOT_SIZE(node),				\
1103 			"Subslot Size can only be 1, 2, 3 or 4");		\
1104 		BUILD_ASSERT(!NEEDS_SUBSLOT_SIZE_AND_BIT_RESOLUTION(node) ||	\
1105 			VALIDATE_BIT_RESOLUTION(node),				\
1106 			"Bit Resolution must fit inside Subslot Size");		\
1107 		BUILD_ASSERT(!DT_PROP(node, implicit_feedback) ||		\
1108 			!AS_IS_SOF_SYNCHRONIZED(node),				\
1109 			"Implicit feedback on SOF synchronized clock");		\
1110 		IF_ENABLED(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node), (		\
1111 			VALIDATE_AS_BANDWIDTH(node)))				\
1112 	))
1113 
1114 #define VALIDATE_INSTANCE(uac2)							\
1115 	BUILD_ASSERT(DT_PROP(uac2, full_speed) || DT_PROP(uac2, high_speed),	\
1116 		"Instance must be allowed to operate at least at one speed");	\
1117 	DT_FOREACH_CHILD(uac2, VALIDATE_NODE)
1118 
1119 #endif /* ZEPHYR_INCLUDE_USBD_UAC2_MACROS_H_ */
1120