Merge "ALSA: compress: Allow pause and resume during draining" into kernel.lnx.5.4.r3-rel

This commit is contained in:
Linux Build Service Account 2023-10-13 02:41:55 -07:00 • committed by Gerrit - the friendly Code Review server
commit 516aee6f45
2 changed files with 59 additions and 8 deletions

View file

@ -59,6 +59,7 @@ struct snd_compr_runtime {
* @direction: stream direction, playback/recording
* @metadata_set: metadata set flag, true when set
* @next_track: has userspace signal next track transition, true when set
* @pause_in_draining: paused during draining state, true when set
* @private_data: pointer to DSP private data
*/
struct snd_compr_stream {
@ -70,6 +71,9 @@ struct snd_compr_stream {
enum snd_compr_direction direction;
bool metadata_set;
bool next_track;
#ifndef CONFIG_AUDIO_QGKI
bool pause_in_draining;
#endif
void *private_data;
#ifdef CONFIG_AUDIO_QGKI
struct snd_soc_pcm_runtime *be;
@ -140,6 +144,7 @@ struct snd_compr_ops {
* @direction: Playback or capture direction
* @lock: device lock
* @device: device id
* @use_pause_in_draining: allow pause in draining, true when set
*/
struct snd_compr {
const char *name;
@ -150,6 +155,9 @@ struct snd_compr {
unsigned int direction;
struct mutex lock;
int device;
#ifndef CONFIG_AUDIO_QGKI
bool use_pause_in_draining;
#endif
#ifdef CONFIG_SND_VERBOSE_PROCFS
/* private: */
char id[64];
@ -164,6 +172,20 @@ int snd_compress_deregister(struct snd_compr *device);
int snd_compress_new(struct snd_card *card, int device,
int type, const char *id, struct snd_compr *compr);
/**
* snd_compr_use_pause_in_draining - Allow pause and resume in draining state
* @substream: compress substream to set
*
* Allow pause and resume in draining state.
* Only HW driver supports this transition can call this API.
*/
#ifndef CONFIG_AUDIO_QGKI
static inline void snd_compr_use_pause_in_draining(struct snd_compr_stream *substream)
{
substream->device->use_pause_in_draining = true;
}
#endif
/* dsp driver callback apis
* For playback: driver should call snd_compress_fragment_elapsed() to let the
* framework know that a fragment has been consumed from the ring buffer

View file

@ -698,11 +698,24 @@ static int snd_compr_pause(struct snd_compr_stream *stream)
{
int retval;
if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING)
switch (stream->runtime->state) {
case SNDRV_PCM_STATE_RUNNING:
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
if (!retval)
stream->runtime->state = SNDRV_PCM_STATE_PAUSED;
break;
#ifndef CONFIG_AUDIO_QGKI
case SNDRV_PCM_STATE_DRAINING:
if (!stream->device->use_pause_in_draining)
return -EPERM;
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
if (!retval)
stream->pause_in_draining = true;
break;
#endif
default:
return -EPERM;
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
if (!retval)
stream->runtime->state = SNDRV_PCM_STATE_PAUSED;
}
return retval;
}
@ -710,11 +723,24 @@ static int snd_compr_resume(struct snd_compr_stream *stream)
{
int retval;
if (stream->runtime->state != SNDRV_PCM_STATE_PAUSED)
switch (stream->runtime->state) {
case SNDRV_PCM_STATE_PAUSED:
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
if (!retval)
stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
break;
#ifndef CONFIG_AUDIO_QGKI
case SNDRV_PCM_STATE_DRAINING:
if (!stream->pause_in_draining)
return -EPERM;
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
if (!retval)
stream->pause_in_draining = false;
break;
#endif
default:
return -EPERM;
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
if (!retval)
stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
}
return retval;
}
@ -754,6 +780,9 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
if (!retval) {
#ifndef CONFIG_AUDIO_QGKI
stream->pause_in_draining = false;
#endif
snd_compr_drain_notify(stream);
stream->runtime->total_bytes_available = 0;
stream->runtime->total_bytes_transferred = 0;