diff options
Diffstat (limited to 'sound/soc/sof')
-rw-r--r-- | sound/soc/sof/Kconfig | 4 | ||||
-rw-r--r-- | sound/soc/sof/Makefile | 1 | ||||
-rw-r--r-- | sound/soc/sof/compress.c | 51 | ||||
-rw-r--r-- | sound/soc/sof/imx/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/sof/ipc.c | 6 | ||||
-rw-r--r-- | sound/soc/sof/pcm.c | 7 | ||||
-rw-r--r-- | sound/soc/sof/sof-audio.h | 11 | ||||
-rw-r--r-- | sound/soc/sof/topology.c | 6 |
8 files changed, 82 insertions, 6 deletions
diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig index 94d1a859fedc..6bb4db87af03 100644 --- a/sound/soc/sof/Kconfig +++ b/sound/soc/sof/Kconfig @@ -46,6 +46,10 @@ config SND_SOC_SOF_OF required to enable i.MX8 devices. Say Y if you need this option. If unsure select "N". +config SND_SOC_SOF_COMPRESS + tristate + select SND_SOC_COMPRESS + config SND_SOC_SOF_DEBUG_PROBES bool "SOF enable data probing" select SND_SOC_COMPRESS diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index c5b97c66a9f1..06e5f49f7ee8 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -4,6 +4,7 @@ snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\ control.o trace.o utils.o sof-audio.o stream-ipc.o snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += sof-probes.o +snd-sof-$(CONFIG_SND_SOC_SOF_COMPRESS) += compress.o snd-sof-pci-objs := sof-pci-dev.o snd-sof-acpi-objs := sof-acpi-dev.o diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c new file mode 100644 index 000000000000..01ca85f0b87f --- /dev/null +++ b/sound/soc/sof/compress.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// Copyright 2021 NXP +// +// Author: Daniel Baluta <daniel.baluta@nxp.com> + +#include <sound/soc.h> +#include <sound/sof.h> +#include <sound/compress_driver.h> +#include "sof-audio.h" +#include "sof-priv.h" + +static void snd_sof_compr_fragment_elapsed_work(struct work_struct *work) +{ + struct snd_sof_pcm_stream *sps = + container_of(work, struct snd_sof_pcm_stream, + period_elapsed_work); + + snd_compr_fragment_elapsed(sps->cstream); +} + +void snd_sof_compr_init_elapsed_work(struct work_struct *work) +{ + INIT_WORK(work, snd_sof_compr_fragment_elapsed_work); +} + +/* + * sof compr fragment elapse, this could be called in irq thread context + */ +void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream) +{ + struct snd_soc_component *component; + struct snd_soc_pcm_runtime *rtd; + struct snd_sof_pcm *spcm; + + if (!cstream) + return; + + rtd = cstream->private_data; + component = snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME); + + spcm = snd_sof_find_spcm_dai(component, rtd); + if (!spcm) { + dev_err(component->dev, + "fragment elapsed called for unknown stream!\n"); + return; + } + + /* use the same workqueue-based solution as for PCM, cf. snd_sof_pcm_elapsed */ + schedule_work(&spcm->stream[cstream->direction].period_elapsed_work); +} diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig index 49d605cb09a5..34cf228c188f 100644 --- a/sound/soc/sof/imx/Kconfig +++ b/sound/soc/sof/imx/Kconfig @@ -38,6 +38,7 @@ config SND_SOC_SOF_IMX8 tristate select SND_SOC_SOF_IMX_COMMON select SND_SOC_SOF_XTENSA + select SND_SOC_SOF_COMPRESS help This option is not user-selectable but automagically handled by 'select' statements at a higher level. @@ -54,6 +55,7 @@ config SND_SOC_SOF_IMX8M tristate select SND_SOC_SOF_IMX_COMMON select SND_SOC_SOF_XTENSA + select SND_SOC_SOF_COMPRESS help This option is not user-selectable but automagically handled by 'select' statements at a higher level. diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index 53593df95155..1efc2c395c54 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -539,8 +539,10 @@ static void ipc_period_elapsed(struct snd_sof_dev *sdev, u32 msg_id) memcpy(&stream->posn, &posn, sizeof(posn)); - /* only inform ALSA for period_wakeup mode */ - if (!stream->substream->runtime->no_period_wakeup) + if (spcm->pcm.compress) + snd_sof_compr_fragment_elapsed(stream->cstream); + else if (!stream->substream->runtime->no_period_wakeup) + /* only inform ALSA for period_wakeup mode */ snd_sof_pcm_period_elapsed(stream->substream); } diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 374df2dfa816..fa0bfcd2474e 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -57,7 +57,7 @@ static int sof_pcm_dsp_params(struct snd_sof_pcm *spcm, struct snd_pcm_substream /* * sof pcm period elapse work */ -void snd_sof_pcm_period_elapsed_work(struct work_struct *work) +static void snd_sof_pcm_period_elapsed_work(struct work_struct *work) { struct snd_sof_pcm_stream *sps = container_of(work, struct snd_sof_pcm_stream, @@ -66,6 +66,11 @@ void snd_sof_pcm_period_elapsed_work(struct work_struct *work) snd_pcm_period_elapsed(sps->substream); } +void snd_sof_pcm_init_elapsed_work(struct work_struct *work) +{ + INIT_WORK(work, snd_sof_pcm_period_elapsed_work); +} + /* * sof pcm period elapse, this could be called at irq thread context. */ diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index 149b3dbcddd1..3f16611fbca7 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -36,6 +36,7 @@ struct snd_sof_pcm_stream { struct snd_dma_buffer page_table; struct sof_ipc_stream_posn posn; struct snd_pcm_substream *substream; + struct snd_compr_stream *cstream; 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 */ @@ -231,7 +232,15 @@ struct snd_sof_pcm *snd_sof_find_spcm_pcm_id(struct snd_soc_component *scomp, const struct sof_ipc_pipe_new *snd_sof_pipeline_find(struct snd_sof_dev *sdev, int pipeline_id); void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream); -void snd_sof_pcm_period_elapsed_work(struct work_struct *work); +void snd_sof_pcm_init_elapsed_work(struct work_struct *work); + +#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMPRESS) +void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream); +void snd_sof_compr_init_elapsed_work(struct work_struct *work); +#else +static inline void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream) { } +static inline void snd_sof_compr_init_elapsed_work(struct work_struct *work) { } +#endif /* * Mixer IPC diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 534f004f6162..e81fa2058c7d 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -2587,8 +2587,10 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index, for_each_pcm_streams(stream) { spcm->stream[stream].comp_id = COMP_ID_UNASSIGNED; - INIT_WORK(&spcm->stream[stream].period_elapsed_work, - snd_sof_pcm_period_elapsed_work); + if (pcm->compress) + snd_sof_compr_init_elapsed_work(&spcm->stream[stream].period_elapsed_work); + else + snd_sof_pcm_init_elapsed_work(&spcm->stream[stream].period_elapsed_work); } spcm->pcm = *pcm; |