Commit dc5eafe7 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: usb-audio: Support PCM sync_stop

USB-audio driver had some implementation of its own sync-stop
mechanism.  This patch moved a part of it to the common PCM sync_stop
ops.

Link: https://lore.kernel.org/r/20191210063454.31603-56-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 0ca4cefa
...@@ -260,18 +260,31 @@ static int start_endpoints(struct snd_usb_substream *subs) ...@@ -260,18 +260,31 @@ static int start_endpoints(struct snd_usb_substream *subs)
return 0; return 0;
} }
static void stop_endpoints(struct snd_usb_substream *subs, bool wait) static void sync_pending_stops(struct snd_usb_substream *subs)
{
snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint);
snd_usb_endpoint_sync_pending_stop(subs->data_endpoint);
}
static void stop_endpoints(struct snd_usb_substream *subs)
{ {
if (test_and_clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) if (test_and_clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags))
snd_usb_endpoint_stop(subs->sync_endpoint); snd_usb_endpoint_stop(subs->sync_endpoint);
if (test_and_clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags)) if (test_and_clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags))
snd_usb_endpoint_stop(subs->data_endpoint); snd_usb_endpoint_stop(subs->data_endpoint);
}
if (wait) { /* PCM sync_stop callback */
snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint); static int snd_usb_pcm_sync_stop(struct snd_pcm_substream *substream)
snd_usb_endpoint_sync_pending_stop(subs->data_endpoint); {
struct snd_usb_substream *subs = substream->runtime->private_data;
if (!snd_usb_lock_shutdown(subs->stream->chip)) {
sync_pending_stops(subs);
snd_usb_unlock_shutdown(subs->stream->chip);
} }
return 0;
} }
static int search_roland_implicit_fb(struct usb_device *dev, int ifnum, static int search_roland_implicit_fb(struct usb_device *dev, int ifnum,
...@@ -697,7 +710,8 @@ static int configure_endpoint(struct snd_usb_substream *subs) ...@@ -697,7 +710,8 @@ static int configure_endpoint(struct snd_usb_substream *subs)
int ret; int ret;
/* format changed */ /* format changed */
stop_endpoints(subs, true); stop_endpoints(subs);
sync_pending_stops(subs);
ret = snd_usb_endpoint_set_params(subs->data_endpoint, ret = snd_usb_endpoint_set_params(subs->data_endpoint,
subs->pcm_format, subs->pcm_format,
subs->channels, subs->channels,
...@@ -842,7 +856,8 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) ...@@ -842,7 +856,8 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
subs->cur_rate = 0; subs->cur_rate = 0;
subs->period_bytes = 0; subs->period_bytes = 0;
if (!snd_usb_lock_shutdown(subs->stream->chip)) { if (!snd_usb_lock_shutdown(subs->stream->chip)) {
stop_endpoints(subs, true); stop_endpoints(subs);
sync_pending_stops(subs);
snd_usb_endpoint_deactivate(subs->sync_endpoint); snd_usb_endpoint_deactivate(subs->sync_endpoint);
snd_usb_endpoint_deactivate(subs->data_endpoint); snd_usb_endpoint_deactivate(subs->data_endpoint);
snd_usb_unlock_shutdown(subs->stream->chip); snd_usb_unlock_shutdown(subs->stream->chip);
...@@ -877,9 +892,6 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) ...@@ -877,9 +892,6 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
goto unlock; goto unlock;
} }
snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint);
snd_usb_endpoint_sync_pending_stop(subs->data_endpoint);
ret = snd_usb_pcm_change_state(subs, UAC3_PD_STATE_D0); ret = snd_usb_pcm_change_state(subs, UAC3_PD_STATE_D0);
if (ret < 0) if (ret < 0)
goto unlock; goto unlock;
...@@ -1337,7 +1349,6 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream) ...@@ -1337,7 +1349,6 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream)
struct snd_usb_substream *subs = &as->substream[direction]; struct snd_usb_substream *subs = &as->substream[direction];
int ret; int ret;
stop_endpoints(subs, true);
snd_media_stop_pipeline(subs); snd_media_stop_pipeline(subs);
if (!as->chip->keep_iface && if (!as->chip->keep_iface &&
...@@ -1714,7 +1725,7 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea ...@@ -1714,7 +1725,7 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
subs->running = 1; subs->running = 1;
return 0; return 0;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
stop_endpoints(subs, false); stop_endpoints(subs);
subs->running = 0; subs->running = 0;
return 0; return 0;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
...@@ -1744,7 +1755,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream ...@@ -1744,7 +1755,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream
subs->running = 1; subs->running = 1;
return 0; return 0;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
stop_endpoints(subs, false); stop_endpoints(subs);
subs->running = 0; subs->running = 0;
return 0; return 0;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
...@@ -1767,6 +1778,7 @@ static const struct snd_pcm_ops snd_usb_playback_ops = { ...@@ -1767,6 +1778,7 @@ static const struct snd_pcm_ops snd_usb_playback_ops = {
.hw_free = snd_usb_hw_free, .hw_free = snd_usb_hw_free,
.prepare = snd_usb_pcm_prepare, .prepare = snd_usb_pcm_prepare,
.trigger = snd_usb_substream_playback_trigger, .trigger = snd_usb_substream_playback_trigger,
.sync_stop = snd_usb_pcm_sync_stop,
.pointer = snd_usb_pcm_pointer, .pointer = snd_usb_pcm_pointer,
}; };
...@@ -1777,6 +1789,7 @@ static const struct snd_pcm_ops snd_usb_capture_ops = { ...@@ -1777,6 +1789,7 @@ static const struct snd_pcm_ops snd_usb_capture_ops = {
.hw_free = snd_usb_hw_free, .hw_free = snd_usb_hw_free,
.prepare = snd_usb_pcm_prepare, .prepare = snd_usb_pcm_prepare,
.trigger = snd_usb_substream_capture_trigger, .trigger = snd_usb_substream_capture_trigger,
.sync_stop = snd_usb_pcm_sync_stop,
.pointer = snd_usb_pcm_pointer, .pointer = snd_usb_pcm_pointer,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment