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.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
0ca4cefad1
commit
dc5eafe778
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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
|
|||||||
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
|
|||||||
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 = {
|
|||||||
.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 = {
|
|||||||
.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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user