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