1 /*
2  * USB audio class internal header
3  *
4  * Copyright (c) 2020 Nordic Semiconductor ASA
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 /**
10  * @file
11  * @brief USB Audio Device Class internal header
12  *
13  * This header file is used to store internal configuration
14  * defines.
15  */
16 
17 #ifndef ZEPHYR_INCLUDE_USB_CLASS_AUDIO_INTERNAL_H_
18 #define ZEPHYR_INCLUDE_USB_CLASS_AUDIO_INTERNAL_H_
19 
20 #define DUMMY_API  (const void *)1
21 
22 #define USB_PASSIVE_IF_DESC_SIZE sizeof(struct usb_if_descriptor)
23 #define USB_AC_CS_IF_DESC_SIZE sizeof(struct as_cs_interface_descriptor)
24 #define USB_FORMAT_TYPE_I_DESC_SIZE sizeof(struct format_type_i_descriptor)
25 #define USB_STD_AS_AD_EP_DESC_SIZE sizeof(struct std_as_ad_endpoint_descriptor)
26 #define USB_CS_AS_AD_EP_DESC_SIZE sizeof(struct cs_as_ad_ep_descriptor)
27 #define USB_ACTIVE_IF_DESC_SIZE (USB_PASSIVE_IF_DESC_SIZE + \
28 				 USB_AC_CS_IF_DESC_SIZE + \
29 				 USB_FORMAT_TYPE_I_DESC_SIZE + \
30 				 USB_STD_AS_AD_EP_DESC_SIZE + \
31 				 USB_CS_AS_AD_EP_DESC_SIZE)
32 
33 #define INPUT_TERMINAL_DESC_SIZE sizeof(struct input_terminal_descriptor)
34 #define OUTPUT_TERMINAL_DESC_SIZE sizeof(struct output_terminal_descriptor)
35 
36 #define BMA_CONTROLS_OFFSET 6
37 #define FU_FIXED_ELEMS_SIZE 7
38 
39 /* Macros for maintaining features of feature unit entity */
40 #define FEATURE_MUTE_SIZE			0x01
41 #define FEATURE_VOLUME_SIZE			0x02
42 #define FEATURE_BASS_SIZE			0x01
43 #define FEATURE_MID_SIZE			0x01
44 #define FEATURE_TREBLE_SIZE			0x01
45 #define FEATURE_TONE_CONTROL_SIZE (FEATURE_BASS_SIZE +\
46 				   FEATURE_MID_SIZE + \
47 				   FEATURE_TREBLE_SIZE)
48 #define FEATURE_GRAPHIC_EQUALIZER_SIZE		0x01
49 #define FEATURE_AUTOMATIC_GAIN_CONTROL_SIZE	0x01
50 #define FEATURE_DELAY_SIZE			0x02
51 #define FEATURE_BASS_BOOST_SIZE			0x01
52 #define FEATURE_LOUDNESS_SIZE			0x01
53 
54 #define POS_MUTE		   0
55 #define POS_VOLUME		   (POS_MUTE + FEATURE_MUTE_SIZE)
56 #define POS_BASS		   (POS_VOLUME + FEATURE_VOLUME_SIZE)
57 #define POS_MID			   (POS_BASS + FEATURE_BASS_SIZE)
58 #define POS_TREBLE		   (POS_MID + FEATURE_MID_SIZE)
59 #define POS_GRAPHIC_EQUALIZER	   (POS_TREBLE + FEATURE_TREBLE_SIZE)
60 #define POS_AUTOMATIC_GAIN_CONTROL (POS_GRAPHIC_EQUALIZER + \
61 					FEATURE_GRAPHIC_EQUALIZER_SIZE)
62 #define POS_DELAY		   (POS_AUTOMATIC_GAIN_CONTROL + \
63 					FEATURE_AUTOMATIC_GAIN_CONTROL_SIZE)
64 #define POS_BASS_BOOST		   (POS_DELAY + FEATURE_DELAY_SIZE)
65 #define POS_LOUDNESS		   (POS_BASS_BOOST + FEATURE_BASS_BOOST_SIZE)
66 
67 #define POS(prop, ch_idx, ch_cnt) (ch_cnt * POS_##prop + \
68 				  (ch_idx * FEATURE_##prop##_SIZE))
69 #define LEN(ch_cnt, prop) (ch_cnt * FEATURE_##prop##_SIZE)
70 
71 /* Names of compatibles used for configuration of the device */
72 #define COMPAT_HP  usb_audio_hp
73 #define COMPAT_MIC usb_audio_mic
74 #define COMPAT_HS  usb_audio_hs
75 
76 #define HEADPHONES_DEVICE_COUNT  DT_NUM_INST_STATUS_OKAY(COMPAT_HP)
77 #define MICROPHONE_DEVICE_COUNT  DT_NUM_INST_STATUS_OKAY(COMPAT_MIC)
78 #define HEADSET_DEVICE_COUNT     DT_NUM_INST_STATUS_OKAY(COMPAT_HS)
79 
80 #define IF_USB_AUDIO_PROP_HP(i, prop, bitmask) \
81 	COND_CODE_1(DT_PROP(DT_INST(i, COMPAT_HP), prop), (bitmask), (0))
82 #define IF_USB_AUDIO_PROP_MIC(i, prop, bitmask) \
83 	COND_CODE_1(DT_PROP(DT_INST(i, COMPAT_MIC), prop), (bitmask), (0))
84 #define IF_USB_AUDIO_PROP_HS_HP(i, prop, bitmask) \
85 	COND_CODE_1(DT_PROP(DT_INST(i, COMPAT_HS), hp_##prop), (bitmask), (0))
86 #define IF_USB_AUDIO_PROP_HS_MIC(i, prop, bitmask) \
87 	COND_CODE_1(DT_PROP(DT_INST(i, COMPAT_HS), mic_##prop), (bitmask), (0))
88 #define IF_USB_AUDIO_PROP(dev, i, prop, bitmask) \
89 	IF_USB_AUDIO_PROP_##dev(i, prop, bitmask)
90 
91 /* Macro for getting the bitmask of configured channels for given device */
92 #define CH_CFG(dev, i) (0x0000			 \
93 | IF_USB_AUDIO_PROP(dev, i, channel_l,   BIT(0)) \
94 | IF_USB_AUDIO_PROP(dev, i, channel_r,   BIT(1)) \
95 | IF_USB_AUDIO_PROP(dev, i, channel_c,   BIT(2)) \
96 | IF_USB_AUDIO_PROP(dev, i, channel_lfe, BIT(3)) \
97 | IF_USB_AUDIO_PROP(dev, i, channel_ls,  BIT(4)) \
98 | IF_USB_AUDIO_PROP(dev, i, channel_rs,  BIT(5)) \
99 | IF_USB_AUDIO_PROP(dev, i, channel_lc,  BIT(6)) \
100 | IF_USB_AUDIO_PROP(dev, i, channel_rc,  BIT(7)) \
101 | IF_USB_AUDIO_PROP(dev, i, channel_s,   BIT(8)) \
102 | IF_USB_AUDIO_PROP(dev, i, channel_sl,  BIT(9)) \
103 | IF_USB_AUDIO_PROP(dev, i, channel_sr,  BIT(10))\
104 | IF_USB_AUDIO_PROP(dev, i, channel_t,   BIT(11))\
105 )
106 
107 /* Macro for getting the number of configured channels for given device.
108  * Master channel (0) excluded.
109  */
110 #define CH_CNT(dev, i) (0		   \
111 + IF_USB_AUDIO_PROP(dev, i, channel_l,   1)\
112 + IF_USB_AUDIO_PROP(dev, i, channel_r,   1)\
113 + IF_USB_AUDIO_PROP(dev, i, channel_c,   1)\
114 + IF_USB_AUDIO_PROP(dev, i, channel_lfe, 1)\
115 + IF_USB_AUDIO_PROP(dev, i, channel_ls,  1)\
116 + IF_USB_AUDIO_PROP(dev, i, channel_rs,  1)\
117 + IF_USB_AUDIO_PROP(dev, i, channel_lc,  1)\
118 + IF_USB_AUDIO_PROP(dev, i, channel_rc,  1)\
119 + IF_USB_AUDIO_PROP(dev, i, channel_s,   1)\
120 + IF_USB_AUDIO_PROP(dev, i, channel_sl,  1)\
121 + IF_USB_AUDIO_PROP(dev, i, channel_sr,  1)\
122 + IF_USB_AUDIO_PROP(dev, i, channel_t,   1)\
123 )
124 
125 /* Macro for getting bitmask of supported features for given device */
126 #define FEATURES(dev, i) (0x0000					    \
127 | IF_USB_AUDIO_PROP(dev, i, feature_mute,		    BIT(0))	    \
128 | IF_USB_AUDIO_PROP(dev, i, feature_volume,		    BIT(1))	    \
129 | IF_USB_AUDIO_PROP(dev, i, feature_tone_control,  BIT(2) | BIT(3) | BIT(4))\
130 | IF_USB_AUDIO_PROP(dev, i, feature_graphic_equalizer,	    BIT(5))	    \
131 | IF_USB_AUDIO_PROP(dev, i, feature_automatic_gain_control, BIT(6))	    \
132 | IF_USB_AUDIO_PROP(dev, i, feature_delay,		    BIT(7))	    \
133 | IF_USB_AUDIO_PROP(dev, i, feature_bass_boost,		    BIT(8))	    \
134 | IF_USB_AUDIO_PROP(dev, i, feature_loudness,		    BIT(9))	    \
135 )
136 
137 /* Macro for getting required size to store values for supported features. */
138 #define FEATURES_SIZE(dev, i) ((CH_CNT(dev, i) + 1) * (0x0000	\
139 + IF_USB_AUDIO_PROP(dev, i, feature_mute,			\
140 			    FEATURE_MUTE_SIZE)			\
141 + IF_USB_AUDIO_PROP(dev, i, feature_volume,			\
142 			    FEATURE_VOLUME_SIZE)		\
143 + IF_USB_AUDIO_PROP(dev, i, feature_tone_control,		\
144 			    FEATURE_TONE_CONTROL_SIZE)		\
145 + IF_USB_AUDIO_PROP(dev, i, feature_graphic_equalizer,		\
146 			    FEATURE_GRAPHIC_EQUALIZER_SIZE)	\
147 + IF_USB_AUDIO_PROP(dev, i, feature_automatic_gain_control,	\
148 			    FEATURE_AUTOMATIC_GAIN_CONTROL_SIZE)\
149 + IF_USB_AUDIO_PROP(dev, i, feature_delay,			\
150 			    FEATURE_DELAY_SIZE)			\
151 + IF_USB_AUDIO_PROP(dev, i, feature_bass_boost,			\
152 			    FEATURE_BASS_BOOST_SIZE)		\
153 + IF_USB_AUDIO_PROP(dev, i, feature_loudness,			\
154 			    FEATURE_LOUDNESS_SIZE)		\
155 ))
156 
157 #define GET_RES_HP(i) DT_PROP(DT_INST(i, COMPAT_HP), resolution)
158 #define GET_RES_MIC(i) DT_PROP(DT_INST(i, COMPAT_MIC), resolution)
159 #define GET_RES_HS_HP(i) DT_PROP(DT_INST(i, COMPAT_HS), hp_resolution)
160 #define GET_RES_HS_MIC(i) DT_PROP(DT_INST(i, COMPAT_HS), mic_resolution)
161 #define GET_RES(dev, i) GET_RES_##dev(i)
162 
163 #define GET_VOLUME_HS(i, prop) DT_PROP_OR(DT_INST(i, COMPAT_HS), prop, 0)
164 #define GET_VOLUME_HP(i, prop) DT_PROP_OR(DT_INST(i, COMPAT_HP), prop, 0)
165 #define GET_VOLUME_MIC(i, prop) DT_PROP_OR(DT_INST(i, COMPAT_MIC), prop, 0)
166 #define GET_VOLUME(dev, i, prop) GET_VOLUME_##dev(i, prop)
167 
168 #define GET_RATE_HP(i) DT_PROP(DT_INST(i, COMPAT_HP), sample_rate_hz)
169 #define GET_RATE_MIC(i) DT_PROP(DT_INST(i, COMPAT_MIC), sample_rate_hz)
170 #define GET_RATE_HS_HP(i) DT_PROP(DT_INST(i, COMPAT_HS), hp_sample_rate_hz)
171 #define GET_RATE_HS_MIC(i) DT_PROP(DT_INST(i, COMPAT_HS), mic_sample_rate_hz)
172 #define GET_RATE(dev, i) GET_RATE_##dev(i)
173 
174 #define GET_INTERVAL_HP(i) DT_PROP(DT_INST(i, COMPAT_HP), polling_interval)
175 #define GET_INTERVAL_MIC(i) DT_PROP(DT_INST(i, COMPAT_MIC), polling_interval)
176 #define GET_INTERVAL_HS_HP(i) DT_PROP(DT_INST(i, COMPAT_HS), hp_polling_interval)
177 #define GET_INTERVAL_HS_MIC(i) DT_PROP(DT_INST(i, COMPAT_HS), mic_polling_interval)
178 #define GET_INTERVAL(dev, i) GET_INTERVAL_##dev(i)
179 
180 #define SYNC_TYPE_HP(i)     3
181 #define SYNC_TYPE_MIC(i)    DT_ENUM_IDX(DT_INST(i, COMPAT_MIC), sync_type)
182 #define SYNC_TYPE_HS_HP(i)  3
183 #define SYNC_TYPE_HS_MIC(i) DT_ENUM_IDX(DT_INST(i, COMPAT_HS), mic_sync_type)
184 #define SYNC_TYPE(dev, i) (SYNC_TYPE_##dev(i) << 2)
185 
186 #define EP_SIZE(dev, i) \
187 	(DIV_ROUND_UP((GET_RES(dev, i)/8 * CH_CNT(dev, i) * GET_RATE(dev, i)), 1000))
188 
189 /* *_ID() macros are used to give proper Id to each entity describing
190  * the device. Entities Id must start from 1 that's why 1 is added.
191  * Multiplication by 3 for HP/MIC comes from the fact that 3 entities are
192  * required to describe the device, 6 in case of HS.
193  */
194 #define HP_ID(i) ((3*i) + 1)
195 #define MIC_ID(i) ((3*(HEADPHONES_DEVICE_COUNT + i)) + 1)
196 #define HS_ID(i) ((3*(HEADPHONES_DEVICE_COUNT + \
197 		      MICROPHONE_DEVICE_COUNT)) + 6*i + 1)
198 
199 /* *_LINK() macros are used to properly connect relevant audio streaming
200  * class specific interface with valid entity. In case of Headphones this
201  * will always be 1st entity describing the device (Input terminal). This
202  * is where addition of 1 comes from. In case of Headphones thill will always
203  * be 3rd entity (Output terminal) - addition of 3.
204  */
205 #define HP_LINK(i) ((3*i) + 1)
206 #define MIC_LINK(i) ((3*(HEADPHONES_DEVICE_COUNT + i)) + 3)
207 
208 /**
209  * Addressable logical object inside an audio function.
210  * Entity is one of: Terminal or Unit.
211  * Refer to 1.4 Terms and Abbreviations from audio10.pdf
212  */
213 struct usb_audio_entity {
214 	enum usb_audio_cs_ac_int_desc_subtypes subtype;
215 	uint8_t id;
216 };
217 
218 /**
219  * @warning Size of baInterface is 2 just to make it usable
220  * for all kind of devices: headphones, microphone and headset.
221  * Actual size of the struct should be checked by reading
222  * .bLength.
223  */
224 struct cs_ac_if_descriptor {
225 	uint8_t bLength;
226 	uint8_t bDescriptorType;
227 	uint8_t bDescriptorSubtype;
228 	uint16_t bcdADC;
229 	uint16_t wTotalLength;
230 	uint8_t bInCollection;
231 	uint8_t baInterfaceNr[2];
232 } __packed;
233 
234 struct input_terminal_descriptor {
235 	uint8_t bLength;
236 	uint8_t bDescriptorType;
237 	uint8_t bDescriptorSubtype;
238 	uint8_t bTerminalID;
239 	uint16_t wTerminalType;
240 	uint8_t bAssocTerminal;
241 	uint8_t bNrChannels;
242 	uint16_t wChannelConfig;
243 	uint8_t iChannelNames;
244 	uint8_t iTerminal;
245 } __packed;
246 
247 /**
248  * @note Size of Feature unit descriptor is not fixed.
249  * This structure is just a helper not a common type.
250  */
251 struct feature_unit_descriptor {
252 	uint8_t bLength;
253 	uint8_t bDescriptorType;
254 	uint8_t bDescriptorSubtype;
255 	uint8_t bUnitID;
256 	uint8_t bSourceID;
257 	uint8_t bControlSize;
258 	uint16_t bmaControls[1];
259 } __packed;
260 
261 struct output_terminal_descriptor {
262 	uint8_t bLength;
263 	uint8_t bDescriptorType;
264 	uint8_t bDescriptorSubtype;
265 	uint8_t bTerminalID;
266 	uint16_t wTerminalType;
267 	uint8_t bAssocTerminal;
268 	uint8_t bSourceID;
269 	uint8_t iTerminal;
270 } __packed;
271 
272 struct as_cs_interface_descriptor {
273 	uint8_t  bLength;
274 	uint8_t  bDescriptorType;
275 	uint8_t  bDescriptorSubtype;
276 	uint8_t  bTerminalLink;
277 	uint8_t  bDelay;
278 	uint16_t wFormatTag;
279 } __packed;
280 
281 struct format_type_i_descriptor {
282 	uint8_t bLength;
283 	uint8_t bDescriptorType;
284 	uint8_t bDescriptorSubtype;
285 	uint8_t bFormatType;
286 	uint8_t bNrChannels;
287 	uint8_t bSubframeSize;
288 	uint8_t bBitResolution;
289 	uint8_t bSamFreqType;
290 	uint8_t tSamFreq[3];
291 } __packed;
292 
293 struct std_as_ad_endpoint_descriptor {
294 	uint8_t bLength;
295 	uint8_t bDescriptorType;
296 	uint8_t bEndpointAddress;
297 	uint8_t bmAttributes;
298 	uint16_t wMaxPacketSize;
299 	uint8_t bInterval;
300 	uint8_t bRefresh;
301 	uint8_t bSynchAddress;
302 } __packed;
303 
304 struct cs_as_ad_ep_descriptor {
305 	uint8_t bLength;
306 	uint8_t bDescriptorType;
307 	uint8_t bDescriptorSubtype;
308 	uint8_t bmAttributes;
309 	uint8_t bLockDelayUnits;
310 	uint16_t wLockDelay;
311 } __packed;
312 
313 #define DECLARE_HEADER(dev, i, ifaces)	\
314 struct dev##_cs_ac_if_descriptor_##i {	\
315 	uint8_t bLength;			\
316 	uint8_t bDescriptorType;		\
317 	uint8_t bDescriptorSubtype;	\
318 	uint16_t bcdADC;			\
319 	uint16_t wTotalLength;		\
320 	uint8_t bInCollection;		\
321 	uint8_t baInterfaceNr[ifaces];	\
322 } __packed
323 
324 #define DECLARE_FEATURE_UNIT(dev, i)		\
325 struct dev##_feature_unit_descriptor_##i {	\
326 	uint8_t bLength;				\
327 	uint8_t bDescriptorType;			\
328 	uint8_t bDescriptorSubtype;		\
329 	uint8_t bUnitID;				\
330 	uint8_t bSourceID;				\
331 	uint8_t bControlSize;			\
332 	uint16_t bmaControls[CH_CNT(dev, i) + 1];	\
333 	uint8_t iFeature;				\
334 } __packed
335 
336 #define INIT_IAD(iface_subclass, if_cnt)			\
337 {								\
338 	.bLength = sizeof(struct usb_association_descriptor),	\
339 	.bDescriptorType = USB_DESC_INTERFACE_ASSOC,		\
340 	.bFirstInterface = 0,					\
341 	.bInterfaceCount = if_cnt,				\
342 	.bFunctionClass = USB_BCC_AUDIO,			\
343 	.bFunctionSubClass = iface_subclass,			\
344 	.bFunctionProtocol = 0,					\
345 	.iFunction = 0,						\
346 }
347 
348 #define USB_AUDIO_IAD_DECLARE struct usb_association_descriptor iad;
349 #define USB_AUDIO_IAD(if_cnt)  .iad = INIT_IAD(USB_AUDIO_AUDIOCONTROL, if_cnt),
350 
351 #define DECLARE_DESCRIPTOR(dev, i, ifaces)				\
352 DECLARE_HEADER(dev, i, ifaces);						\
353 DECLARE_FEATURE_UNIT(dev, i);						\
354 struct dev##_descriptor_##i {						\
355 	USB_AUDIO_IAD_DECLARE						\
356 	struct usb_if_descriptor std_ac_interface;			\
357 	struct dev##_cs_ac_if_descriptor_##i cs_ac_interface;		\
358 	struct input_terminal_descriptor input_terminal;		\
359 	struct dev##_feature_unit_descriptor_##i feature_unit;		\
360 	struct output_terminal_descriptor output_terminal;		\
361 	struct usb_if_descriptor as_interface_alt_0;			\
362 	struct usb_if_descriptor as_interface_alt_1;			\
363 		struct as_cs_interface_descriptor as_cs_interface;	\
364 		struct format_type_i_descriptor format;			\
365 		struct std_as_ad_endpoint_descriptor std_ep;		\
366 		struct cs_as_ad_ep_descriptor cs_ep;			\
367 } __packed
368 
369 #define DECLARE_DESCRIPTOR_BIDIR(dev, i, ifaces)			\
370 DECLARE_HEADER(dev, i, ifaces);						\
371 DECLARE_FEATURE_UNIT(dev##_MIC, i);					\
372 DECLARE_FEATURE_UNIT(dev##_HP, i);					\
373 struct dev##_descriptor_##i {						\
374 	USB_AUDIO_IAD_DECLARE						\
375 	struct usb_if_descriptor std_ac_interface;			\
376 	struct dev##_cs_ac_if_descriptor_##i cs_ac_interface;		\
377 	struct input_terminal_descriptor input_terminal_0;		\
378 	struct dev##_MIC_feature_unit_descriptor_##i feature_unit_0;	\
379 	struct output_terminal_descriptor output_terminal_0;		\
380 	struct input_terminal_descriptor input_terminal_1;		\
381 	struct dev##_HP_feature_unit_descriptor_##i feature_unit_1;	\
382 	struct output_terminal_descriptor output_terminal_1;		\
383 	struct usb_if_descriptor as_interface_alt_0_0;			\
384 	struct usb_if_descriptor as_interface_alt_0_1;			\
385 		struct as_cs_interface_descriptor as_cs_interface_0;	\
386 		struct format_type_i_descriptor format_0;		\
387 		struct std_as_ad_endpoint_descriptor std_ep_0;		\
388 		struct cs_as_ad_ep_descriptor cs_ep_0;			\
389 	struct usb_if_descriptor as_interface_alt_1_0;			\
390 	struct usb_if_descriptor as_interface_alt_1_1;			\
391 		struct as_cs_interface_descriptor as_cs_interface_1;	\
392 		struct format_type_i_descriptor format_1;		\
393 		struct std_as_ad_endpoint_descriptor std_ep_1;		\
394 		struct cs_as_ad_ep_descriptor cs_ep_1;			\
395 } __packed
396 
397 #define INIT_STD_IF(iface_subclass, iface_num, alt_setting, eps_num)	\
398 {									\
399 	.bLength = sizeof(struct usb_if_descriptor),			\
400 	.bDescriptorType = USB_DESC_INTERFACE,				\
401 	.bInterfaceNumber = iface_num,					\
402 	.bAlternateSetting = alt_setting,				\
403 	.bNumEndpoints = eps_num,					\
404 	.bInterfaceClass = USB_BCC_AUDIO,				\
405 	.bInterfaceSubClass = iface_subclass,				\
406 	.bInterfaceProtocol = 0,					\
407 	.iInterface = 0,						\
408 }
409 
410 #define INIT_CS_AC_IF(dev, i, ifaces)					\
411 {									\
412 	.bLength = sizeof(struct dev##_cs_ac_if_descriptor_##i),	\
413 	.bDescriptorType = USB_DESC_CS_INTERFACE,			\
414 	.bDescriptorSubtype = USB_AUDIO_HEADER,				\
415 	.bcdADC = sys_cpu_to_le16(0x0100),				\
416 	.wTotalLength = sys_cpu_to_le16(				\
417 		sizeof(struct dev##_cs_ac_if_descriptor_##i) +		\
418 		INPUT_TERMINAL_DESC_SIZE +				\
419 		sizeof(struct dev##_feature_unit_descriptor_##i) +	\
420 		OUTPUT_TERMINAL_DESC_SIZE),				\
421 	.bInCollection = ifaces,					\
422 	.baInterfaceNr = {0},						\
423 }
424 
425 #define INIT_CS_AC_IF_BIDIR(dev, i, ifaces)				\
426 {									\
427 	.bLength = sizeof(struct dev##_cs_ac_if_descriptor_##i),	\
428 	.bDescriptorType = USB_DESC_CS_INTERFACE,			\
429 	.bDescriptorSubtype = USB_AUDIO_HEADER,				\
430 	.bcdADC = sys_cpu_to_le16(0x0100),				\
431 	.wTotalLength = sys_cpu_to_le16(				\
432 		sizeof(struct dev##_cs_ac_if_descriptor_##i) +		\
433 		2*INPUT_TERMINAL_DESC_SIZE +				\
434 		sizeof(struct dev##_MIC_feature_unit_descriptor_##i) +	\
435 		sizeof(struct dev##_HP_feature_unit_descriptor_##i) +	\
436 		2*OUTPUT_TERMINAL_DESC_SIZE),				\
437 	.bInCollection = ifaces,					\
438 	.baInterfaceNr = {0},						\
439 }
440 
441 #define INIT_IN_TERMINAL(dev, i, terminal_id, type)		\
442 {								\
443 	.bLength = INPUT_TERMINAL_DESC_SIZE,			\
444 	.bDescriptorType = USB_DESC_CS_INTERFACE,		\
445 	.bDescriptorSubtype = USB_AUDIO_INPUT_TERMINAL,		\
446 	.bTerminalID = terminal_id,				\
447 	.wTerminalType = sys_cpu_to_le16(type),			\
448 	.bAssocTerminal = 0,					\
449 	.bNrChannels = MAX(1, CH_CNT(dev, i)),			\
450 	.wChannelConfig = sys_cpu_to_le16(CH_CFG(dev, i)),	\
451 	.iChannelNames = 0,					\
452 	.iTerminal = 0,						\
453 }
454 
455 #define INIT_OUT_TERMINAL(terminal_id, source_id, type)	\
456 {							\
457 	.bLength = OUTPUT_TERMINAL_DESC_SIZE,		\
458 	.bDescriptorType = USB_DESC_CS_INTERFACE,	\
459 	.bDescriptorSubtype = USB_AUDIO_OUTPUT_TERMINAL,\
460 	.bTerminalID = terminal_id,			\
461 	.wTerminalType = sys_cpu_to_le16(type),		\
462 	.bAssocTerminal = 0,				\
463 	.bSourceID = source_id,				\
464 	.iTerminal = 0,					\
465 }
466 
467 /** refer to Table 4-7 from audio10.pdf
468  */
469 #define INIT_FEATURE_UNIT(dev, i, unit_id, source_id)			\
470 {									\
471 	.bLength = sizeof(struct dev##_feature_unit_descriptor_##i),	\
472 	.bDescriptorType = USB_DESC_CS_INTERFACE,			\
473 	.bDescriptorSubtype = USB_AUDIO_FEATURE_UNIT,			\
474 	.bUnitID = unit_id,						\
475 	.bSourceID = source_id,						\
476 	.bControlSize = sizeof(uint16_t),					\
477 	.bmaControls = { FEATURES(dev, i) },				\
478 	.iFeature = 0,							\
479 }
480 
481 /* Class-Specific AS Interface Descriptor 4.5.2 audio10.pdf */
482 #define INIT_AS_GENERAL(link)				\
483 {							\
484 	.bLength = USB_AC_CS_IF_DESC_SIZE,		\
485 	.bDescriptorType = USB_DESC_CS_INTERFACE,	\
486 	.bDescriptorSubtype = USB_AUDIO_AS_GENERAL,	\
487 	.bTerminalLink = link,				\
488 	.bDelay = 1,					\
489 	.wFormatTag = sys_cpu_to_le16(0x0001),		\
490 }
491 
492 #define SAMPLE_RATE(rate)			\
493 	{(((rate) >> 0) & 0xff), (((rate) >> 8) & 0xff), (((rate) >> 16) & 0xff)}
494 
495 /** Class-Specific AS Format Type Descriptor 4.5.3 audio10.pdf
496  *  For more information refer to 2.2.5 Type I Format Type Descriptor
497  *  from frmts10.pdf
498  */
499 #define INIT_AS_FORMAT_I(ch_cnt, res, rate)			\
500 {								\
501 	.bLength = sizeof(struct format_type_i_descriptor),	\
502 	.bDescriptorType = USB_DESC_CS_INTERFACE,		\
503 	.bDescriptorSubtype = USB_AUDIO_FORMAT_TYPE,		\
504 	.bFormatType = 0x01,					\
505 	.bNrChannels = MAX(1, ch_cnt),				\
506 	.bSubframeSize = res/8,					\
507 	.bBitResolution = res,					\
508 	.bSamFreqType = 1,					\
509 	.tSamFreq = SAMPLE_RATE(rate),				\
510 }
511 
512 #define INIT_STD_AS_AD_EP(dev, i, addr)					\
513 {									\
514 	.bLength = sizeof(struct std_as_ad_endpoint_descriptor),	\
515 	.bDescriptorType = USB_DESC_ENDPOINT,				\
516 	.bEndpointAddress = addr,					\
517 	.bmAttributes = (USB_DC_EP_ISOCHRONOUS | SYNC_TYPE(dev, i)),	\
518 	.wMaxPacketSize = sys_cpu_to_le16(EP_SIZE(dev, i)),		\
519 	.bInterval = GET_INTERVAL(dev, i),				\
520 	.bRefresh = 0x00,						\
521 	.bSynchAddress = 0x00,						\
522 }
523 
524 #define INIT_CS_AS_AD_EP					\
525 {								\
526 	.bLength = sizeof(struct cs_as_ad_ep_descriptor),	\
527 	.bDescriptorType = USB_DESC_CS_ENDPOINT,		\
528 	.bDescriptorSubtype = 0x01,				\
529 	.bmAttributes = 0x00,					\
530 	.bLockDelayUnits = 0x00,				\
531 	.wLockDelay = 0,					\
532 }
533 
534 #define INIT_EP_DATA(cb, addr)	\
535 	{			\
536 		.ep_cb = cb,	\
537 		.ep_addr = addr,\
538 	}
539 
540 #endif /* ZEPHYR_INCLUDE_USB_CLASS_AUDIO_INTERNAL_H_ */
541