diff options
-rw-r--r-- | sound/soc/sof/Kconfig | 4 | ||||
-rw-r--r-- | sound/soc/sof/Makefile | 3 | ||||
-rw-r--r-- | sound/soc/sof/compress.c | 51 | ||||
-rw-r--r-- | sound/soc/sof/imx/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/sof/imx/imx8.c | 39 | ||||
-rw-r--r-- | sound/soc/sof/imx/imx8m.c | 26 | ||||
-rw-r--r-- | sound/soc/sof/intel/Makefile | 3 | ||||
-rw-r--r-- | sound/soc/sof/intel/apl.c | 4 | ||||
-rw-r--r-- | sound/soc/sof/intel/bdw.c | 12 | ||||
-rw-r--r-- | sound/soc/sof/intel/byt.c | 24 | ||||
-rw-r--r-- | sound/soc/sof/intel/cnl.c | 4 | ||||
-rw-r--r-- | sound/soc/sof/intel/icl.c | 4 | ||||
-rw-r--r-- | sound/soc/sof/intel/pci-tng.c | 12 | ||||
-rw-r--r-- | sound/soc/sof/intel/tgl.c | 4 | ||||
-rw-r--r-- | sound/soc/sof/ipc.c | 6 | ||||
-rw-r--r-- | sound/soc/sof/ops.h | 15 | ||||
-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/sof-priv.h | 28 | ||||
-rw-r--r-- | sound/soc/sof/stream-ipc.c (renamed from sound/soc/sof/intel/intel-ipc.c) | 50 | ||||
-rw-r--r-- | sound/soc/sof/topology.c | 6 |
21 files changed, 218 insertions, 97 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 bdea0faac117..06e5f49f7ee8 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -1,9 +1,10 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 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 + 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/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 080dafbf5c33..20695fe288ce 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -369,21 +369,6 @@ static int imx8_get_bar_index(struct snd_sof_dev *sdev, u32 type) return type; } -static int imx8_ipc_msg_data(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - void *p, size_t sz) -{ - sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); - return 0; -} - -static int imx8_ipc_pcm_params(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - const struct sof_ipc_pcm_params_reply *reply) -{ - return 0; -} - static struct snd_soc_dai_driver imx8_dai[] = { { .name = "esai0", @@ -421,14 +406,18 @@ struct snd_sof_dsp_ops sof_imx8_ops = { .block_read = sof_block_read, .block_write = sof_block_write, + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* ipc */ .send_msg = imx8_send_msg, .fw_ready = sof_fw_ready, .get_mailbox_offset = imx8_get_mailbox_offset, .get_window_offset = imx8_get_window_offset, - .ipc_msg_data = imx8_ipc_msg_data, - .ipc_pcm_params = imx8_ipc_pcm_params, + .ipc_msg_data = sof_ipc_msg_data, + .ipc_pcm_params = sof_ipc_pcm_params, /* module loading */ .load_module = snd_sof_parse_module_memcpy, @@ -440,6 +429,10 @@ struct snd_sof_dsp_ops sof_imx8_ops = { .dbg_dump = imx8_dump, .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem, + /* stream callbacks */ + .pcm_open = sof_stream_pcm_open, + .pcm_close = sof_stream_pcm_close, + /* Firmware ops */ .dsp_arch_ops = &sof_xtensa_arch_ops, @@ -468,14 +461,18 @@ struct snd_sof_dsp_ops sof_imx8x_ops = { .block_read = sof_block_read, .block_write = sof_block_write, + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* ipc */ .send_msg = imx8_send_msg, .fw_ready = sof_fw_ready, .get_mailbox_offset = imx8_get_mailbox_offset, .get_window_offset = imx8_get_window_offset, - .ipc_msg_data = imx8_ipc_msg_data, - .ipc_pcm_params = imx8_ipc_pcm_params, + .ipc_msg_data = sof_ipc_msg_data, + .ipc_pcm_params = sof_ipc_pcm_params, /* module loading */ .load_module = snd_sof_parse_module_memcpy, @@ -487,6 +484,10 @@ struct snd_sof_dsp_ops sof_imx8x_ops = { .dbg_dump = imx8_dump, .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem, + /* stream callbacks */ + .pcm_open = sof_stream_pcm_open, + .pcm_close = sof_stream_pcm_close, + /* Firmware ops */ .dsp_arch_ops = &sof_xtensa_arch_ops, diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c index 7094790b8aba..ae1b48abbae0 100644 --- a/sound/soc/sof/imx/imx8m.c +++ b/sound/soc/sof/imx/imx8m.c @@ -232,21 +232,6 @@ static int imx8m_get_bar_index(struct snd_sof_dev *sdev, u32 type) return type; } -static int imx8m_ipc_msg_data(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - void *p, size_t sz) -{ - sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); - return 0; -} - -static int imx8m_ipc_pcm_params(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - const struct sof_ipc_pcm_params_reply *reply) -{ - return 0; -} - static struct snd_soc_dai_driver imx8m_dai[] = { { .name = "sai1", @@ -284,14 +269,18 @@ struct snd_sof_dsp_ops sof_imx8m_ops = { .block_read = sof_block_read, .block_write = sof_block_write, + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* ipc */ .send_msg = imx8m_send_msg, .fw_ready = sof_fw_ready, .get_mailbox_offset = imx8m_get_mailbox_offset, .get_window_offset = imx8m_get_window_offset, - .ipc_msg_data = imx8m_ipc_msg_data, - .ipc_pcm_params = imx8m_ipc_pcm_params, + .ipc_msg_data = sof_ipc_msg_data, + .ipc_pcm_params = sof_ipc_pcm_params, /* module loading */ .load_module = snd_sof_parse_module_memcpy, @@ -303,6 +292,9 @@ struct snd_sof_dsp_ops sof_imx8m_ops = { .dbg_dump = imx8_dump, .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem, + /* stream callbacks */ + .pcm_open = sof_stream_pcm_open, + .pcm_close = sof_stream_pcm_close, /* Firmware ops */ .dsp_arch_ops = &sof_xtensa_arch_ops, diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile index 9635dd47a17d..1f473d4d8416 100644 --- a/sound/soc/sof/intel/Makefile +++ b/sound/soc/sof/intel/Makefile @@ -3,8 +3,6 @@ snd-sof-acpi-intel-byt-objs := byt.o snd-sof-acpi-intel-bdw-objs := bdw.o -snd-sof-intel-ipc-objs := intel-ipc.o - snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \ hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \ hda-dai.o hda-bus.o \ @@ -18,7 +16,6 @@ snd-sof-intel-atom-objs := atom.o obj-$(CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP) += snd-sof-intel-atom.o obj-$(CONFIG_SND_SOC_SOF_BAYTRAIL) += snd-sof-acpi-intel-byt.o obj-$(CONFIG_SND_SOC_SOF_BROADWELL) += snd-sof-acpi-intel-bdw.o -obj-$(CONFIG_SND_SOC_SOF_INTEL_HIFI_EP_IPC) += snd-sof-intel-ipc.o obj-$(CONFIG_SND_SOC_SOF_HDA_COMMON) += snd-sof-intel-hda-common.o obj-$(CONFIG_SND_SOC_SOF_HDA) += snd-sof-intel-hda.o diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index e6a1f6532547..917f78cf6daf 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -42,6 +42,10 @@ const struct snd_sof_dsp_ops sof_apl_ops = { .block_read = sof_block_read, .block_write = sof_block_write, + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_thread = hda_dsp_ipc_irq_thread, diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index d09275417749..2c09a523288e 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -616,14 +616,18 @@ static const struct snd_sof_dsp_ops sof_bdw_ops = { .block_read = sof_block_read, .block_write = sof_block_write, + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* ipc */ .send_msg = bdw_send_msg, .fw_ready = sof_fw_ready, .get_mailbox_offset = bdw_get_mailbox_offset, .get_window_offset = bdw_get_window_offset, - .ipc_msg_data = intel_ipc_msg_data, - .ipc_pcm_params = intel_ipc_pcm_params, + .ipc_msg_data = sof_ipc_msg_data, + .ipc_pcm_params = sof_ipc_pcm_params, /* machine driver */ .machine_select = bdw_machine_select, @@ -638,8 +642,8 @@ static const struct snd_sof_dsp_ops sof_bdw_ops = { .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem, /* stream callbacks */ - .pcm_open = intel_pcm_open, - .pcm_close = intel_pcm_close, + .pcm_open = sof_stream_pcm_open, + .pcm_close = sof_stream_pcm_close, /* Module loading */ .load_module = snd_sof_parse_module_memcpy, diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 8f60c72fee7e..e2fa08f1ae74 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -226,6 +226,10 @@ static const struct snd_sof_dsp_ops sof_byt_ops = { .block_read = sof_block_read, .block_write = sof_block_write, + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_handler = atom_irq_handler, .irq_thread = atom_irq_thread, @@ -236,8 +240,8 @@ static const struct snd_sof_dsp_ops sof_byt_ops = { .get_mailbox_offset = atom_get_mailbox_offset, .get_window_offset = atom_get_window_offset, - .ipc_msg_data = intel_ipc_msg_data, - .ipc_pcm_params = intel_ipc_pcm_params, + .ipc_msg_data = sof_ipc_msg_data, + .ipc_pcm_params = sof_ipc_pcm_params, /* machine driver */ .machine_select = atom_machine_select, @@ -252,8 +256,8 @@ static const struct snd_sof_dsp_ops sof_byt_ops = { .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem, /* stream callbacks */ - .pcm_open = intel_pcm_open, - .pcm_close = intel_pcm_close, + .pcm_open = sof_stream_pcm_open, + .pcm_close = sof_stream_pcm_close, /* module loading */ .load_module = snd_sof_parse_module_memcpy, @@ -304,6 +308,10 @@ static const struct snd_sof_dsp_ops sof_cht_ops = { .block_read = sof_block_read, .block_write = sof_block_write, + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_handler = atom_irq_handler, .irq_thread = atom_irq_thread, @@ -314,8 +322,8 @@ static const struct snd_sof_dsp_ops sof_cht_ops = { .get_mailbox_offset = atom_get_mailbox_offset, .get_window_offset = atom_get_window_offset, - .ipc_msg_data = intel_ipc_msg_data, - .ipc_pcm_params = intel_ipc_pcm_params, + .ipc_msg_data = sof_ipc_msg_data, + .ipc_pcm_params = sof_ipc_pcm_params, /* machine driver */ .machine_select = atom_machine_select, @@ -330,8 +338,8 @@ static const struct snd_sof_dsp_ops sof_cht_ops = { .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem, /* stream callbacks */ - .pcm_open = intel_pcm_open, - .pcm_close = intel_pcm_close, + .pcm_open = sof_stream_pcm_open, + .pcm_close = sof_stream_pcm_close, /* module loading */ .load_module = snd_sof_parse_module_memcpy, diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 430a268e6b26..3957e2b3db32 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -247,6 +247,10 @@ const struct snd_sof_dsp_ops sof_cnl_ops = { .block_read = sof_block_read, .block_write = sof_block_write, + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_thread = cnl_ipc_irq_thread, diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c index 38a40c03c9da..0b2cc331d55b 100644 --- a/sound/soc/sof/intel/icl.c +++ b/sound/soc/sof/intel/icl.c @@ -41,6 +41,10 @@ const struct snd_sof_dsp_ops sof_icl_ops = { .block_read = sof_block_read, .block_write = sof_block_write, + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_thread = cnl_ipc_irq_thread, diff --git a/sound/soc/sof/intel/pci-tng.c b/sound/soc/sof/intel/pci-tng.c index 3d6d013844d7..18eb41b8a8f4 100644 --- a/sound/soc/sof/intel/pci-tng.c +++ b/sound/soc/sof/intel/pci-tng.c @@ -142,6 +142,10 @@ const struct snd_sof_dsp_ops sof_tng_ops = { .block_read = sof_block_read, .block_write = sof_block_write, + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_handler = atom_irq_handler, .irq_thread = atom_irq_thread, @@ -152,8 +156,8 @@ const struct snd_sof_dsp_ops sof_tng_ops = { .get_mailbox_offset = atom_get_mailbox_offset, .get_window_offset = atom_get_window_offset, - .ipc_msg_data = intel_ipc_msg_data, - .ipc_pcm_params = intel_ipc_pcm_params, + .ipc_msg_data = sof_ipc_msg_data, + .ipc_pcm_params = sof_ipc_pcm_params, /* machine driver */ .machine_select = atom_machine_select, @@ -168,8 +172,8 @@ const struct snd_sof_dsp_ops sof_tng_ops = { .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem, /* stream callbacks */ - .pcm_open = intel_pcm_open, - .pcm_close = intel_pcm_close, + .pcm_open = sof_stream_pcm_open, + .pcm_close = sof_stream_pcm_close, /* module loading */ .load_module = snd_sof_parse_module_memcpy, diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c index 664a11aaada2..48da8e7a67bc 100644 --- a/sound/soc/sof/intel/tgl.c +++ b/sound/soc/sof/intel/tgl.c @@ -37,6 +37,10 @@ const struct snd_sof_dsp_ops sof_tgl_ops = { .block_read = sof_block_read, .block_write = sof_block_write, + /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_thread = cnl_ipc_irq_thread, diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index 5a308c62f7ca..b2e556b64994 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -545,8 +545,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/ops.h b/sound/soc/sof/ops.h index 290e32a8a7d4..09bf38fdfb8a 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -312,6 +312,21 @@ static inline int snd_sof_dsp_block_write(struct snd_sof_dev *sdev, return sof_ops(sdev)->block_write(sdev, blk_type, offset, src, bytes); } +/* mailbox IO */ +static inline void snd_sof_dsp_mailbox_read(struct snd_sof_dev *sdev, + u32 offset, void *dest, size_t bytes) +{ + if (sof_ops(sdev)->mailbox_read) + sof_ops(sdev)->mailbox_read(sdev, offset, dest, bytes); +} + +static inline void snd_sof_dsp_mailbox_write(struct snd_sof_dev *sdev, + u32 offset, void *src, size_t bytes) +{ + if (sof_ops(sdev)->mailbox_write) + sof_ops(sdev)->mailbox_write(sdev, offset, src, bytes); +} + /* ipc */ static inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) 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 fe2ffe02fdfb..05e98e231b85 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/sof-priv.h b/sound/soc/sof/sof-priv.h index d9525f3ff5cd..efaec2989a27 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -154,6 +154,14 @@ struct snd_sof_dsp_ops { enum snd_sof_fw_blk_type type, u32 offset, void *src, size_t size); /* mandatory */ + /* Mailbox IO */ + void (*mailbox_read)(struct snd_sof_dev *sof_dev, + u32 offset, void *dest, + size_t size); /* optional */ + void (*mailbox_write)(struct snd_sof_dev *sof_dev, + u32 offset, void *src, + size_t size); /* optional */ + /* doorbell */ irqreturn_t (*irq_handler)(int irq, void *context); /* optional */ irqreturn_t (*irq_thread)(int irq, void *context); /* optional */ @@ -592,17 +600,17 @@ int sof_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type, int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id); -int intel_ipc_msg_data(struct snd_sof_dev *sdev, +int sof_ipc_msg_data(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + void *p, size_t sz); +int sof_ipc_pcm_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, - void *p, size_t sz); -int intel_ipc_pcm_params(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - const struct sof_ipc_pcm_params_reply *reply); - -int intel_pcm_open(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream); -int intel_pcm_close(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream); + const struct sof_ipc_pcm_params_reply *reply); + +int sof_stream_pcm_open(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream); +int sof_stream_pcm_close(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream); int sof_machine_check(struct snd_sof_dev *sdev); #endif diff --git a/sound/soc/sof/intel/intel-ipc.c b/sound/soc/sof/stream-ipc.c index df37187c8427..15a55851faeb 100644 --- a/sound/soc/sof/intel/intel-ipc.c +++ b/sound/soc/sof/stream-ipc.c @@ -7,7 +7,7 @@ // // Authors: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> -/* Intel-specific SOF IPC code */ +/* Generic SOF IPC code */ #include <linux/device.h> #include <linux/export.h> @@ -17,39 +17,39 @@ #include <sound/pcm.h> #include <sound/sof/stream.h> -#include "../ops.h" -#include "../sof-priv.h" +#include "ops.h" +#include "sof-priv.h" -struct intel_stream { +struct sof_stream { size_t posn_offset; }; -/* Mailbox-based Intel IPC implementation */ -int intel_ipc_msg_data(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - void *p, size_t sz) +/* Mailbox-based Generic IPC implementation */ +int sof_ipc_msg_data(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + void *p, size_t sz) { if (!substream || !sdev->stream_box.size) { - sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); + snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); } else { - struct intel_stream *stream = substream->runtime->private_data; + struct sof_stream *stream = substream->runtime->private_data; /* The stream might already be closed */ if (!stream) return -ESTRPIPE; - sof_mailbox_read(sdev, stream->posn_offset, p, sz); + snd_sof_dsp_mailbox_read(sdev, stream->posn_offset, p, sz); } return 0; } -EXPORT_SYMBOL_NS(intel_ipc_msg_data, SND_SOC_SOF_INTEL_HIFI_EP_IPC); +EXPORT_SYMBOL(sof_ipc_msg_data); -int intel_ipc_pcm_params(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - const struct sof_ipc_pcm_params_reply *reply) +int sof_ipc_pcm_params(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + const struct sof_ipc_pcm_params_reply *reply) { - struct intel_stream *stream = substream->runtime->private_data; + struct sof_stream *stream = substream->runtime->private_data; size_t posn_offset = reply->posn_offset; /* check if offset is overflow or it is not aligned */ @@ -64,12 +64,12 @@ int intel_ipc_pcm_params(struct snd_sof_dev *sdev, return 0; } -EXPORT_SYMBOL_NS(intel_ipc_pcm_params, SND_SOC_SOF_INTEL_HIFI_EP_IPC); +EXPORT_SYMBOL(sof_ipc_pcm_params); -int intel_pcm_open(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream) +int sof_stream_pcm_open(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream) { - struct intel_stream *stream = kmalloc(sizeof(*stream), GFP_KERNEL); + struct sof_stream *stream = kmalloc(sizeof(*stream), GFP_KERNEL); if (!stream) return -ENOMEM; @@ -86,18 +86,18 @@ int intel_pcm_open(struct snd_sof_dev *sdev, return 0; } -EXPORT_SYMBOL_NS(intel_pcm_open, SND_SOC_SOF_INTEL_HIFI_EP_IPC); +EXPORT_SYMBOL(sof_stream_pcm_open); -int intel_pcm_close(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream) +int sof_stream_pcm_close(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream) { - struct intel_stream *stream = substream->runtime->private_data; + struct sof_stream *stream = substream->runtime->private_data; substream->runtime->private_data = NULL; kfree(stream); return 0; } -EXPORT_SYMBOL_NS(intel_pcm_close, SND_SOC_SOF_INTEL_HIFI_EP_IPC); +EXPORT_SYMBOL(sof_stream_pcm_close); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 50854ed02173..bb9e62bbe5db 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -2601,8 +2601,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; |