This patch series adds support for additional alternate settings for UAC1/2 gadgets. See references [2] and [3] for discussions on the API. *** Userspace API *** * Add the ability to create c_alt.x and p_alt.x directories under the function with settings that are available per alternate mode. The existing API is preserved and used as defaults when creating c/p_alt.x. Subsequent changes to the function-wide settings don't change existing c/p_alt.x directories. If no directories for c/p_alt.1 exist, alternate setting 1 will continue to be created from the function-wide settings. Settings that can be changed per-alt-mode (bAlternateSetting): - name (iInterface - Interface Descriptor name) - chmask (wChannelConfig - Channel mask) - ssize (bSubframeSize - Sample size bytes) - terminal_type (wTerminalType - Terminal Type) - sync (OUT only) (bmAttributes - Endpoint Synch Type) - hs_bint (bInterval - Used for HS and above, 0=auto) - Terminal names (see below) * Add the ability to set terminal name strings. Defaults are the same as the hard-coded strings that were present in UAC1/2 functions. These are now present as p_/c_ function-wide variants and in p/c_alt.x directories. (Note: UAC1 defaults aren't the same as UAC2) These are now settable with: - it_name (iTerminal - Input Terminal name) - it_ch_name (iChannelNames - Input Terminal first channel name) - fu_vol_name (iFeature - Feature Unit, for mute/volume, name) - ot_name (iTerminal - Output Terminal name) * UAC1 specific UAPI changes (to bring it up to parity with UAC2) - Added support for c_sync (support for USB Out ASYNC mode) - Added support for p/c_terminal_type (note that these DO correct the order from UAC2 so they follow the device centric view, and align with the other c/p options) - Added p/c_hs_bint *** Descriptors *** * Strings are now dynamically allocated as needed. For simplicity the algorithm is O(n^2) and allocates the maximum table size (256) (2KB on 64-bit systems.) This allows multiple path descriptors to reuse the same string ids if they are all named the same. * Path descriptors (Input Terminal -> <Feature Unit> -> Output Terminal) are now created based on differences in settings. Any differences in names or chmask will create a new set of terminals. * Descriptors for each alternate setting are now attached to those settings and many global descriptors are removed. Maximum size for each alternate setting is calculated for its enpoints. All alternate settings use the same set of endpoint numbers though. * Differences from previously created descriptors with the default settings - String IDs are allocated differently. Referenced strings all match but have different numbers. - Unit/Terminal IDs are allocated differently. Source IDs/Associated Terminal numbers are different, but reference the same terminals. - UAC2 Terminal descriptors are not quite in the same order. Old order was IT, FU, IT, FU, OT, OT. Now it is IT, FU, OT, IT, FU, OT. This change in order doesn't really matter, but will show up if you look at a diff between the two. - UAC1 Endpoint wMaxPacketSize was hard-coded to 200. Calcluated value is now 196 for default settings. * UAC1 Specific Bug Fixes - LowSpeed interval is fixed (bInterval was 4 for all speeds) - SuperSpeed descriptors are fixed. The old implementation had only partial support for SuperSpeed and creates invalid descriptors in the default case. (Turning off volume/mute control is the only working case for SuperSpeed.) *** Back-end Functionality *** * Volume Mute Controls - When using a combination of alt modes that requires separate terminals the volume/mute functional unit must also be duplicated. This causes there to be multiple volume controls on the USB side. In this case, there is still only one volume/mute control on the ALSA side and all associated instances on the USB side are synchronized. (Changing any one of the associated volume/mute controls causes the others to be updated to the same value.) *** Remaining Work *** * Alternate settings aren't yet updating the u_audio back end so the function-wide settings are all that is used by the ALSA interface. This effectively means that changing any settings that affect the audio samples (ssize/chmask) won't yet pass good audio. * Testing. Defaults and a few random combination have been tested with the Dummy HCD driver (with patch [1] to allow isochronous endpoints) but no audio testing has been done yet (just UAPI and descriptor testing.) These are both pending my having a target that has an up-to-date kernel for some real hardware testing. This is in-progress but may take a bit to get working as my current device is running 4.19.168. *** Deficiencies (not planned to fix) *** * There appears to be no way to prevent removal of c_alt.x/p_alt.x while the function is bound. (This is not unique to these folders, as other folders may be removed after a function is bound and UDC set.) This doesn't appear to cause any critical failures, but removing c_alt.x/p_alt.x while the gadget is active will cause those alt modes to no longer function correctly. *** References *** [1] https://lore.kernel.org/linux-usb/20220126132249.2133168-1-m.grzeschik@xxxxxxxxxxxxxx/ Patch for partial ISOC support in dummy_hcd. As the patch mentions, this is only useful for validating non-ISOC parts of gadgets, but does allow them to bind for testing of descriptors at least. [2] https://lore.kernel.org/linux-usb/CO1PR17MB54195BE778868AFDFE2DCB36E1112@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/ Discussion thread on UAPI for adding strings [3] https://lore.kernel.org/linux-usb/35be4668-58d3-894a-72cf-de1afaacae45@xxxxxxxxxxx/ Discussion thread on UAPI for adding alt modes