diff --git a/include/uapi/sound/sof/tokens.h b/include/uapi/sound/sof/tokens.h index 0a246bc218d32a..c28c766270de01 100644 --- a/include/uapi/sound/sof/tokens.h +++ b/include/uapi/sound/sof/tokens.h @@ -153,6 +153,8 @@ /* Stream */ #define SOF_TKN_STREAM_PLAYBACK_COMPATIBLE_D0I3 1200 #define SOF_TKN_STREAM_CAPTURE_COMPATIBLE_D0I3 1201 +#define SOF_TKN_STREAM_PLAYBACK_PAUSE_SUPPORTED 1202 +#define SOF_TKN_STREAM_CAPTURE_PAUSE_SUPPORTED 1203 /* Led control for mute switches */ #define SOF_TKN_MUTE_LED_USE 1300 diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index f6e24edd7adbe9..450f33eb46b2d9 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -37,6 +37,11 @@ static bool hda_disable_rewinds; module_param_named(disable_rewinds, hda_disable_rewinds, bool, 0444); MODULE_PARM_DESC(disable_rewinds, "SOF HDA disable rewinds"); +static bool hda_force_pause_support; +module_param_named(force_pause_support, hda_force_pause_support, bool, 0444); +MODULE_PARM_DESC(force_pause_support, + "SOF HDA ignore pause_supported flag to allow pause operation"); + u32 hda_dsp_get_mult_div(struct snd_sof_dev *sdev, int rate) { switch (rate) { @@ -240,6 +245,14 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev, if (hda_always_enable_dmi_l1 && direction == SNDRV_PCM_STREAM_CAPTURE) runtime->hw.info &= ~SNDRV_PCM_INFO_PAUSE; + /* + * Follow the pause_supported flag (unless a module parameter is set to + * ignore it) and disable the pause push/release support + */ + if (!hda_force_pause_support && + !spcm->stream[substream->stream].pause_supported) + runtime->hw.info &= ~SNDRV_PCM_INFO_PAUSE; + if (hda_always_enable_dmi_l1 || direction == SNDRV_PCM_STREAM_PLAYBACK || spcm->stream[substream->stream].d0i3_compatible) diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index b9b8b64768b979..4fd676826627ee 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -332,6 +332,14 @@ struct snd_sof_pcm_stream { struct work_struct period_elapsed_work; struct snd_soc_dapm_widget_list *list; /* list of connected DAPM widgets */ bool d0i3_compatible; /* DSP can be in D0I3 when this pcm is opened */ + /* + * Flag for the core and platform code about PCM pause/resume support. + * Note: End-users are using audio via media servers (Pulseaudio, Pipewire, + * CRAS, etc) and media servers do not use pause/resume. + * Media players using ALSA directly have means to handle PCM devices + * without pause/resume support also. + */ + bool pause_supported; unsigned int dsp_max_burst_size_in_ms; /* The maximum size of the host DMA burst in ms */ /* * flag to indicate that the DSP pipelines should be kept diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index b5438213199163..55a8cee9ae2d3f 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -407,6 +407,10 @@ static const struct sof_topology_token stream_tokens[] = { offsetof(struct snd_sof_pcm, stream[0].d0i3_compatible)}, {SOF_TKN_STREAM_CAPTURE_COMPATIBLE_D0I3, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16, offsetof(struct snd_sof_pcm, stream[1].d0i3_compatible)}, + {SOF_TKN_STREAM_PLAYBACK_PAUSE_SUPPORTED, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16, + offsetof(struct snd_sof_pcm, stream[0].pause_supported)}, + {SOF_TKN_STREAM_CAPTURE_PAUSE_SUPPORTED, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16, + offsetof(struct snd_sof_pcm, stream[1].pause_supported)}, }; /* Leds */