• Takashi Iwai's avatar
    ALSA: usb-audio: Refactor endpoint management · bf6313a0
    Takashi Iwai authored
    
    
    This is an intensive surgery for the endpoint and stream management
    for achieving more robust and clean code.
    
    The goals of this patch are:
    - More clear endpoint resource changes
    - The interface altsetting control in a single place
    Below are brief description of the whole changes.
    
    First off, most of the endpoint operations are moved into endpoint.c,
    so that the snd_usb_endpoint object is only referred in other places.
    The endpoint object is acquired and released via the new functions
    snd_usb_endpoint_open() and snd_usb_endpoint_close() that are called
    at PCM hw_params and hw_free callbacks, respectively.  Those are
    ref-counted and EPs can manage the multiple opens.
    
    The open callback receives the audioformat and hw_params arguments,
    and those are used for initializing the EP parameters; especially the
    endpoint, interface and altset numbers are read from there, as well as
    the PCM parameters like the format, rate and channels.  Those are
    stored in snd_usb_endpoint object.  If it's the secondary open, the
    function checks whether the given parameters are compatible with the
    already opened EP setup, too.
    
    The coupling with a sync EP (including an implicit feedback sync) is
    done by the sole snd_usb_endpoint_set_sync() call.
    
    The configuration of each endpoint is done in a single shot via
    snd_usb_endpoint_configure() call.  This is the place where most of
    PCM configurations are done.  A few flags and special handling in the
    snd_usb_substream are dropped along with this change.
    
    A significant difference wrt the configuration from the previous code
    is the order of USB host interface setups.  Now the interface is
    always disabled at beginning and (re-)enabled at the last step of
    snd_usb_endpoint_configure(), in order to be compliant with the
    standard UAC2/3.  For UAC1, the interface is set before the parameter
    setups since there seem devices that require it (e.g. Yamaha THR10),
    just like how it was done in the previous driver code.
    
    The start/stop are almost same as before, also single-shots.  The URB
    callbacks need to be set via snd_usb_endpoint_set_callback() like the
    previous code at the trigger phase, too.
    
    Finally, the flag for the re-setup is set at the device suspend
    through the full EP list, instead of PCM trigger.  This catches the
    overlooked cases where the PCM hasn't been running yet but the device
    needs the full setup after resume.
    Tested-by: default avatarKeith Milner <kamilner@superlative.org>
    Tested-by: default avatarDylan Robinson <dylan_robinson@motu.com>
    Link: https://lore.kernel.org/r/20201123085347.19667-26-tiwai@suse.de
    
    Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
    bf6313a0