aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/endpoint.h
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2020-11-23 09:53:31 +0100
committerTakashi Iwai <tiwai@suse.de>2020-11-23 15:15:16 +0100
commitbf6313a0ff766925462e97b4e733d5952de02367 (patch)
tree4fd24aae13948d68f4fd6d02eef16cec62bf428a /sound/usb/endpoint.h
parentALSA: usb-audio: Fix EP matching for continuous rates (diff)
downloadlinux-dev-bf6313a0ff766925462e97b4e733d5952de02367.tar.xz
linux-dev-bf6313a0ff766925462e97b4e733d5952de02367.zip
ALSA: usb-audio: Refactor endpoint management
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: Keith Milner <kamilner@superlative.org> Tested-by: Dylan Robinson <dylan_robinson@motu.com> Link: https://lore.kernel.org/r/20201123085347.19667-26-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/endpoint.h')
-rw-r--r--sound/usb/endpoint.h40
1 files changed, 21 insertions, 19 deletions
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index e2fddb3dcf7a..2bfa6d3e029c 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -10,16 +10,25 @@ struct snd_usb_endpoint *snd_usb_get_endpoint(struct snd_usb_audio *chip,
int snd_usb_add_endpoint(struct snd_usb_audio *chip, int ep_num, int type);
-int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
- snd_pcm_format_t pcm_format,
- unsigned int channels,
- unsigned int period_bytes,
- unsigned int period_frames,
- unsigned int buffer_periods,
- unsigned int rate,
- struct audioformat *fmt,
- struct snd_usb_endpoint *sync_ep);
-
+struct snd_usb_endpoint *
+snd_usb_endpoint_open(struct snd_usb_audio *chip,
+ struct audioformat *fp,
+ const struct snd_pcm_hw_params *params,
+ bool is_sync_ep);
+void snd_usb_endpoint_close(struct snd_usb_audio *chip,
+ struct snd_usb_endpoint *ep);
+int snd_usb_endpoint_configure(struct snd_usb_audio *chip,
+ struct snd_usb_endpoint *ep);
+void snd_usb_endpoint_suspend(struct snd_usb_endpoint *ep);
+
+bool snd_usb_endpoint_compatible(struct snd_usb_audio *chip,
+ struct snd_usb_endpoint *ep,
+ const struct audioformat *fp,
+ const struct snd_pcm_hw_params *params);
+
+void snd_usb_endpoint_set_sync(struct snd_usb_audio *chip,
+ struct snd_usb_endpoint *data_ep,
+ struct snd_usb_endpoint *sync_ep);
void snd_usb_endpoint_set_callback(struct snd_usb_endpoint *ep,
void (*prepare)(struct snd_usb_substream *subs,
struct urb *urb),
@@ -27,23 +36,16 @@ void snd_usb_endpoint_set_callback(struct snd_usb_endpoint *ep,
struct urb *urb),
struct snd_usb_substream *data_subs);
-int snd_usb_endpoint_start(struct snd_usb_endpoint *ep);
+int snd_usb_endpoint_start(struct snd_usb_endpoint *ep);
void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep);
void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep);
+void snd_usb_endpoint_suspend(struct snd_usb_endpoint *ep);
int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
-void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep);
void snd_usb_endpoint_release(struct snd_usb_endpoint *ep);
void snd_usb_endpoint_free(struct snd_usb_endpoint *ep);
int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep);
int snd_usb_endpoint_slave_next_packet_size(struct snd_usb_endpoint *ep);
int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep);
-void snd_usb_endpoint_set_syncinterval(struct snd_usb_audio *chip,
- struct snd_usb_endpoint *ep,
- struct usb_host_interface *alts);
-
-void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep,
- struct snd_usb_endpoint *sender,
- const struct urb *urb);
#endif /* __USBAUDIO_ENDPOINT_H */