diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 01c3e7af7897ba..00d681350746f6 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -436,13 +436,13 @@ config SND_SOC_INTEL_SOF_RT5682_MACH If unsure select "N". endif ## SND_SOC_SOF_HDA_COMMON || SND_SOC_SOF_BAYTRAIL -if SND_SOC_INTEL_SKYLAKE -config SND_SOC_INTEL_CNL_RT700_MACH - tristate "SOC Machine Audio driver for CNL Platform" - depends on X86 && ACPI +if SND_SOC_SOF_SOUNDWIRE +config SND_SOC_INTEL_SOUNDWIRE_RT700_MACH + tristate "CNL with RT700 codec" + depends on SOUNDWIRE && ACPI select SND_SOC_RT700 select SND_SOC_RT700_SDW - select SND_SOC_DMIC + select SND_SOC_HDAC_HDMI if SND_SOC_SOF_HDA help This adds support for ASoC machine driver . This will create an alsa sound card. diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index 203f9d3f8f18b4..166a5cb31b5842 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -61,5 +61,5 @@ obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH) += snd-skl_nau88l25_max98357a.o obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH) += snd-soc-skl_nau88l25_ssm4567.o obj-$(CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH) += snd-soc-skl_hda_dsp.o -obj-$(CONFIG_SND_SOC_INTEL_CNL_RT700_MACH) += snd-soc-cnl_rt700.o +obj-$(CONFIG_SND_SOC_INTEL_SOUNDWIRE_RT700_MACH) += snd-soc-cnl_rt700.o diff --git a/sound/soc/intel/boards/cnl_rt700.c b/sound/soc/intel/boards/cnl_rt700.c index e5dac8b58b9060..9ac04b70d084f8 100644 --- a/sound/soc/intel/boards/cnl_rt700.c +++ b/sound/soc/intel/boards/cnl_rt700.c @@ -1,10 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2016-19 Intel Corp + /* * cnl_rt700.c - ASOC Machine driver for Intel cnl_rt700 platform * with ALC700 SoundWire codec. * - * Copyright (C) 2016 Intel Corp - * Author: Hardik Shah - * * Based on * moor_dpcm_florida.c - ASOC Machine driver for Intel Moorefield platform * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -21,119 +21,115 @@ * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include -#include -#include -#include -#include +#include #include #include +#include #include -#include +#include +#include +#include +#include +#include +#include #include #include #include -#include -#include +#include +#include "../../codecs/hdac_hdmi.h" struct cnl_rt700_mc_private { - u8 pmic_id; - void __iomem *osc_clk0_reg; - int bt_mode; + struct list_head hdmi_pcm_list; }; -#ifndef CONFIG_SND_SOC_SDW_AGGM1M2 -static const struct snd_soc_dapm_widget cnl_rt700_widgets[] = { - SND_SOC_DAPM_HP("Headphones", NULL), - SND_SOC_DAPM_MIC("AMIC", NULL), - SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("Speaker", NULL), +#if IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI) +static struct snd_soc_jack cnl_hdmi[3]; + +struct cnl_hdmi_pcm { + struct list_head head; + struct snd_soc_dai *codec_dai; + int device; }; + +static int cnl_hdmi_init(struct snd_soc_pcm_runtime *rtd) +{ + struct cnl_rt700_mc_private *ctx = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_dai *dai = rtd->codec_dai; + struct cnl_hdmi_pcm *pcm; + + pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); + if (!pcm) + return -ENOMEM; + + /* dai_link id is 1:1 mapped to the PCM device */ + pcm->device = rtd->dai_link->id; + pcm->codec_dai = dai; + + list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); + + return 0; +} + +#define NAME_SIZE 32 +static int cnl_card_late_probe(struct snd_soc_card *card) +{ + struct cnl_rt700_mc_private *ctx = snd_soc_card_get_drvdata(card); + struct cnl_hdmi_pcm *pcm; + struct snd_soc_component *component = NULL; + int err, i = 0; + char jack_name[NAME_SIZE]; + + pr_err("bard: %s\n", __func__); + list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { + component = pcm->codec_dai->component; + snprintf(jack_name, sizeof(jack_name), + "HDMI/DP, pcm=%d Jack", pcm->device); + err = snd_soc_card_jack_new(card, jack_name, + SND_JACK_AVOUT, &cnl_hdmi[i], + NULL, 0); + + if (err) + return err; + + err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, + &cnl_hdmi[i]); + if (err < 0) + return err; + + i++; + } + + if (!component) + return -EINVAL; + + return hdac_hdmi_jack_port_init(component, &card->dapm); +} #else +static int cnl_card_late_probe(struct snd_soc_card *card) +{ + return 0; +} +#endif + static const struct snd_soc_dapm_widget cnl_rt700_widgets[] = { SND_SOC_DAPM_HP("Headphones", NULL), - SND_SOC_DAPM_HP("Headphones_2", NULL), SND_SOC_DAPM_MIC("AMIC", NULL), - SND_SOC_DAPM_MIC("AMIC_2", NULL), - SND_SOC_DAPM_MIC("SoC DMIC", NULL), + SND_SOC_DAPM_SPK("Speaker", NULL), }; -#endif -#ifndef CONFIG_SND_SOC_SDW_AGGM1M2 static const struct snd_soc_dapm_route cnl_rt700_map[] = { /*Headphones*/ { "Headphones", NULL, "HP" }, { "Speaker", NULL, "SPK" }, - { "I2NP", NULL, "AMIC" }, - - /* SWM map link the SWM outs to codec AIF */ - { "DP1 Playback", NULL, "SDW1 Tx0"}, - { "SDW1 Tx0", NULL, "codec0_out"}, - - { "codec0_in", NULL, "SDW1 Rx0" }, - { "SDW1 Rx0", NULL, "DP2 Capture" }, - -}; -#else -static const struct snd_soc_dapm_route cnl_rt700_map[] = { - /*Headphones*/ - { "Headphones", NULL, "HP" }, - { "Headphones_2", NULL, "HP_2" }, { "MIC2", NULL, "AMIC" }, - { "MIC2_2", NULL, "AMIC_2" }, - - /* SWM map link the SWM outs to codec AIF */ - { "DP1 Playback", NULL, "SDW Tx10"}, - { "SDW Tx10", NULL, "sdw_codec0_out"}, - { "DP1 Playback2", NULL, "SDW2 Tx"}, - { "SDW2 Tx", NULL, "sdw_codec0_out"}, - - { "sdw_codec0_in", NULL, "SDW Rx10" }, - { "SDW Rx10", NULL, "DP2 Capture" }, - {"sdw_codec0_in", NULL, "SDW2 Rx"}, - {"SDW2 Rx", NULL, "DP2 Capture2"}, - - {"DMic", NULL, "SoC DMIC"}, - {"DMIC01 Rx", NULL, "Capture"}, - {"dmic01_hifi", NULL, "DMIC01 Rx"}, - }; -#endif -#ifndef CONFIG_SND_SOC_SDW_AGGM1M2 static const struct snd_kcontrol_new cnl_rt700_controls[] = { SOC_DAPM_PIN_SWITCH("Headphones"), SOC_DAPM_PIN_SWITCH("AMIC"), SOC_DAPM_PIN_SWITCH("Speaker"), }; -#else -static const struct snd_kcontrol_new cnl_rt700_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphones"), - SOC_DAPM_PIN_SWITCH("Headphones_2"), - SOC_DAPM_PIN_SWITCH("AMIC"), - SOC_DAPM_PIN_SWITCH("AMIC_2"), -}; -#endif - - -static int cnl_rt700_init(struct snd_soc_pcm_runtime *runtime) -{ - int ret; - struct snd_soc_card *card = runtime->card; - - pr_info("Entry %s\n", __func__); - card->dapm.idle_bias_off = true; - - ret = snd_soc_add_card_controls(card, cnl_rt700_controls, - ARRAY_SIZE(cnl_rt700_controls)); - if (ret) { - pr_err("unable to add card controls\n"); - return ret; - } - return 0; -} static int cnl_rt700_codec_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) @@ -149,12 +145,8 @@ static int cnl_rt700_codec_fixup(struct snd_soc_pcm_runtime *rtd, pr_debug("Invoked %s for dailink %s\n", __func__, rtd->dai_link->name); slot_width = 24; rate->min = rate->max = 48000; -#ifdef CONFIG_SND_SOC_SDW_AGGM1M2 - channels->min = 1; - channels->max = 2; -#else channels->min = channels->max = 2; -#endif + snd_mask_none(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT)); snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), SNDRV_PCM_FORMAT_S24_LE); @@ -167,117 +159,127 @@ static int cnl_rt700_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } -static int cnl_dmic_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - channels->min = channels->max = 2; - - return 0; -} +SND_SOC_DAILINK_DEF(sdw1_pin, + DAILINK_COMP_ARRAY(COMP_CPU("SDW1 Pin0"))); +SND_SOC_DAILINK_DEF(sdw1_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("sdw:1:25d:700:0:0", "rt700-aif1"))); + +#if IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI) +SND_SOC_DAILINK_DEF(idisp1_pin, + DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); +SND_SOC_DAILINK_DEF(idisp1_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); + +SND_SOC_DAILINK_DEF(idisp2_pin, + DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); +SND_SOC_DAILINK_DEF(idisp2_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); + +SND_SOC_DAILINK_DEF(idisp3_pin, + DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); +SND_SOC_DAILINK_DEF(idisp3_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); +#endif -static const struct snd_soc_pcm_stream cnl_rt700_dai_params = { - .formats = SNDRV_PCM_FMTBIT_S24_LE, - .rate_min = 48000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 4, -}; +SND_SOC_DAILINK_DEF(platform, + DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); -#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CNL_FPGA) -static const char pname[] = "0000:02:18.0"; -static const char cname[] = "sdw-slave0-10:02:5d:07:01:00"; -#else -static const char pname[] = "0000:00:1f.3"; -static const char cname[] = "sdw:25d:700:0:0:1"; -#endif struct snd_soc_dai_link cnl_rt700_msic_dailink[] = { - { - .name = "CNL Audio Port", - .stream_name = "Audio", - .cpu_dai_name = "System Pin", - .platform_name = "0000:00:1f.3", - .nonatomic = 1, - .dynamic = 1, - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", - .dpcm_playback = 1, - .dpcm_capture = 1, - }, { .name = "SDW0-Codec", - .cpu_dai_name = "SDW1 Pin0", - .platform_name = "0000:00:1f.3", - .codec_name = "sdw:1:25d:700:0:0", - .codec_dai_name = "rt700-aif1", + .id = 0, .be_hw_params_fixup = cnl_rt700_codec_fixup, .ignore_suspend = 1, .no_pcm = 1, .dpcm_playback = 1, .dpcm_capture = 1, + .nonatomic = true, + SND_SOC_DAILINK_REG(sdw1_pin, sdw1_codec, platform), + }, +#if IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI) + { + .name = "iDisp1", + .id = 1, + .init = cnl_hdmi_init, + .no_pcm = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), + }, + { + .name = "iDisp2", + .id = 2, + .init = cnl_hdmi_init, + .no_pcm = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), + }, + { + .name = "iDisp3", + .id = 3, + .init = cnl_hdmi_init, + .no_pcm = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), }, +#endif }; -static int -cnl_add_dai_link(struct snd_soc_card *card, struct snd_soc_dai_link *link) -{ - link->platform_name = pname; - link->nonatomic = 1; - - return 0; -} - /* SoC card */ static struct snd_soc_card snd_soc_card_cnl_rt700 = { .name = "cnl_rt700-audio", .dai_link = cnl_rt700_msic_dailink, .num_links = ARRAY_SIZE(cnl_rt700_msic_dailink), + .controls = cnl_rt700_controls, + .num_controls = ARRAY_SIZE(cnl_rt700_controls), .dapm_widgets = cnl_rt700_widgets, .num_dapm_widgets = ARRAY_SIZE(cnl_rt700_widgets), .dapm_routes = cnl_rt700_map, .num_dapm_routes = ARRAY_SIZE(cnl_rt700_map), - .add_dai_link = cnl_add_dai_link, - .owner = THIS_MODULE, + .late_probe = cnl_card_late_probe, }; static int snd_cnl_rt700_mc_probe(struct platform_device *pdev) { - int ret_val = 0; - struct cnl_rt700_mc_private *drv; + struct cnl_rt700_mc_private *ctx; + struct snd_soc_acpi_mach *mach; + const char *platform_name; + struct snd_soc_card *card; + int ret; - pr_err("Entry %s\n", __func__); + dev_dbg(&pdev->dev, "Entry %s\n", __func__); - drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); - if (!drv) + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) return -ENOMEM; - pr_err("1 Entry %s\n", __func__); +#if IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI) + INIT_LIST_HEAD(&ctx->hdmi_pcm_list); +#endif + + card = &snd_soc_card_cnl_rt700; + card->dev = &pdev->dev; + snd_soc_card_cnl_rt700.dev = &pdev->dev; - snd_soc_card_set_drvdata(&snd_soc_card_cnl_rt700, drv); - /* Register the card */ - ret_val = snd_soc_register_card(&snd_soc_card_cnl_rt700); - if (ret_val && (ret_val != -EPROBE_DEFER)) { - pr_err("snd_soc_register_card failed %d\n", ret_val); - goto unalloc; - } - platform_set_drvdata(pdev, &snd_soc_card_cnl_rt700); - return ret_val; -unalloc: - return ret_val; -} + /* override plaform name, if required */ + mach = (&pdev->dev)->platform_data; + platform_name = mach->mach_params.platform; -static int snd_cnl_rt700_mc_remove(struct platform_device *pdev) -{ - struct snd_soc_card *soc_card = platform_get_drvdata(pdev); - struct cnl_rt700_mc_private *drv = snd_soc_card_get_drvdata(soc_card); + ret = snd_soc_fixup_dai_links_platform_name(card, platform_name); + if (ret) + return ret; - snd_soc_card_set_drvdata(soc_card, NULL); - snd_soc_unregister_card(soc_card); - platform_set_drvdata(pdev, NULL); - return 0; + snd_soc_card_set_drvdata(card, ctx); + + /* Register the card */ + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret) { + pr_err("snd_soc_register_card failed %d\n", ret); + return ret; + } + platform_set_drvdata(pdev, &snd_soc_card_cnl_rt700); + return ret; } static const struct platform_device_id cnl_board_ids[] = { @@ -292,25 +294,11 @@ static struct platform_driver snd_cnl_rt700_mc_driver = { .name = "cnl_rt700", }, .probe = snd_cnl_rt700_mc_probe, - .remove = snd_cnl_rt700_mc_remove, .id_table = cnl_board_ids }; module_platform_driver(snd_cnl_rt700_mc_driver) -#if 0 -static int snd_cnl_rt700_driver_init(void) -{ - pr_err("Shreyas %s",__func__); - return platform_driver_register(&snd_cnl_rt700_mc_driver); -} -late_initcall(snd_cnl_rt700_driver_init); -static void snd_cnl_rt700_driver_exit(void) -{ - platform_driver_unregister(&snd_cnl_rt700_mc_driver); -} -module_exit(snd_cnl_rt700_driver_exit) -#endif MODULE_DESCRIPTION("ASoC CNL Machine driver"); MODULE_AUTHOR("Hardik Shah "); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/common/soc-acpi-intel-icl-match.c b/sound/soc/intel/common/soc-acpi-intel-icl-match.c index 0b430b9b367368..6716099173c4fd 100644 --- a/sound/soc/intel/common/soc-acpi-intel-icl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-icl-match.c @@ -29,6 +29,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[] = { .sof_fw_filename = "sof-icl.ri", .sof_tplg_filename = "sof-icl-rt5682.tplg", }, + { + .id = "10EC0700", + .drv_name = "cnl_rt700", + .sof_fw_filename = "sof-icl.ri", + .sof_tplg_filename = "sof-icl-rt700.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines); diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig index dd14ce92fe102f..9165611066db26 100644 --- a/sound/soc/sof/intel/Kconfig +++ b/sound/soc/sof/intel/Kconfig @@ -148,6 +148,7 @@ config SND_SOC_SOF_CANNONLAKE_SUPPORT config SND_SOC_SOF_CANNONLAKE tristate select SND_SOC_SOF_HDA_COMMON + select SND_SOC_SOF_SOUNDWIRE help This option is not user-selectable but automagically handled by 'select' statements at a higher level @@ -258,6 +259,21 @@ config SND_SOC_SOF_HDA This option is not user-selectable but automagically handled by 'select' statements at a higher level +config SND_SOC_SOF_SOUNDWIRE_LINK + bool "SOF support for SoundWire" + help + This adds support for SoundWire with Sound Open Firmware + for Intel(R) platforms. + Say Y if you want to enable SoundWire links with SOF. + If unsure select "N". + +config SND_SOC_SOF_SOUNDWIRE + tristate + select SOUNDWIRE if SND_SOC_SOF_SOUNDWIRE_LINK + help + This option is not user-selectable but automagically handled by + 'select' statements at a higher level + endif ## SND_SOC_SOF_INTEL_PCI endif ## SND_SOC_SOF_INTEL_TOPLEVEL