diff --git a/include/sound/sof.h b/include/sound/sof.h index f6056247c3a75f..e522e13e7a18d7 100644 --- a/include/sound/sof.h +++ b/include/sound/sof.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -76,6 +77,10 @@ struct sof_dev_desc { int sof_nocodec_setup(struct device *dev, struct snd_sof_pdata *sof_pdata, struct snd_soc_acpi_mach *mach, - const struct sof_dev_desc *desc); + const struct sof_dev_desc *desc, + struct snd_sof_dsp_ops *ops); +int sof_bes_setup(struct device *dev, struct snd_sof_dsp_ops *ops, + struct snd_soc_dai_link *links, int link_num, + struct snd_soc_card *card); #endif diff --git a/sound/soc/intel/boards/bxt_tdf8532.c b/sound/soc/intel/boards/bxt_tdf8532.c index ffd9cc5dace7a8..1e0e633d493b6d 100644 --- a/sound/soc/intel/boards/bxt_tdf8532.c +++ b/sound/soc/intel/boards/bxt_tdf8532.c @@ -266,6 +266,7 @@ static struct snd_soc_dai_link broxton_tdf8532_dais[] = { .platform_name = "0000:00:0e.0", .init = NULL, .nonatomic = 1, + .dynamic = 1, }, { .name = "Bxt Compress Probe capture", @@ -276,6 +277,7 @@ static struct snd_soc_dai_link broxton_tdf8532_dais[] = { .platform_name = "0000:00:0e.0", .init = NULL, .nonatomic = 1, + .dynamic = 1, }, /* Trace Buffer DAI links */ { @@ -287,6 +289,7 @@ static struct snd_soc_dai_link broxton_tdf8532_dais[] = { .platform_name = "0000:00:0e.0", .capture_only = true, .ignore_suspend = 1, + .dynamic = 1, }, { .name = "Bxt Trace Buffer1", @@ -297,6 +300,7 @@ static struct snd_soc_dai_link broxton_tdf8532_dais[] = { .platform_name = "0000:00:0e.0", .capture_only = true, .ignore_suspend = 1, + .dynamic = 1, }, /* Back End DAI links */ { diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a0160a409e4094..b32ede7de9fd9c 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2126,12 +2126,9 @@ static void soc_check_tplg_fes(struct snd_soc_card *card) /* override platform */ dai_link->platform_name = platform->component.name; - dai_link->cpu_dai_name = platform->component.name; /* convert non BE into BE */ dai_link->no_pcm = 1; - dai_link->dpcm_playback = 1; - dai_link->dpcm_capture = 1; /* override any BE fixups */ dai_link->be_hw_params_fixup = diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index e081723bf82e25..b3ba39d61b2a9e 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -3,7 +3,7 @@ ccflags-y += -DDEBUG snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\ - control.o trace.o compressed.o + control.o trace.o compressed.o utils.o snd-sof-spi-objs := hw-spi.o snd-sof-pci-objs := sof-pci-dev.o diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index b523496612d5ae..ce315938243a73 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -210,7 +210,7 @@ static int sof_probe(struct platform_device *pdev) spin_lock_init(&sdev->ipc_lock); spin_lock_init(&sdev->hw_lock); - /* set up platform and component drivers */ + /* set up platform component driver */ snd_sof_new_platform_drv(sdev); snd_sof_new_dai_drv(sdev); @@ -271,14 +271,16 @@ static int sof_probe(struct platform_device *pdev) goto fw_run_err; } - ret = snd_soc_register_component(&pdev->dev, sdev->cmpnt_drv, - &sdev->dai_drv, sdev->num_dai); + ret = snd_soc_register_component(&pdev->dev, sdev->cmpnt_drv, + sdev->ops->dai_drv->drv, + sdev->ops->dai_drv->num_drv); if (ret < 0) { dev_err(sdev->dev, "error: failed to register DSP DAI driver %d\n", ret); goto comp_err; } + /* init DMA trace */ ret = snd_sof_init_trace(sdev); if (ret < 0) { dev_warn(sdev->dev, diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile index dfeb4fcf217b90..7b5784d88fd154 100644 --- a/sound/soc/sof/intel/Makefile +++ b/sound/soc/sof/intel/Makefile @@ -6,7 +6,7 @@ snd-sof-intel-byt-objs := byt.o snd-sof-intel-hsw-objs := hsw.o snd-sof-intel-bdw-objs := bdw.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-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o hda-dai.o\ skl.o apl.o cnl.o obj-$(CONFIG_SND_SOC_SOF_BAYTRAIL) += snd-sof-intel-byt.o diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index d36e30d2a8b388..9db5a246033c15 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -92,5 +92,8 @@ struct snd_sof_dsp_ops sof_apl_ops = { .trace_init = hda_dsp_trace_init, .trace_release = hda_dsp_trace_release, .trace_trigger = hda_dsp_trace_trigger, + + /* DAI drivers */ + .dai_drv = &hda_dai_drv, }; EXPORT_SYMBOL(sof_apl_ops); diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index eb8ee7dd72a21b..47d3896329d25b 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -709,6 +709,32 @@ static int bdw_remove(struct snd_sof_dev *sdev) return 0; } +#define BDW_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +/* Broadwell DAIs */ +static struct snd_soc_dai_driver bdw_dai[] = { +{ + .name = "ssp0-port", + .playback = SOF_DAI_STREAM("ssp0 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BDW_FORMATS), + .capture = SOF_DAI_STREAM("ssp0 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BDW_FORMATS), +}, +{ + .name = "ssp1-port", + .playback = SOF_DAI_STREAM("ssp1 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BDW_FORMATS), + .capture = SOF_DAI_STREAM("ssp1 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BDW_FORMATS), +}, +}; + +struct snd_sof_dai_drv bdw_dai_drv = { + .drv = bdw_dai, + .num_drv = ARRAY_SIZE(bdw_dai) +}; + /* broadwell ops */ struct snd_sof_dsp_ops sof_bdw_ops = { /*Device init */ @@ -750,6 +776,9 @@ struct snd_sof_dsp_ops sof_bdw_ops = { /*Firmware loading */ .load_firmware = snd_sof_load_firmware_memcpy, + + /* DAI drivers */ + .dai_drv = &bdw_dai_drv, }; EXPORT_SYMBOL(sof_bdw_ops); diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index fa76478d5beed9..77a2c7a041cc96 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -750,6 +750,66 @@ static int byt_remove(struct snd_sof_dev *sdev) return byt_acpi_remove(sdev); } +#define BYT_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +/* Baytrail DAIs */ +static struct snd_soc_dai_driver byt_dai[] = { +{ + .name = "ssp0-port", + .playback = SOF_DAI_STREAM("ssp0 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), + .capture = SOF_DAI_STREAM("ssp0 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), +}, +{ + .name = "ssp1-port", + .playback = SOF_DAI_STREAM("ssp1 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), + .capture = SOF_DAI_STREAM("ssp1 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), +}, +{ + .name = "ssp2-port", + .playback = SOF_DAI_STREAM("ssp2 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), + .capture = SOF_DAI_STREAM("ssp2 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), +}, +{ + .name = "ssp3-port", + .playback = SOF_DAI_STREAM("ssp3 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), + .capture = SOF_DAI_STREAM("ssp3 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), +}, +{ + .name = "ssp4-port", + .playback = SOF_DAI_STREAM("ssp4 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), + .capture = SOF_DAI_STREAM("ssp4 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), +}, +{ + .name = "ssp5-port", + .playback = SOF_DAI_STREAM("ssp5 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), + .capture = SOF_DAI_STREAM("ssp5 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), +}, +}; + +struct snd_sof_dai_drv byt_dai_drv = { + .drv = byt_dai, + .num_drv = 3, /* we have only 3 SSPs on byt*/ +}; + +struct snd_sof_dai_drv cht_dai_drv = { + .drv = byt_dai, + /* all 6 SSPs may be available for cherrytrail */ + .num_drv = ARRAY_SIZE(byt_dai), +}; + /* baytrail ops */ struct snd_sof_dsp_ops sof_byt_ops = { /* device init */ @@ -795,6 +855,9 @@ struct snd_sof_dsp_ops sof_byt_ops = { /*Firmware loading */ .load_firmware = snd_sof_load_firmware_memcpy, + + /* DAI drivers */ + .dai_drv = &byt_dai_drv, }; EXPORT_SYMBOL(sof_byt_ops); @@ -843,6 +906,9 @@ struct snd_sof_dsp_ops sof_cht_ops = { /*Firmware loading */ .load_firmware = snd_sof_load_firmware_memcpy, + + /* DAI drivers */ + .dai_drv = &cht_dai_drv, }; EXPORT_SYMBOL(sof_cht_ops); diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 80d6cc772fd74a..99c80d772ad6d6 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -220,5 +220,8 @@ struct snd_sof_dsp_ops sof_cnl_ops = { .trace_init = hda_dsp_trace_init, .trace_release = hda_dsp_trace_release, .trace_trigger = hda_dsp_trace_trigger, + + /* DAI drivers */ + .dai_drv = &hda_dai_drv, }; EXPORT_SYMBOL(sof_cnl_ops); diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c new file mode 100644 index 00000000000000..091fcc1a7e66a0 --- /dev/null +++ b/sound/soc/sof/intel/hda-dai.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Authors: Keyon Jie + */ + +#include +#include "../sof-priv.h" + +#define SKL_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +/* + * common dai driver for skl+ platforms. + * some products who use this DAI array only physically have a subset of + * the DAIs, but no harm is done here by adding the whole set. + */ +static struct snd_soc_dai_driver skl_dai[] = { +{ + .name = "SSP0 Pin", + .playback = SOF_DAI_STREAM("ssp0 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("ssp0 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "SSP1 Pin", + .playback = SOF_DAI_STREAM("ssp1 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("ssp1 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "SSP2 Pin", + .playback = SOF_DAI_STREAM("ssp2 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("ssp2 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "SSP3 Pin", + .playback = SOF_DAI_STREAM("ssp3 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("ssp3 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "SSP4 Pin", + .playback = SOF_DAI_STREAM("ssp4 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("ssp4 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "SSP5 Pin", + .playback = SOF_DAI_STREAM("ssp5 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("ssp5 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "DMIC01 Pin", + .capture = SOF_DAI_STREAM("DMIC01 Rx", 1, 4, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "DMIC16k Pin", + .capture = SOF_DAI_STREAM("DMIC16k Rx", 1, 4, + SNDRV_PCM_RATE_16000, SKL_FORMATS), +}, +{ + .name = "iDisp1 Pin", + .playback = SOF_DAI_STREAM("iDisp1 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "iDisp2 Pin", + .playback = SOF_DAI_STREAM("iDisp2 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "iDisp3 Pin", + .playback = SOF_DAI_STREAM("iDisp3 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "Analog Codec DAI", + .playback = SOF_DAI_STREAM("Analog Codec Playback", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("Analog Codec Capture", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "Digital Codec DAI", + .playback = SOF_DAI_STREAM("Digital Codec Playback", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("Digital Codec Capture", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "Alt Analog Codec DAI", + .playback = SOF_DAI_STREAM("Alt Analog Codec Playback", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("Alt Analog Codec Capture", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +}; + +struct snd_sof_dai_drv hda_dai_drv = { + .drv = skl_dai, + .num_drv = ARRAY_SIZE(skl_dai) +}; +EXPORT_SYMBOL(hda_dai_drv); + diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 5eb677c601dd4f..75f5b409d743bc 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -494,6 +494,9 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag); int hda_dsp_trace_release(struct snd_sof_dev *sdev); int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd); +/* common dai driver */ +extern struct snd_sof_dai_drv hda_dai_drv; + /* * Platform Specific HW abstraction Ops. */ diff --git a/sound/soc/sof/intel/hsw.c b/sound/soc/sof/intel/hsw.c index e4016738123a3c..5e2c50b47b7502 100644 --- a/sound/soc/sof/intel/hsw.c +++ b/sound/soc/sof/intel/hsw.c @@ -709,6 +709,32 @@ static int hsw_remove(struct snd_sof_dev *sdev) return 0; } +#define HSW_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +/* Haswell DAIs */ +static struct snd_soc_dai_driver hsw_dai[] = { +{ + .name = "ssp0-port", + .playback = SOF_DAI_STREAM("ssp0 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, HSW_FORMATS), + .capture = SOF_DAI_STREAM("ssp0 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, HSW_FORMATS), +}, +{ + .name = "ssp1-port", + .playback = SOF_DAI_STREAM("ssp1 Tx", 1, 8, + SNDRV_PCM_RATE_8000_192000, HSW_FORMATS), + .capture = SOF_DAI_STREAM("ssp1 Rx", 1, 8, + SNDRV_PCM_RATE_8000_192000, HSW_FORMATS), +}, +}; + +struct snd_sof_dai_drv hsw_dai_drv = { + .drv = hsw_dai, + .num_drv = ARRAY_SIZE(hsw_dai) +}; + /* haswell ops */ struct snd_sof_dsp_ops sof_hsw_ops = { /*Device init */ @@ -751,6 +777,9 @@ struct snd_sof_dsp_ops sof_hsw_ops = { /*Firmware loading */ .load_firmware = snd_sof_load_firmware_memcpy, + /* DAI drivers */ + .dai_drv = &hsw_dai_drv, + }; EXPORT_SYMBOL(sof_hsw_ops); diff --git a/sound/soc/sof/intel/skl.c b/sound/soc/sof/intel/skl.c index d4b6de626456b1..adb85a579b697e 100644 --- a/sound/soc/sof/intel/skl.c +++ b/sound/soc/sof/intel/skl.c @@ -97,5 +97,8 @@ struct snd_sof_dsp_ops sof_skl_ops = { .trace_init = hda_dsp_trace_init, .trace_release = hda_dsp_trace_release, .trace_trigger = hda_dsp_trace_trigger, + + /* DAI drivers */ + .dai_drv = &hda_dai_drv, }; EXPORT_SYMBOL(sof_skl_ops); diff --git a/sound/soc/sof/nocodec.c b/sound/soc/sof/nocodec.c index 0685d29f9d28b1..0e1e271fb583a3 100644 --- a/sound/soc/sof/nocodec.c +++ b/sound/soc/sof/nocodec.c @@ -20,12 +20,21 @@ #include #include #include +#include "sof-priv.h" + +static struct snd_soc_card sof_nocodec_card = { + .name = "sof-nocodec", +}; int sof_nocodec_setup(struct device *dev, struct snd_sof_pdata *sof_pdata, struct snd_soc_acpi_mach *mach, - const struct sof_dev_desc *desc) + const struct sof_dev_desc *desc, + struct snd_sof_dsp_ops *ops) { + struct snd_soc_dai_link *links; + int ret; + if (!mach) return -EINVAL; @@ -35,54 +44,22 @@ int sof_nocodec_setup(struct device *dev, mach->sof_fw_filename = desc->nocodec_fw_filename; mach->sof_tplg_filename = desc->nocodec_tplg_filename; - return 0; -} -EXPORT_SYMBOL(sof_nocodec_setup); - -static int sof_nocodec_codec_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - // TODO: read this from topology - return 0; -} - -static struct snd_soc_ops sof_nocodec_ops = {}; + /* create dummy BE dai_links */ + links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) * + ops->dai_drv->num_drv, GFP_KERNEL); + if (!links) + return -ENOMEM; -static int nocodec_rtd_init(struct snd_soc_pcm_runtime *rtd) -{ - snd_soc_set_dmi_name(rtd->card, NULL); + ret = sof_bes_setup(dev, ops, links, ops->dai_drv->num_drv, + &sof_nocodec_card); + if (ret) { + kfree(links); + return ret; + } return 0; } - -/* we just set some BEs - FE provided by topology */ -static struct snd_soc_dai_link sof_nocodec_dais[] = { - /* Back End DAI links */ - { - /* SSP0 - Codec */ - .name = "NoCodec", - .id = 0, - .init = nocodec_rtd_init, - .cpu_dai_name = "sof-audio", - .platform_name = "sof-audio", - .no_pcm = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ops = &sof_nocodec_ops, - .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ignore_suspend = 1, - .be_hw_params_fixup = sof_nocodec_codec_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, - }, -}; - -static struct snd_soc_card sof_nocodec_card = { - .name = "sof-nocodec", - .dai_link = sof_nocodec_dais, - .num_links = ARRAY_SIZE(sof_nocodec_dais), -}; +EXPORT_SYMBOL(sof_nocodec_setup); static int sof_nocodec_probe(struct platform_device *pdev) { diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 558d054af826cd..9a7f16eb0f3057 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -625,30 +625,12 @@ void snd_sof_new_platform_drv(struct snd_sof_dev *sdev) pd->topology_name_prefix = "sof"; } -static const struct snd_soc_dai_ops sof_dai_ops = { -}; - static const struct snd_soc_component_driver sof_dai_component = { - .name = "sof-dai", + .name = "sof-dai", }; -#define SOF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_FLOAT) - void snd_sof_new_dai_drv(struct snd_sof_dev *sdev) { - struct snd_soc_dai_driver *dd = &sdev->dai_drv; - //struct snd_sof_pdata *plat_data = sdev->pdata; - sdev->cmpnt_drv = &sof_dai_component; - dd->playback.channels_min = 1; - dd->playback.channels_max = 16; - dd->playback.rates = SNDRV_PCM_RATE_8000_192000; - dd->playback.formats = SOF_FORMATS; - dd->capture.channels_min = 1; - dd->capture.channels_max = 16; - dd->capture.rates = SNDRV_PCM_RATE_8000_192000; - dd->capture.formats = SOF_FORMATS; - dd->ops = &sof_dai_ops; - sdev->num_dai = 1; } + diff --git a/sound/soc/sof/sof-acpi-dev.c b/sound/soc/sof/sof-acpi-dev.c index dd71297e8c2558..fec3b012ae7191 100644 --- a/sound/soc/sof/sof-acpi-dev.c +++ b/sound/soc/sof/sof-acpi-dev.c @@ -246,7 +246,7 @@ static int sof_acpi_probe(struct platform_device *pdev) /* force nocodec mode */ dev_warn(dev, "Force to use nocodec mode\n"); mach = devm_kzalloc(dev, sizeof(*mach), GFP_KERNEL); - ret = sof_nocodec_setup(dev, sof_pdata, mach, desc); + ret = sof_nocodec_setup(dev, sof_pdata, mach, desc, ops); if (ret < 0) return ret; #else @@ -257,7 +257,7 @@ static int sof_acpi_probe(struct platform_device *pdev) /* fallback to nocodec mode */ dev_warn(dev, "No matching ASoC machine driver found - using nocodec\n"); mach = devm_kzalloc(dev, sizeof(*mach), GFP_KERNEL); - ret = sof_nocodec_setup(dev, sof_pdata, mach, desc); + ret = sof_nocodec_setup(dev, sof_pdata, mach, desc, ops); if (ret < 0) return ret; #else diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 7a2d48e0d34764..83c71ac3418eb8 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -226,7 +226,7 @@ static int sof_pci_probe(struct pci_dev *pci, /* force nocodec mode */ dev_warn(dev, "Force to use nocodec mode\n"); mach = devm_kzalloc(dev, sizeof(*mach), GFP_KERNEL); - ret = sof_nocodec_setup(dev, sof_pdata, mach, desc); + ret = sof_nocodec_setup(dev, sof_pdata, mach, desc, ops); if (ret < 0) return ret; #else @@ -237,7 +237,7 @@ static int sof_pci_probe(struct pci_dev *pci, /* fallback to nocodec mode */ dev_warn(dev, "No matching ASoC machine driver found - using nocodec\n"); mach = devm_kzalloc(dev, sizeof(*mach), GFP_KERNEL); - ret = sof_nocodec_setup(dev, sof_pdata, mach, desc); + ret = sof_nocodec_setup(dev, sof_pdata, mach, desc, ops); if (ret < 0) return ret; #else diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index fabfcb25180940..271f649029a956 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -43,6 +43,14 @@ /* max number of FE PCMs before BEs */ #define SOF_BE_PCM_BASE 16 +/* convenience constructor for DAI driver streams */ +#define SOF_DAI_STREAM(sname, scmin, scmax, srates, sfmt) \ + {.stream_name = sname, .channels_min = scmin, .channels_max = scmax, \ + .rates = srates, .formats = sfmt} + +#define SOF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_FLOAT) + struct snd_sof_dev; struct snd_sof_ipc_msg; struct snd_sof_ipc; @@ -52,6 +60,11 @@ struct snd_soc_component; struct sof_intel_hda_dev; struct snd_sof_pdata; +struct snd_sof_dai_drv { + struct snd_soc_dai_driver *drv; + int num_drv; +}; + /* * SOF DSP HW abstraction operations. * Used to abstract DSP HW architecture and any IO busses between host CPU @@ -139,6 +152,9 @@ struct snd_sof_dsp_ops { int (*trace_init)(struct snd_sof_dev *sdev, u32 *stream_tag); int (*trace_release)(struct snd_sof_dev *sdev); int (*trace_trigger)(struct snd_sof_dev *sdev, int cmd); + + /* DAI ops */ + struct snd_sof_dai_drv *dai_drv; }; /* DSP architecture specific callbacks for oops and stack dumps */ @@ -263,8 +279,6 @@ struct snd_sof_dev { /* ASoC components */ struct snd_soc_platform_driver plat_drv; const struct snd_soc_component_driver *cmpnt_drv; - struct snd_soc_dai_driver dai_drv; - int num_dai; /* DSP firmware boot */ wait_queue_head_t boot_wait; diff --git a/sound/soc/sof/utils.c b/sound/soc/sof/utils.c new file mode 100644 index 00000000000000..8f2116a453526e --- /dev/null +++ b/sound/soc/sof/utils.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Keyon Jie + */ + +#include +#include +#include +#include "sof-priv.h" + +int sof_bes_setup(struct device *dev, struct snd_sof_dsp_ops *ops, + struct snd_soc_dai_link *links, int link_num, + struct snd_soc_card *card) +{ + char name[32]; + int i; + + if (!ops || !links || !card) + return -EINVAL; + + /* set up BE dai_links */ + for (i = 0; i < link_num; i++) { + snprintf(name, 32, "NoCodec-%d", i); + links[i].name = kmemdup(name, sizeof(name), GFP_KERNEL); + if (!links[i].name) + goto no_mem; + + links[i].id = i; + links[i].no_pcm = 1; + links[i].cpu_dai_name = ops->dai_drv->drv[i].name; + links[i].platform_name = "sof-audio"; + links[i].codec_dai_name = "snd-soc-dummy-dai"; + links[i].codec_name = "snd-soc-dummy"; + links[i].dpcm_playback = 1; + links[i].dpcm_capture = 1; + } + + card->dai_link = links; + card->num_links = link_num; + + return 0; +no_mem: + /* free allocated memories and return error */ + for (; i > 0; i--) + kfree(links[i - 1].name); + + return -ENOMEM; +} +EXPORT_SYMBOL(sof_bes_setup); +