diff --git a/include/sound/soc-acpi-intel-match.h b/include/sound/soc-acpi-intel-match.h index 917ddd0f2762ea..1de9ed784c1b23 100644 --- a/include/sound/soc-acpi-intel-match.h +++ b/include/sound/soc-acpi-intel-match.h @@ -34,5 +34,6 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_bxt_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[]; +extern struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[]; #endif diff --git a/include/sound/sof.h b/include/sound/sof.h index f6056247c3a75f..cc1c9d2681c7bf 100644 --- a/include/sound/sof.h +++ b/include/sound/sof.h @@ -76,6 +76,7 @@ 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); #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/intel/common/Makefile b/sound/soc/intel/common/Makefile index 915a34cdc8acbb..fd52419f1c814a 100644 --- a/sound/soc/intel/common/Makefile +++ b/sound/soc/intel/common/Makefile @@ -7,7 +7,7 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m soc-acpi-intel-hsw-bdw-match.o \ soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \ soc-acpi-intel-bxt-match.o soc-acpi-intel-glk-match.o \ - soc-acpi-intel-cnl-match.o + soc-acpi-intel-cnl-match.o soc-acpi-intel-icl-match.o obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o diff --git a/sound/soc/intel/common/soc-acpi-intel-icl-match.c b/sound/soc/intel/common/soc-acpi-intel-icl-match.c new file mode 100644 index 00000000000000..a141bbf8bc11f2 --- /dev/null +++ b/sound/soc/intel/common/soc-acpi-intel-icl-match.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * soc-apci-intel-icl-match.c - tables and support for ICL ACPI enumeration. + * + * Copyright (c) 2018, Intel Corporation. + * + */ + +#include +#include +#include "../skylake/skl.h" + +static struct skl_machine_pdata icl_pdata = { + .use_tplg_pcm = true, +}; + +struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[] = { + { + .id = "INT34C2", + .drv_name = "sof-nocodec", + .fw_filename = "intel/dsp_fw_icl.bin", + .pdata = &icl_pdata, + .sof_fw_filename = "intel/sof-icl.ri", + .sof_tplg_filename = "intel/sof-icl.tplg", + .asoc_plat_name = "0000:00:0e.0", + }, + {}, +}; +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Intel Common ACPI Match module"); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a0160a409e4094..1ddf2f7ffeaf8d 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2126,7 +2126,6 @@ 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; diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index b523496612d5ae..b7bd1466303257 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->drv, + sdev->ops->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/Kconfig b/sound/soc/sof/intel/Kconfig index d9b4b6a23f6021..85750054a5c90c 100644 --- a/sound/soc/sof/intel/Kconfig +++ b/sound/soc/sof/intel/Kconfig @@ -87,6 +87,15 @@ config SND_SOC_SOF_SKYLAKE Say Y if you have such a device. If unsure select "N". +config SND_SOC_SOF_ICELAKE + tristate "SOF support for Icelake" + select SND_SOC_SOF_HDA_COMMON + help + This adds support for Sound Open Firmware for Intel(R) platforms + using the Icelake processors. + Say Y if you have such a device. + If unsure select "N". + config SND_SOC_SOF_HDA_COMMON tristate select SND_SOC_SOF_PCI diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index d36e30d2a8b388..e505e79822957c 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -40,6 +40,110 @@ static const struct snd_sof_debugfs_map apl_dsp_debugfs[] = { {"dsp", HDA_DSP_BAR, 0, 0x10000}, }; +static const struct snd_soc_dai_ops apl_dai_ops = { +}; + +#define APL_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_FLOAT) + +/* Apollolake DAIs */ +static struct snd_soc_dai_driver apl_dai[] = { +{ + .name = "SSP0 Pin", + .ops = &apl_dai_ops, + .playback = SOF_DAI_STREAM("ssp0 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), + .capture = SOF_DAI_STREAM("ssp0 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), +}, +{ + .name = "SSP1 Pin", + .ops = &apl_dai_ops, + .playback = SOF_DAI_STREAM("ssp1 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), + .capture = SOF_DAI_STREAM("ssp1 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), +}, +{ + .name = "SSP2 Pin", + .ops = &apl_dai_ops, + .playback = SOF_DAI_STREAM("ssp2 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), + .capture = SOF_DAI_STREAM("ssp2 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), +}, +{ + .name = "SSP3 Pin", + .ops = &apl_dai_ops, + .playback = SOF_DAI_STREAM("ssp3 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), + .capture = SOF_DAI_STREAM("ssp3 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), +}, +{ + .name = "SSP4 Pin", + .ops = &apl_dai_ops, + .playback = SOF_DAI_STREAM("ssp4 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), + .capture = SOF_DAI_STREAM("ssp4 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), +}, +{ + .name = "SSP5 Pin", + .ops = &apl_dai_ops, + .playback = SOF_DAI_STREAM("ssp5 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), + .capture = SOF_DAI_STREAM("ssp5 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), +}, +{ + .name = "DMIC01 Pin", + .ops = &apl_dai_ops, + .capture = SOF_DAI_STREAM("DMIC01 Rx", 1, 4, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), +}, +{ + .name = "DMIC16k Pin", + .ops = &apl_dai_ops, + .capture = SOF_DAI_STREAM("DMIC16k Rx", 1, 4, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), +}, +{ + .name = "iDisp1 Pin", + .ops = &apl_dai_ops, + .playback = SOF_DAI_STREAM("iDisp1 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), +}, +{ + .name = "iDisp2 Pin", + .ops = &apl_dai_ops, + .playback = SOF_DAI_STREAM("iDisp2 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), +}, +{ + .name = "iDisp3 Pin", + .ops = &apl_dai_ops, + .playback = SOF_DAI_STREAM("iDisp3 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), +}, +{ + .name = "HD-Codec Pin", + .ops = &apl_dai_ops, + .playback = SOF_DAI_STREAM("HD-Codec Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), + .capture = SOF_DAI_STREAM("HD-Codec Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, APL_FORMATS), +}, +{ + .name = "sof-nocodec-dai", + .ops = &apl_dai_ops, + .playback = SOF_DAI_STREAM("DAI0 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SOF_FORMATS), + .capture = SOF_DAI_STREAM("DAI0 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SOF_FORMATS), +}, +}; + /* apollolake ops */ struct snd_sof_dsp_ops sof_apl_ops = { /* probe and remove */ @@ -92,5 +196,9 @@ 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 */ + .drv = apl_dai, + .num_drv = ARRAY_SIZE(apl_dai), }; EXPORT_SYMBOL(sof_apl_ops); diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index eb8ee7dd72a21b..c3deaf14a79f8f 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -709,6 +709,40 @@ static int bdw_remove(struct snd_sof_dev *sdev) return 0; } +static const struct snd_soc_dai_ops bdw_dai_ops = { +}; + +#define BDW_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_FLOAT) + +/* Broadwell DAIs */ +static struct snd_soc_dai_driver bdw_dai[] = { +{ + .name = "ssp0-port", + .ops = &bdw_dai_ops, + .playback = SOF_DAI_STREAM("ssp0 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, BDW_FORMATS), + .capture = SOF_DAI_STREAM("ssp0 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, BDW_FORMATS), +}, +{ + .name = "ssp1-port", + .ops = &bdw_dai_ops, + .playback = SOF_DAI_STREAM("ssp1 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, BDW_FORMATS), + .capture = SOF_DAI_STREAM("ssp1 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, BDW_FORMATS), +}, +{ + .name = "sof-nocodec-dai", + .ops = &bdw_dai_ops, + .playback = SOF_DAI_STREAM("DAI0 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SOF_FORMATS), + .capture = SOF_DAI_STREAM("DAI0 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SOF_FORMATS), +}, +}; + /* broadwell ops */ struct snd_sof_dsp_ops sof_bdw_ops = { /*Device init */ @@ -750,6 +784,10 @@ struct snd_sof_dsp_ops sof_bdw_ops = { /*Firmware loading */ .load_firmware = snd_sof_load_firmware_memcpy, + + /* DAI drivers */ + .drv = bdw_dai, + .num_drv = ARRAY_SIZE(bdw_dai), }; EXPORT_SYMBOL(sof_bdw_ops); diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index fa76478d5beed9..49766bbb786558 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -750,6 +750,48 @@ static int byt_remove(struct snd_sof_dev *sdev) return byt_acpi_remove(sdev); } +static const struct snd_soc_dai_ops byt_dai_ops = { +}; + +#define BYT_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_FLOAT) + +/* Baytrail DAIs */ +static struct snd_soc_dai_driver byt_dai[] = { +{ + .name = "ssp0-port", + .ops = &byt_dai_ops, + .playback = SOF_DAI_STREAM("ssp0 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), + .capture = SOF_DAI_STREAM("ssp0 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), +}, +{ + .name = "ssp1-port", + .ops = &byt_dai_ops, + .playback = SOF_DAI_STREAM("ssp1 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), + .capture = SOF_DAI_STREAM("ssp1 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), +}, +{ + .name = "ssp2-port", + .ops = &byt_dai_ops, + .playback = SOF_DAI_STREAM("ssp2 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), + .capture = SOF_DAI_STREAM("ssp2 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, BYT_FORMATS), +}, +{ + .name = "sof-nocodec-dai", + .ops = &byt_dai_ops, + .playback = SOF_DAI_STREAM("DAI0 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SOF_FORMATS), + .capture = SOF_DAI_STREAM("DAI0 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SOF_FORMATS), +}, +}; + /* baytrail ops */ struct snd_sof_dsp_ops sof_byt_ops = { /* device init */ @@ -795,6 +837,10 @@ struct snd_sof_dsp_ops sof_byt_ops = { /*Firmware loading */ .load_firmware = snd_sof_load_firmware_memcpy, + + /* DAI drivers */ + .drv = byt_dai, + .num_drv = 3, /* BYT only has 3 SSPs */ }; EXPORT_SYMBOL(sof_byt_ops); @@ -843,6 +889,10 @@ struct snd_sof_dsp_ops sof_cht_ops = { /*Firmware loading */ .load_firmware = snd_sof_load_firmware_memcpy, + + /* DAI drivers */ + .drv = byt_dai, + .num_drv = ARRAY_SIZE(byt_dai), }; EXPORT_SYMBOL(sof_cht_ops); diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 80d6cc772fd74a..860988f4d076e3 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -168,6 +168,111 @@ static int cnl_ipc_send_msg(struct snd_sof_dev *sdev, return 0; } +static const struct snd_soc_dai_ops cnl_dai_ops = { +}; + +#define CNL_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_FLOAT) + +/* Cannonlake DAIs */ +static struct snd_soc_dai_driver cnl_dai[] = { +{ + .name = "SSP0 Pin", + .ops = &cnl_dai_ops, + .playback = SOF_DAI_STREAM("ssp0 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), + .capture = SOF_DAI_STREAM("ssp0 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), +}, +{ + .name = "SSP1 Pin", + .ops = &cnl_dai_ops, + .playback = SOF_DAI_STREAM("ssp1 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), + .capture = SOF_DAI_STREAM("ssp1 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), +}, +{ + .name = "SSP2 Pin", + .ops = &cnl_dai_ops, + .playback = SOF_DAI_STREAM("ssp2 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), + .capture = SOF_DAI_STREAM("ssp2 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), +}, +{ + .name = "SSP3 Pin", + .ops = &cnl_dai_ops, + .playback = SOF_DAI_STREAM("ssp3 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), + .capture = SOF_DAI_STREAM("ssp3 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), +}, +{ + .name = "SSP4 Pin", + .ops = &cnl_dai_ops, + .playback = SOF_DAI_STREAM("ssp4 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), + .capture = SOF_DAI_STREAM("ssp4 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), +}, +{ + .name = "SSP5 Pin", + .ops = &cnl_dai_ops, + .playback = SOF_DAI_STREAM("ssp5 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), + .capture = SOF_DAI_STREAM("ssp5 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), +}, +{ + .name = "DMIC01 Pin", + .ops = &cnl_dai_ops, + .capture = SOF_DAI_STREAM("DMIC01 Rx", 1, 4, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), +}, +{ + .name = "DMIC16k Pin", + .ops = &cnl_dai_ops, + .capture = SOF_DAI_STREAM("DMIC16k Rx", 1, 4, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), +}, +{ + .name = "iDisp1 Pin", + .ops = &cnl_dai_ops, + .playback = SOF_DAI_STREAM("iDisp1 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), +}, +{ + .name = "iDisp2 Pin", + .ops = &cnl_dai_ops, + .playback = SOF_DAI_STREAM("iDisp2 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), +}, +{ + .name = "iDisp3 Pin", + .ops = &cnl_dai_ops, + .playback = SOF_DAI_STREAM("iDisp3 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), +}, +{ + .name = "HD-Codec Pin", + .ops = &cnl_dai_ops, + .playback = SOF_DAI_STREAM("HD-Codec Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), + .capture = SOF_DAI_STREAM("HD-Codec Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, CNL_FORMATS), +}, +{ + .name = "sof-nocodec-dai", + .ops = &cnl_dai_ops, + .playback = SOF_DAI_STREAM("DAI0 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SOF_FORMATS), + .capture = SOF_DAI_STREAM("DAI0 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SOF_FORMATS), +}, +}; + + /* cannonlake ops */ struct snd_sof_dsp_ops sof_cnl_ops = { /* probe and remove */ @@ -220,5 +325,9 @@ 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 */ + .drv = cnl_dai, + .num_drv = ARRAY_SIZE(cnl_dai), }; EXPORT_SYMBOL(sof_cnl_ops); diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 7949d6d5508025..5542851f2e5af4 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -283,6 +283,21 @@ static const struct sof_intel_dsp_desc chip_info[] = { .ipc_ctl = CNL_DSP_REG_HIPCCTL, .ops = &sof_cnl_ops, }, +{ + /* Icelake */ + .id = 0x34c8, + .cores_num = 4, + .cores_mask = HDA_DSP_CORE_MASK(0) | + HDA_DSP_CORE_MASK(1) | + HDA_DSP_CORE_MASK(2) | + HDA_DSP_CORE_MASK(3), + .ipc_req = CNL_DSP_REG_HIPCIDR, + .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY, + .ipc_ack = CNL_DSP_REG_HIPCIDA, + .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE, + .ipc_ctl = CNL_DSP_REG_HIPCCTL, + .ops = &sof_cnl_ops, +}, }; static const struct sof_intel_dsp_desc *get_chip_info(int pci_id) diff --git a/sound/soc/sof/intel/hsw.c b/sound/soc/sof/intel/hsw.c index e4016738123a3c..319ed7dd1a8f66 100644 --- a/sound/soc/sof/intel/hsw.c +++ b/sound/soc/sof/intel/hsw.c @@ -709,6 +709,40 @@ static int hsw_remove(struct snd_sof_dev *sdev) return 0; } +static const struct snd_soc_dai_ops hsw_dai_ops = { +}; + +#define HSW_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_FLOAT) + +/* Haswell DAIs */ +static struct snd_soc_dai_driver hsw_dai[] = { +{ + .name = "ssp0-port", + .ops = &hsw_dai_ops, + .playback = SOF_DAI_STREAM("ssp0 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, HSW_FORMATS), + .capture = SOF_DAI_STREAM("ssp0 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, HSW_FORMATS), +}, +{ + .name = "ssp1-port", + .ops = &hsw_dai_ops, + .playback = SOF_DAI_STREAM("ssp1 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, HSW_FORMATS), + .capture = SOF_DAI_STREAM("ssp1 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, HSW_FORMATS), +}, +{ + .name = "sof-nocodec-dai", + .ops = &hsw_dai_ops, + .playback = SOF_DAI_STREAM("DAI0 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SOF_FORMATS), + .capture = SOF_DAI_STREAM("DAI0 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SOF_FORMATS), +}, +}; + /* haswell ops */ struct snd_sof_dsp_ops sof_hsw_ops = { /*Device init */ @@ -751,6 +785,10 @@ struct snd_sof_dsp_ops sof_hsw_ops = { /*Firmware loading */ .load_firmware = snd_sof_load_firmware_memcpy, + /* DAI drivers */ + .drv = hsw_dai, + .num_drv = ARRAY_SIZE(hsw_dai), + }; EXPORT_SYMBOL(sof_hsw_ops); diff --git a/sound/soc/sof/intel/skl.c b/sound/soc/sof/intel/skl.c index d4b6de626456b1..80e9716080f131 100644 --- a/sound/soc/sof/intel/skl.c +++ b/sound/soc/sof/intel/skl.c @@ -45,6 +45,110 @@ int skl_run_firmware(struct snd_sof_dev *sdev) return 0; } +static const struct snd_soc_dai_ops skl_dai_ops = { +}; + +#define SKL_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_FLOAT) + +/* Skylake DAIs */ +static struct snd_soc_dai_driver skl_dai[] = { +{ + .name = "SSP0 Pin", + .ops = &skl_dai_ops, + .playback = SOF_DAI_STREAM("ssp0 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("ssp0 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "SSP1 Pin", + .ops = &skl_dai_ops, + .playback = SOF_DAI_STREAM("ssp1 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("ssp1 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "SSP2 Pin", + .ops = &skl_dai_ops, + .playback = SOF_DAI_STREAM("ssp2 Tx", 1, 16, + 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", + .ops = &skl_dai_ops, + .playback = SOF_DAI_STREAM("ssp3 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("ssp3 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "SSP4 Pin", + .ops = &skl_dai_ops, + .playback = SOF_DAI_STREAM("ssp4 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("ssp4 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "SSP5 Pin", + .ops = &skl_dai_ops, + .playback = SOF_DAI_STREAM("ssp5 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("ssp5 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "DMIC01 Pin", + .ops = &skl_dai_ops, + .capture = SOF_DAI_STREAM("DMIC01 Rx", 1, 4, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "DMIC16k Pin", + .ops = &skl_dai_ops, + .capture = SOF_DAI_STREAM("DMIC16k Rx", 1, 4, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "iDisp1 Pin", + .ops = &skl_dai_ops, + .playback = SOF_DAI_STREAM("iDisp1 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "iDisp2 Pin", + .ops = &skl_dai_ops, + .playback = SOF_DAI_STREAM("iDisp2 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "iDisp3 Pin", + .ops = &skl_dai_ops, + .playback = SOF_DAI_STREAM("iDisp3 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "HD-Codec Pin", + .ops = &skl_dai_ops, + .playback = SOF_DAI_STREAM("HD-Codec Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), + .capture = SOF_DAI_STREAM("HD-Codec Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SKL_FORMATS), +}, +{ + .name = "sof-nocodec-dai", + .ops = &skl_dai_ops, + .playback = SOF_DAI_STREAM("DAI0 Tx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SOF_FORMATS), + .capture = SOF_DAI_STREAM("DAI0 Rx", 1, 16, + SNDRV_PCM_RATE_8000_192000, SOF_FORMATS), +}, +}; + /* skylake ops */ struct snd_sof_dsp_ops sof_skl_ops = { /* probe and remove */ @@ -97,5 +201,9 @@ 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 */ + .drv = skl_dai, + .num_drv = ARRAY_SIZE(skl_dai), }; EXPORT_SYMBOL(sof_skl_ops); diff --git a/sound/soc/sof/nocodec.c b/sound/soc/sof/nocodec.c index 0685d29f9d28b1..c123174c1feff9 100644 --- a/sound/soc/sof/nocodec.c +++ b/sound/soc/sof/nocodec.c @@ -20,24 +20,7 @@ #include #include #include - -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) -{ - if (!mach) - return -EINVAL; - - sof_pdata->drv_name = "sof-nocodec"; - - mach->drv_name = "sof-nocodec"; - mach->sof_fw_filename = desc->nocodec_fw_filename; - mach->sof_tplg_filename = desc->nocodec_tplg_filename; - - return 0; -} -EXPORT_SYMBOL(sof_nocodec_setup); +#include "sof-priv.h" static int sof_nocodec_codec_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) @@ -55,35 +38,61 @@ static int nocodec_rtd_init(struct snd_soc_pcm_runtime *rtd) 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), }; +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, + struct snd_sof_dsp_ops *ops) +{ + struct snd_soc_dai_link *links; + char name[32]; + int i; + + if (!mach) + return -EINVAL; + + sof_pdata->drv_name = "sof-nocodec"; + + mach->drv_name = "sof-nocodec"; + mach->sof_fw_filename = desc->nocodec_fw_filename; + mach->sof_tplg_filename = desc->nocodec_tplg_filename; + + /* create dummy BE dai_links */ + links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) * + ops->num_drv, GFP_KERNEL); + if (!links) + return -ENOMEM; + + for (i = 0; i < ops->num_drv; i++) { + snprintf(name, 32, "NoCodec-%d", i); + links[i].name = kmemdup(name, sizeof(name), GFP_KERNEL); + links[i].id = i; + links[i].init = nocodec_rtd_init; + links[i].no_pcm = 1; + links[i].cpu_dai_name = ops->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].ops = &sof_nocodec_ops; + links[i].dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS; + links[i].ignore_suspend = 1; + links[i].be_hw_params_fixup = sof_nocodec_codec_fixup; + links[i].dpcm_playback = 1; + links[i].dpcm_capture = 1; + } + + sof_nocodec_card.dai_link = links; + sof_nocodec_card.num_links = ops->num_drv; + + return 0; +} +EXPORT_SYMBOL(sof_nocodec_setup); + static int sof_nocodec_probe(struct platform_device *pdev) { struct snd_soc_card *card = &sof_nocodec_card; 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..ce3c232aa49fd9 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -114,6 +114,19 @@ static struct sof_dev_desc kbl_desc = { }; #endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) +static const struct sof_dev_desc icl_desc = { + .machines = snd_soc_acpi_intel_icl_machines, + .resindex_lpe_base = 0, + .resindex_pcicfg_base = -1, + .resindex_imr_base = -1, + .irqindex_host_ipc = -1, + .resindex_dma_base = -1, + .nocodec_fw_filename = "intel/sof-icl.ri", + .nocodec_tplg_filename = "intel/sof-icl-nocodec.tplg" +}; +#endif + struct sof_pci_priv { struct snd_sof_pdata *sof_pdata; struct platform_device *pdev_pcm; @@ -169,6 +182,9 @@ static const struct sof_ops_table mach_ops[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_KABYLAKE) {&kbl_desc, &sof_apl_ops}, #endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) + {&icl_desc, &sof_cnl_ops}, +#endif }; static struct snd_sof_dsp_ops *sof_pci_get_ops(const struct sof_dev_desc *d) @@ -226,7 +242,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 +253,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 @@ -321,6 +337,11 @@ static const struct pci_device_id sof_pci_ids[] = { { PCI_DEVICE(0x8086, 0x9d70), .driver_data = (unsigned long)&skl_desc}, #endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) + { PCI_DEVICE(0x8086, 0x34C8), + .driver_data = (unsigned long)&icl_desc}, +#endif + { 0, } }; MODULE_DEVICE_TABLE(pci, sof_pci_ids); diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index fabfcb25180940..5fcbf6d84200fa 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; @@ -139,6 +147,10 @@ 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_soc_dai_driver *drv; + int num_drv; }; /* DSP architecture specific callbacks for oops and stack dumps */ @@ -263,8 +275,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;