diff options
Diffstat (limited to '')
64 files changed, 2209 insertions, 1782 deletions
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 0ae6eecc88..9e427f00de 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -38,6 +38,15 @@ config SND_SOC_INTEL_SOF_REALTEK_COMMON config SND_SOC_INTEL_SOF_CIRRUS_COMMON tristate +config SND_SOC_INTEL_SOF_NUVOTON_COMMON + tristate + +config SND_SOC_INTEL_SOF_SSP_COMMON + tristate + +config SND_SOC_INTEL_SOF_BOARD_HELPERS + tristate + if SND_SOC_INTEL_CATPT config SND_SOC_INTEL_HASWELL_MACH @@ -489,10 +498,11 @@ config SND_SOC_INTEL_SOF_RT5682_MACH select SND_SOC_RT5682_I2C select SND_SOC_RT5682S select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI select SND_SOC_INTEL_HDA_DSP_COMMON + select SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_INTEL_SOF_MAXIM_COMMON select SND_SOC_INTEL_SOF_REALTEK_COMMON + select SND_SOC_INTEL_SOF_SSP_COMMON help This adds support for ASoC machine driver for SOF platforms with rt5650 or rt5682 codec. @@ -507,9 +517,10 @@ config SND_SOC_INTEL_SOF_CS42L42_MACH select SND_SOC_CS42L42 select SND_SOC_MAX98357A select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI select SND_SOC_INTEL_HDA_DSP_COMMON + select SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_INTEL_SOF_MAXIM_COMMON + select SND_SOC_INTEL_SOF_SSP_COMMON help This adds support for ASoC machine driver for SOF platforms with cs42l42 codec. @@ -557,10 +568,12 @@ config SND_SOC_INTEL_SOF_NAU8825_MACH select SND_SOC_MAX98357A select SND_SOC_NAU8315 select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI select SND_SOC_INTEL_HDA_DSP_COMMON + select SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_INTEL_SOF_MAXIM_COMMON + select SND_SOC_INTEL_SOF_NUVOTON_COMMON select SND_SOC_INTEL_SOF_REALTEK_COMMON + select SND_SOC_INTEL_SOF_SSP_COMMON help This adds support for ASoC machine driver for SOF platforms with nau8825 codec. @@ -600,25 +613,24 @@ config SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH endif ## SND_SOC_SOF_COMETLAKE && SND_SOC_SOF_HDA_LINK -if SND_SOC_SOF_JASPERLAKE - -config SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH - tristate "SOF with DA7219 and MAX98373/MAX98360A in I2S Mode" +config SND_SOC_INTEL_SOF_DA7219_MACH + tristate "SOF with DA7219 codec in I2S Mode" depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC select SND_SOC_INTEL_HDA_DSP_COMMON select SND_SOC_DA7219 + select SND_SOC_MAX98357A select SND_SOC_MAX98373_I2C select SND_SOC_DMIC + select SND_SOC_INTEL_SOF_MAXIM_COMMON + select SND_SOC_INTEL_SOF_SSP_COMMON help This adds support for ASoC machine driver for SOF platforms - with DA7219 + MAX98373/MAX98360A I2S audio codec. + with Dialog DA7219 I2S audio codec. Say Y if you have such a device. If unsure select "N". -endif ## SND_SOC_SOF_JASPERLAKE - if SND_SOC_SOF_HDA_LINK config SND_SOC_INTEL_SOF_SSP_AMP_MACH @@ -628,10 +640,11 @@ config SND_SOC_INTEL_SOF_SSP_AMP_MACH select SND_SOC_RT1308 select SND_SOC_CS35L41_I2C select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI select SND_SOC_INTEL_HDA_DSP_COMMON + select SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_INTEL_SOF_REALTEK_COMMON select SND_SOC_INTEL_SOF_CIRRUS_COMMON + select SND_SOC_INTEL_SOF_SSP_COMMON help This adds support for ASoC machine driver for SOF platforms with RT1308/CS35L41 I2S audio codec. @@ -679,6 +692,10 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH select SND_SOC_RT1318_SDW select SND_SOC_RT5682_SDW select SND_SOC_CS42L42_SDW + select SND_SOC_CS42L43 + select SND_SOC_CS42L43_SDW + select MFD_CS42L43 + select MFD_CS42L43_SDW select SND_SOC_CS35L56_SDW select SND_SOC_DMIC select SND_SOC_INTEL_HDA_DSP_COMMON diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index a570b5b40f..943bf8b80e 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -23,6 +23,7 @@ snd-soc-sof_rt5682-objs := sof_rt5682.o snd-soc-sof_cs42l42-objs := sof_cs42l42.o snd-soc-sof_es8336-objs := sof_es8336.o snd-soc-sof_nau8825-objs := sof_nau8825.o +snd-soc-sof_da7219-objs := sof_da7219.o snd-soc-cml_rt1011_rt5682-objs := cml_rt1011_rt5682.o snd-soc-kbl_da7219_max98357a-objs := kbl_da7219_max98357a.o snd-soc-kbl_da7219_max98927-objs := kbl_da7219_max98927.o @@ -33,7 +34,6 @@ snd-soc-skl_rt286-objs := skl_rt286.o snd-soc-skl_hda_dsp-objs := skl_hda_dsp_generic.o skl_hda_dsp_common.o snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o -snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o snd-soc-ehl-rt5660-objs := ehl_rt5660.o snd-soc-sof-ssp-amp-objs := sof_ssp_amp.o snd-soc-sof-sdw-objs += sof_sdw.o \ @@ -42,12 +42,14 @@ snd-soc-sof-sdw-objs += sof_sdw.o \ sof_sdw_rt711.o sof_sdw_rt_sdca_jack_common.o \ sof_sdw_rt712_sdca.o sof_sdw_rt715.o \ sof_sdw_rt715_sdca.o sof_sdw_dmic.o \ - sof_sdw_cs42l42.o sof_sdw_cs_amp.o \ + sof_sdw_cs42l42.o sof_sdw_cs42l43.o \ + sof_sdw_cs_amp.o \ sof_sdw_hdmi.o obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o obj-$(CONFIG_SND_SOC_INTEL_SOF_CS42L42_MACH) += snd-soc-sof_cs42l42.o obj-$(CONFIG_SND_SOC_INTEL_SOF_ES8336_MACH) += snd-soc-sof_es8336.o obj-$(CONFIG_SND_SOC_INTEL_SOF_NAU8825_MACH) += snd-soc-sof_nau8825.o +obj-$(CONFIG_SND_SOC_INTEL_SOF_DA7219_MACH) += snd-soc-sof_da7219.o obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-hsw-rt5640.o obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON) += snd-soc-sst-bxt-da7219_max98357a.o obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o @@ -78,7 +80,6 @@ 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_SOF_DA7219_MAX98373_MACH) += snd-soc-sof_da7219_max98373.o obj-$(CONFIG_SND_SOC_INTEL_EHL_RT5660_MACH) += snd-soc-ehl-rt5660.o obj-$(CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH) += snd-soc-sof-sdw.o obj-$(CONFIG_SND_SOC_INTEL_SOF_SSP_AMP_MACH) += snd-soc-sof-ssp-amp.o @@ -95,3 +96,12 @@ obj-$(CONFIG_SND_SOC_INTEL_SOF_REALTEK_COMMON) += snd-soc-intel-sof-realtek-comm snd-soc-intel-sof-cirrus-common-objs += sof_cirrus_common.o obj-$(CONFIG_SND_SOC_INTEL_SOF_CIRRUS_COMMON) += snd-soc-intel-sof-cirrus-common.o + +snd-soc-intel-sof-nuvoton-common-objs += sof_nuvoton_common.o +obj-$(CONFIG_SND_SOC_INTEL_SOF_NUVOTON_COMMON) += snd-soc-intel-sof-nuvoton-common.o + +snd-soc-intel-sof-ssp-common-objs += sof_ssp_common.o +obj-$(CONFIG_SND_SOC_INTEL_SOF_SSP_COMMON) += snd-soc-intel-sof-ssp-common.o + +snd-soc-intel-sof-board-helpers-objs += sof_board_helpers.o +obj-$(CONFIG_SND_SOC_INTEL_SOF_BOARD_HELPERS) += snd-soc-intel-sof-board-helpers.o diff --git a/sound/soc/intel/boards/bdw-rt5650.c b/sound/soc/intel/boards/bdw-rt5650.c index d0682bc543..3ae26f2145 100644 --- a/sound/soc/intel/boards/bdw-rt5650.c +++ b/sound/soc/intel/boards/bdw-rt5650.c @@ -103,8 +103,8 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, static int bdw_rt5650_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* Workaround: set codec PLL to 19.2MHz that PLL source is @@ -167,7 +167,7 @@ static int bdw_rt5650_init(struct snd_soc_pcm_runtime *rtd) { struct bdw_rt5650_priv *bdw_rt5650 = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; int ret; diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c index f3e08d258a..304af3d06d 100644 --- a/sound/soc/intel/boards/bdw-rt5677.c +++ b/sound/soc/intel/boards/bdw-rt5677.c @@ -153,8 +153,8 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_MCLK, 24576000, @@ -170,8 +170,8 @@ static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream, static int bdw_rt5677_dsp_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_PLL1, 24576000, @@ -227,7 +227,7 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd) { struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); int ret; diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index 036579331d..7f20159c23 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -61,7 +61,7 @@ static const struct snd_soc_dapm_route card_routes[] = { static int codec_link_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; int ret; ret = snd_soc_card_jack_new_pins(rtd->card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, @@ -75,7 +75,7 @@ static int codec_link_init(struct snd_soc_pcm_runtime *rtd) static void codec_link_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(codec, NULL, NULL); } @@ -98,8 +98,8 @@ static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, static int codec_link_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, SND_SOC_CLOCK_IN); diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index cbfff466c5..816fad8c1f 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c @@ -226,8 +226,8 @@ static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) { int ret; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; int clk_freq; /* Configure sysclk for codec */ @@ -275,7 +275,7 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct bxt_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct bxt_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -293,7 +293,7 @@ static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd) static int broxton_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index bf89fe8042..4631106f2a 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c @@ -155,7 +155,7 @@ static const struct snd_soc_dapm_route geminilake_rt298_map[] = { static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); @@ -165,7 +165,7 @@ static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd) static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; int ret = 0; ret = snd_soc_card_jack_new_pins(rtd->card, "Headset", @@ -186,7 +186,7 @@ static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd) static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct bxt_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -224,8 +224,8 @@ static int broxton_ssp5_fixup(struct snd_soc_pcm_runtime *rtd, static int broxton_rt298_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, diff --git a/sound/soc/intel/boards/bytcht_cx2072x.c b/sound/soc/intel/boards/bytcht_cx2072x.c index 9942a2de6f..10a84a2c10 100644 --- a/sound/soc/intel/boards/bytcht_cx2072x.c +++ b/sound/soc/intel/boards/bytcht_cx2072x.c @@ -70,7 +70,7 @@ static const struct acpi_gpio_mapping byt_cht_cx2072x_acpi_gpios[] = { static int byt_cht_cx2072x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; - struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; int ret; if (devm_acpi_dev_add_driver_gpios(codec->dev, @@ -80,7 +80,7 @@ static int byt_cht_cx2072x_init(struct snd_soc_pcm_runtime *rtd) card->dapm.idle_bias_off = true; /* set the default PLL rate, the clock is handled by the codec driver */ - ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(rtd, 0), CX2072X_MCLK_EXTERNAL_PLL, + ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_codec(rtd, 0), CX2072X_MCLK_EXTERNAL_PLL, 19200000, SND_SOC_CLOCK_IN); if (ret) { dev_err(rtd->dev, "Could not set sysclk\n"); @@ -97,7 +97,7 @@ static int byt_cht_cx2072x_init(struct snd_soc_pcm_runtime *rtd) snd_soc_component_set_jack(codec, &byt_cht_cx2072x_headset, NULL); - snd_soc_dai_set_bclk_ratio(asoc_rtd_to_codec(rtd, 0), 50); + snd_soc_dai_set_bclk_ratio(snd_soc_rtd_to_codec(rtd, 0), 50); return 0; } @@ -123,7 +123,7 @@ static int byt_cht_cx2072x_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch 24-bit. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP); @@ -132,7 +132,7 @@ static int byt_cht_cx2072x_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcht_da7213.c b/sound/soc/intel/boards/bytcht_da7213.c index a3b0cfab17..7e5eea6900 100644 --- a/sound/soc/intel/boards/bytcht_da7213.c +++ b/sound/soc/intel/boards/bytcht_da7213.c @@ -78,7 +78,7 @@ static int codec_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch 24-bit. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP); @@ -87,7 +87,7 @@ static int codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; @@ -105,8 +105,8 @@ static int aif1_startup(struct snd_pcm_substream *substream) static int aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, DA7213_CLKSRC_MCLK, @@ -126,8 +126,8 @@ static int aif1_hw_params(struct snd_pcm_substream *substream, static int aif1_hw_free(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_pll(codec_dai, 0, diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 7a30d2d36f..8a0b0e864f 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -157,7 +157,7 @@ static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = { static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime) { - struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component; struct snd_soc_card *card = runtime->card; struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; @@ -212,7 +212,7 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime) if (ret) dev_err(card->dev, "unable to enable MCLK\n"); - ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(runtime, 0), 0, 19200000, + ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_codec(runtime, 0), 0, 19200000, SND_SOC_CLOCK_IN); if (ret < 0) { dev_err(card->dev, "can't set codec clock %d\n", ret); @@ -262,7 +262,7 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch 24-bit. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP @@ -272,7 +272,7 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcht_nocodec.c b/sound/soc/intel/boards/bytcht_nocodec.c index 7fc03f2efd..4a957d1cec 100644 --- a/sound/soc/intel/boards/bytcht_nocodec.c +++ b/sound/soc/intel/boards/bytcht_nocodec.c @@ -58,7 +58,7 @@ static int codec_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch 24-bit. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP); @@ -68,7 +68,7 @@ static int codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 6b631a608a..42466b4b1c 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -528,8 +528,8 @@ static int byt_rt5640_hp_elitepad_1000g2_jack2_check(void *data) static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params)); } @@ -1245,7 +1245,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_card *card = runtime->card; struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); struct rt5640_set_jack_data *jack_data = &priv->jack_data; - struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component; const struct snd_soc_dapm_route *custom_map = NULL; int num_routes = 0; int ret; @@ -1463,7 +1463,7 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP); @@ -1472,7 +1472,7 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 805afaf47b..f9fe8414f4 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -344,8 +344,8 @@ static struct snd_soc_jack_pin bytcr_jack_pins[] = { static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); snd_pcm_format_t format = params_format(params); int rate = params_rate(params); int bclk_ratio; @@ -563,7 +563,7 @@ static int byt_rt5651_add_codec_device_props(struct device *i2c_dev, static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; - struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component; struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; int num_routes; @@ -703,7 +703,7 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP @@ -714,7 +714,7 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 5c9e06ed1a..6978ebde66 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -10,11 +10,13 @@ */ #include <linux/acpi.h> +#include <linux/bitfield.h> #include <linux/clk.h> #include <linux/device.h> #include <linux/init.h> #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/platform_data/x86/soc.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/spi/spi.h> @@ -26,8 +28,6 @@ #include "../../codecs/wm5102.h" #include "../atom/sst-atom-controls.h" -#define MCLK_FREQ 25000000 - #define WM5102_MAX_SYSCLK_4K 49152000 /* max sysclk for 4K family */ #define WM5102_MAX_SYSCLK_11025 45158400 /* max sysclk for 11.025K family */ @@ -35,8 +35,67 @@ struct byt_wm5102_private { struct snd_soc_jack jack; struct clk *mclk; struct gpio_desc *spkvdd_en_gpio; + int mclk_freq; }; +#define BYT_WM5102_IN_MAP GENMASK(3, 0) +#define BYT_WM5102_OUT_MAP GENMASK(7, 4) +#define BYT_WM5102_SSP2 BIT(16) +#define BYT_WM5102_MCLK_19_2MHZ BIT(17) + +enum { + BYT_WM5102_INTMIC_IN3L_HSMIC_IN1L, + BYT_WM5102_INTMIC_IN1L_HSMIC_IN2L, +}; + +/* Note these values are pre-shifted for easy use of setting quirks */ +enum { + BYT_WM5102_SPK_SPK_MAP = FIELD_PREP_CONST(BYT_WM5102_OUT_MAP, 0), + BYT_WM5102_SPK_HPOUT2_MAP = FIELD_PREP_CONST(BYT_WM5102_OUT_MAP, 1), +}; + +static unsigned long quirk; + +static int quirk_override = -1; +module_param_named(quirk, quirk_override, int, 0444); +MODULE_PARM_DESC(quirk, "Board-specific quirk override"); + +static void log_quirks(struct device *dev) +{ + switch (quirk & BYT_WM5102_IN_MAP) { + case BYT_WM5102_INTMIC_IN3L_HSMIC_IN1L: + dev_info_once(dev, "quirk INTMIC_IN3L_HSMIC_IN1L enabled\n"); + break; + case BYT_WM5102_INTMIC_IN1L_HSMIC_IN2L: + dev_info_once(dev, "quirk INTMIC_IN1L_HSMIC_IN2L enabled\n"); + break; + default: + dev_warn_once(dev, "quirk sets invalid input map: 0x%lx, defaulting to INTMIC_IN3L_HSMIC_IN1L\n", + quirk & BYT_WM5102_IN_MAP); + quirk &= ~BYT_WM5102_IN_MAP; + quirk |= BYT_WM5102_INTMIC_IN3L_HSMIC_IN1L; + break; + } + switch (quirk & BYT_WM5102_OUT_MAP) { + case BYT_WM5102_SPK_SPK_MAP: + dev_info_once(dev, "quirk SPK_SPK_MAP enabled\n"); + break; + case BYT_WM5102_SPK_HPOUT2_MAP: + dev_info_once(dev, "quirk SPK_HPOUT2_MAP enabled\n"); + break; + default: + dev_warn_once(dev, "quirk sets invalid output map: 0x%lx, defaulting to SPK_SPK_MAP\n", + quirk & BYT_WM5102_OUT_MAP); + quirk &= ~BYT_WM5102_OUT_MAP; + quirk |= BYT_WM5102_SPK_SPK_MAP; + break; + } + if (quirk & BYT_WM5102_SSP2) + dev_info_once(dev, "quirk SSP2 enabled"); + if (quirk & BYT_WM5102_MCLK_19_2MHZ) + dev_info_once(dev, "quirk MCLK 19.2MHz enabled"); +} + static int byt_wm5102_spkvdd_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -52,6 +111,7 @@ static int byt_wm5102_spkvdd_power_event(struct snd_soc_dapm_widget *w, static int byt_wm5102_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai, int rate) { struct snd_soc_component *codec_component = codec_dai->component; + struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(codec_component->card); int sr_mult = ((rate % 4000) == 0) ? (WM5102_MAX_SYSCLK_4K / rate) : (WM5102_MAX_SYSCLK_11025 / rate); @@ -63,7 +123,7 @@ static int byt_wm5102_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai, int /* Configure the FLL1 PLL before selecting it */ ret = snd_soc_dai_set_pll(codec_dai, WM5102_FLL1, ARIZONA_CLK_SRC_MCLK1, - MCLK_FREQ, rate * sr_mult); + priv->mclk_freq, rate * sr_mult); if (ret) { dev_err(codec_component->dev, "Error setting PLL: %d\n", ret); return ret; @@ -145,35 +205,58 @@ static const struct snd_soc_dapm_route byt_wm5102_audio_map[] = { {"Headset Mic", NULL, "Platform Clock"}, {"Internal Mic", NULL, "Platform Clock"}, {"Speaker", NULL, "Platform Clock"}, - {"Line Out", NULL, "Platform Clock"}, - - {"Speaker", NULL, "SPKOUTLP"}, - {"Speaker", NULL, "SPKOUTLN"}, - {"Speaker", NULL, "SPKOUTRP"}, - {"Speaker", NULL, "SPKOUTRN"}, {"Speaker", NULL, "Speaker VDD"}, {"Headphone", NULL, "HPOUT1L"}, {"Headphone", NULL, "HPOUT1R"}, - {"Internal Mic", NULL, "MICBIAS3"}, - {"IN3L", NULL, "Internal Mic"}, - /* * The Headset Mix uses MICBIAS1 or 2 depending on if a CTIA/OMTP Headset * is connected, as the MICBIAS is applied after the CTIA/OMTP cross-switch. */ {"Headset Mic", NULL, "MICBIAS1"}, {"Headset Mic", NULL, "MICBIAS2"}, - {"IN1L", NULL, "Headset Mic"}, + {"Internal Mic", NULL, "MICBIAS3"}, +}; +static const struct snd_soc_dapm_route bytcr_wm5102_ssp0_map[] = { {"AIF1 Playback", NULL, "ssp0 Tx"}, {"ssp0 Tx", NULL, "modem_out"}, - {"modem_in", NULL, "ssp0 Rx"}, {"ssp0 Rx", NULL, "AIF1 Capture"}, }; +static const struct snd_soc_dapm_route bytcr_wm5102_ssp2_map[] = { + {"AIF1 Playback", NULL, "ssp2 Tx"}, + {"ssp2 Tx", NULL, "codec_out0"}, + {"ssp2 Tx", NULL, "codec_out1"}, + {"codec_in0", NULL, "ssp2 Rx"}, + {"codec_in1", NULL, "ssp2 Rx"}, + {"ssp2 Rx", NULL, "AIF1 Capture"}, +}; + +static const struct snd_soc_dapm_route byt_wm5102_spk_spk_map[] = { + {"Speaker", NULL, "SPKOUTLP"}, + {"Speaker", NULL, "SPKOUTLN"}, + {"Speaker", NULL, "SPKOUTRP"}, + {"Speaker", NULL, "SPKOUTRN"}, +}; + +static const struct snd_soc_dapm_route byt_wm5102_spk_hpout2_map[] = { + {"Speaker", NULL, "HPOUT2L"}, + {"Speaker", NULL, "HPOUT2R"}, +}; + +static const struct snd_soc_dapm_route byt_wm5102_intmic_in3l_hsmic_in1l_map[] = { + {"IN3L", NULL, "Internal Mic"}, + {"IN1L", NULL, "Headset Mic"}, +}; + +static const struct snd_soc_dapm_route byt_wm5102_intmic_in1l_hsmic_in2l_map[] = { + {"IN1L", NULL, "Internal Mic"}, + {"IN2L", NULL, "Headset Mic"}, +}; + static const struct snd_kcontrol_new byt_wm5102_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headset Mic"), @@ -201,8 +284,9 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; - int ret, jack_type; + struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component; + const struct snd_soc_dapm_route *custom_map = NULL; + int ret, jack_type, num_routes = 0; card->dapm.idle_bias_off = true; @@ -213,6 +297,50 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) return ret; } + switch (quirk & BYT_WM5102_IN_MAP) { + case BYT_WM5102_INTMIC_IN3L_HSMIC_IN1L: + custom_map = byt_wm5102_intmic_in3l_hsmic_in1l_map; + num_routes = ARRAY_SIZE(byt_wm5102_intmic_in3l_hsmic_in1l_map); + break; + case BYT_WM5102_INTMIC_IN1L_HSMIC_IN2L: + custom_map = byt_wm5102_intmic_in1l_hsmic_in2l_map; + num_routes = ARRAY_SIZE(byt_wm5102_intmic_in1l_hsmic_in2l_map); + break; + } + ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + if (ret) + return ret; + + switch (quirk & BYT_WM5102_OUT_MAP) { + case BYT_WM5102_SPK_SPK_MAP: + custom_map = byt_wm5102_spk_spk_map; + num_routes = ARRAY_SIZE(byt_wm5102_spk_spk_map); + break; + case BYT_WM5102_SPK_HPOUT2_MAP: + custom_map = byt_wm5102_spk_hpout2_map; + num_routes = ARRAY_SIZE(byt_wm5102_spk_hpout2_map); + break; + } + ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + if (ret) + return ret; + + if (quirk & BYT_WM5102_SSP2) { + custom_map = bytcr_wm5102_ssp2_map; + num_routes = ARRAY_SIZE(bytcr_wm5102_ssp2_map); + } else { + custom_map = bytcr_wm5102_ssp0_map; + num_routes = ARRAY_SIZE(bytcr_wm5102_ssp0_map); + } + ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + if (ret) + return ret; + + if (quirk & BYT_WM5102_MCLK_19_2MHZ) + priv->mclk_freq = 19200000; + else + priv->mclk_freq = 25000000; + /* * The firmware might enable the clock at boot (this information * may or may not be reflected in the enable clock register). @@ -225,7 +353,7 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) if (!ret) clk_disable_unprepare(priv->mclk); - ret = clk_set_rate(priv->mclk, MCLK_FREQ); + ret = clk_set_rate(priv->mclk, priv->mclk_freq); if (ret) { dev_err(card->dev, "Error setting MCLK rate: %d\n", ret); return ret; @@ -253,7 +381,7 @@ static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - int ret; + int ret, bits; /* The DSP will convert the FE rate to 48k, stereo */ rate->min = 48000; @@ -261,15 +389,22 @@ static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, channels->min = 2; channels->max = 2; - /* set SSP0 to 16-bit */ - params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); + if (quirk & BYT_WM5102_SSP2) { + /* set SSP2 to 24-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + bits = 24; + } else { + /* set SSP0 to 16-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); + bits = 16; + } /* * Default mode for SSP configuration is TDM 4 slot, override config * with explicit setting to I2S 2ch 16-bit. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP); @@ -278,7 +413,7 @@ static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); if (ret) { dev_err(rtd->dev, "Error setting I2S config: %d\n", ret); return ret; @@ -345,12 +480,9 @@ static struct snd_soc_dai_link byt_wm5102_dais[] = { /* back ends */ { /* - * This must be named SSP2-Codec even though this machine driver - * always uses SSP0. Most machine drivers support both and dynamically - * update the dailink to point to SSP0 or SSP2, while keeping the name - * as "SSP2-Codec". The SOF tplg files hardcode the "SSP2-Codec" even - * in the byt-foo-ssp0.tplg versions because the other machine-drivers - * use "SSP2-Codec" even when SSP0 is used. + * This dailink is updated dynamically to point to SSP0 or SSP2. + * Yet its name is always kept as "SSP2-Codec" because the SOF + * tplg files hardcode "SSP2-Codec" even in byt-foo-ssp0.tplg. */ .name = "SSP2-Codec", .id = 0, @@ -384,8 +516,13 @@ static struct snd_soc_card byt_wm5102_card = { .fully_routed = true, }; +static char byt_wm5102_components[64]; /* = "cfg-spk:* cfg-int-mic:* cfg-hs-mic:* ..." */ + static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) { + static const char * const out_map_name[] = { "spk", "hpout2" }; + static const char * const intmic_map_name[] = { "in3l", "in1l" }; + static const char * const hsmic_map_name[] = { "in1l", "in2l" }; char codec_name[SND_ACPI_I2C_ID_LEN]; struct device *dev = &pdev->dev; struct byt_wm5102_private *priv; @@ -393,8 +530,9 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) const char *platform_name; struct acpi_device *adev; struct device *codec_dev; + int dai_index = 0; bool sof_parent; - int ret; + int i, ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -413,14 +551,15 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) */ mach = dev->platform_data; adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1); - if (!adev) { - dev_err(dev, "Error cannot find acpi-dev for codec\n"); - return -ENOENT; + if (adev) { + snprintf(codec_name, sizeof(codec_name), "spi-%s", acpi_dev_name(adev)); + acpi_dev_put(adev); + } else { + /* Special case for when the codec is missing from the DSTD */ + strscpy(codec_name, "spi1.0", sizeof(codec_name)); } - snprintf(codec_name, sizeof(codec_name), "spi-%s", acpi_dev_name(adev)); codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, codec_name); - acpi_dev_put(adev); if (!codec_dev) return -EPROBE_DEFER; @@ -440,6 +579,39 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) return dev_err_probe(dev, ret, "getting spkvdd-GPIO\n"); } + if (soc_intel_is_cht()) { + /* + * CHT always uses SSP2 and 19.2 MHz; and + * the one currently supported CHT design uses HPOUT2 as + * speaker output and has the intmic on IN1L + hsmic on IN2L. + */ + quirk = BYT_WM5102_SSP2 | BYT_WM5102_MCLK_19_2MHZ | + BYT_WM5102_INTMIC_IN1L_HSMIC_IN2L | + BYT_WM5102_SPK_HPOUT2_MAP; + } + if (quirk_override != -1) { + dev_info_once(dev, "Overriding quirk 0x%lx => 0x%x\n", + quirk, quirk_override); + quirk = quirk_override; + } + log_quirks(dev); + + snprintf(byt_wm5102_components, sizeof(byt_wm5102_components), + "cfg-spk:%s cfg-intmic:%s cfg-hsmic:%s", + out_map_name[FIELD_GET(BYT_WM5102_OUT_MAP, quirk)], + intmic_map_name[FIELD_GET(BYT_WM5102_IN_MAP, quirk)], + hsmic_map_name[FIELD_GET(BYT_WM5102_IN_MAP, quirk)]); + byt_wm5102_card.components = byt_wm5102_components; + + /* find index of codec dai */ + for (i = 0; i < ARRAY_SIZE(byt_wm5102_dais); i++) { + if (!strcmp(byt_wm5102_dais[i].codecs->name, + "wm5102-codec")) { + dai_index = i; + break; + } + } + /* override platform name, if required */ byt_wm5102_card.dev = dev; platform_name = mach->mach_params.platform; @@ -447,6 +619,10 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) if (ret) goto out_put_gpio; + /* override SSP port, if required */ + if (quirk & BYT_WM5102_SSP2) + byt_wm5102_dais[dai_index].cpus->dai_name = "ssp2-port"; + /* set card and driver name and pm-ops */ sof_parent = snd_soc_acpi_sof_parent(dev); if (sof_parent) { diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index 850310de77..f43bc20d6a 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -112,8 +112,8 @@ static const struct snd_kcontrol_new cht_mc_controls[] = { static int cht_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, M98090_REG_SYSTEM_CLOCK, @@ -258,7 +258,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, int ret = 0; unsigned int fmt = 0; - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); if (ret < 0) { dev_err(rtd->dev, "can't set cpu_dai slot fmt: %d\n", ret); return ret; @@ -266,7 +266,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP; - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), fmt); + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), fmt); if (ret < 0) { dev_err(rtd->dev, "can't set cpu_dai set fmt: %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/cht_bsw_nau8824.c b/sound/soc/intel/boards/cht_bsw_nau8824.c index af2d9a7846..7651b83632 100644 --- a/sound/soc/intel/boards/cht_bsw_nau8824.c +++ b/sound/soc/intel/boards/cht_bsw_nau8824.c @@ -72,8 +72,8 @@ static const struct snd_kcontrol_new cht_mc_controls[] = { static int cht_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, NAU8824_CLK_FLL_FS, 0, @@ -96,7 +96,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) { struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); struct snd_soc_jack *jack = &ctx->jack; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); struct snd_soc_component *component = codec_dai->component; int ret, jack_type; @@ -145,7 +145,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0xf, 0x1, 4, 24); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_codec(rtd, 0), 0xf, 0x1, 4, 24); if (ret < 0) { dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index 875bc0b3d8..df23a581c1 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -207,8 +207,8 @@ static struct snd_soc_jack_pin cht_bsw_jack_pins[] = { static int cht_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ @@ -252,7 +252,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); - struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component; int jack_type; int ret; @@ -359,7 +359,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch 16-bit. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP @@ -369,7 +369,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_codec(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BC_FC @@ -379,7 +379,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; @@ -393,7 +393,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, /* * Default mode for SSP configuration is TDM 4 slot */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_codec(rtd, 0), SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_BC_FC); @@ -403,7 +403,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, } /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0xF, 0xF, 4, 24); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_codec(rtd, 0), 0xF, 0xF, 4, 24); if (ret < 0) { dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index daa630a0ef..f6da24f3c4 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -155,8 +155,8 @@ static const struct snd_kcontrol_new cht_mc_controls[] = { static int cht_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ @@ -188,7 +188,7 @@ static const struct acpi_gpio_mapping cht_rt5672_gpios[] = { static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) { int ret; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); struct snd_soc_component *component = codec_dai->component; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); @@ -297,7 +297,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, * board. Since we only support 2 channels anyways, there is no need * for TDM on any cht-bsw-rt5672 designs. So we use I2S 2ch everywhere. */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP); @@ -306,7 +306,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/cml_rt1011_rt5682.c b/sound/soc/intel/boards/cml_rt1011_rt5682.c index 20da83d9ee..679a09b63e 100644 --- a/sound/soc/intel/boards/cml_rt1011_rt5682.c +++ b/sound/soc/intel/boards/cml_rt1011_rt5682.c @@ -135,7 +135,7 @@ static struct snd_soc_jack_pin jack_pins[] = { static int cml_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) { struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_jack *jack; int ret; @@ -175,7 +175,7 @@ static int cml_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) static void cml_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(component, NULL, NULL); } @@ -212,8 +212,8 @@ static int cml_rt1011_spk_init(struct snd_soc_pcm_runtime *rtd) static int cml_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int clk_id, clk_freq, pll_out, ret; clk_id = RT5682_PLL1_S_MCLK; @@ -245,7 +245,7 @@ static int cml_rt5682_hw_params(struct snd_pcm_substream *substream, static int cml_rt1011_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; struct snd_soc_card *card = rtd->card; int srate, i, ret = 0; @@ -369,7 +369,7 @@ static int sof_card_late_probe(struct snd_soc_card *card) static int hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); diff --git a/sound/soc/intel/boards/ehl_rt5660.c b/sound/soc/intel/boards/ehl_rt5660.c index fee80638cb..686e603212 100644 --- a/sound/soc/intel/boards/ehl_rt5660.c +++ b/sound/soc/intel/boards/ehl_rt5660.c @@ -74,7 +74,7 @@ struct sof_hdmi_pcm { static int hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct sof_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -109,8 +109,8 @@ static int card_late_probe(struct snd_soc_card *card) static int rt5660_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, @@ -267,7 +267,7 @@ static void hdmi_link_init(struct snd_soc_card *card, * hdmi codec is not supported */ for (i = HDMI_LINK_START; i <= HDMI_LINE_END; i++) - card->dai_link[i].codecs[0] = asoc_dummy_dlc; + card->dai_link[i].codecs[0] = snd_soc_dummy_dlc; } static int snd_ehl_rt5660_probe(struct platform_device *pdev) diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c b/sound/soc/intel/boards/glk_rt5682_max98357a.c index cf0f89db3e..657e465823 100644 --- a/sound/soc/intel/boards/glk_rt5682_max98357a.c +++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c @@ -152,8 +152,8 @@ static int geminilake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) { struct glk_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_jack *jack; int pll_id, pll_source, clk_id, ret; @@ -215,8 +215,8 @@ static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) static int geminilake_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* Set valid bitmask & configuration for I2S in 24 bit */ @@ -236,7 +236,7 @@ static struct snd_soc_ops geminilake_rt5682_ops = { static int geminilake_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct glk_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct glk_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -253,7 +253,7 @@ static int geminilake_hdmi_init(struct snd_soc_pcm_runtime *rtd) static int geminilake_rt5682_fe_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; struct snd_soc_dapm_context *dapm; int ret; diff --git a/sound/soc/intel/boards/hsw_rt5640.c b/sound/soc/intel/boards/hsw_rt5640.c index 050c53ebd6..2a2fe27dff 100644 --- a/sound/soc/intel/boards/hsw_rt5640.c +++ b/sound/soc/intel/boards/hsw_rt5640.c @@ -47,8 +47,8 @@ static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, static int codec_link_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_MCLK, 12288000, SND_SOC_CLOCK_IN); diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c index 9714951307..a5d8965303 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c +++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c @@ -179,8 +179,8 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_jack *jack; int ret; @@ -225,7 +225,7 @@ static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct kbl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -258,7 +258,7 @@ static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c index a1f8234c77..98c11ec0ad 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98927.c +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c @@ -194,7 +194,7 @@ static const struct snd_soc_dapm_route kabylake_ssp1_map[] = { static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *runtime = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int ret, j; @@ -239,7 +239,7 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, static int kabylake_ssp0_trigger(struct snd_pcm_substream *substream, int cmd) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int j, ret; @@ -354,7 +354,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_jack *jack; struct snd_soc_card *card = rtd->card; int ret; @@ -406,7 +406,7 @@ static int kabylake_dmic_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct kbl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -439,7 +439,7 @@ static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); diff --git a/sound/soc/intel/boards/kbl_rt5660.c b/sound/soc/intel/boards/kbl_rt5660.c index 2c7a547f63..30e0aca161 100644 --- a/sound/soc/intel/boards/kbl_rt5660.c +++ b/sound/soc/intel/boards/kbl_rt5660.c @@ -157,7 +157,7 @@ static int kabylake_rt5660_codec_init(struct snd_soc_pcm_runtime *rtd) { int ret; struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); ret = devm_acpi_dev_add_driver_gpios(component->dev, acpi_rt5660_gpios); @@ -222,7 +222,7 @@ static void kabylake_rt5660_codec_exit(struct snd_soc_pcm_runtime *rtd) static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct kbl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -255,8 +255,8 @@ static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_rt5660_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c index 2d4224c5b1..9071b1f1cb 100644 --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c @@ -259,7 +259,7 @@ static int kabylake_rt5663_fe_init(struct snd_soc_pcm_runtime *rtd) { int ret; struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); ret = snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); @@ -275,7 +275,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) { int ret; struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_jack *jack; /* @@ -324,7 +324,7 @@ static int kabylake_rt5663_max98927_codec_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) { struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct kbl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -472,8 +472,8 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ @@ -510,7 +510,7 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int ret = 0, j; diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c index 2c79fca57b..178fe9c37d 100644 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c @@ -217,7 +217,7 @@ static struct snd_soc_codec_conf max98927_codec_conf[] = { static int kabylake_rt5663_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; int ret; dapm = snd_soc_component_get_dapm(component); @@ -232,7 +232,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) { int ret; struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_jack *jack; /* @@ -268,7 +268,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct kbl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -407,8 +407,8 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ @@ -431,7 +431,7 @@ static struct snd_soc_ops kabylake_rt5663_ops = { static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int ret = 0, j; diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c index 70c806cc5b..6e172719c9 100644 --- a/sound/soc/intel/boards/skl_hda_dsp_generic.c +++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c @@ -157,7 +157,7 @@ static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params) card->dapm_routes = &skl_hda_map[IDISP_ROUTE_COUNT]; num_route -= IDISP_ROUTE_COUNT; for (i = 0; i < IDISP_DAI_COUNT; i++) { - skl_hda_be_dai_links[i].codecs = &asoc_dummy_dlc; + skl_hda_be_dai_links[i].codecs = &snd_soc_dummy_dlc; skl_hda_be_dai_links[i].num_codecs = 1; } } @@ -181,7 +181,7 @@ static void skl_set_hda_codec_autosuspend_delay(struct snd_soc_card *card) for_each_card_rtds(card, rtd) { if (!strstr(rtd->dai_link->codecs->name, "ehdaudio0D0")) continue; - dai = asoc_rtd_to_codec(rtd, 0); + dai = snd_soc_rtd_to_codec(rtd, 0); hda_pvt = snd_soc_component_get_drvdata(dai->component); if (hda_pvt) { /* diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c index e13a5a4d8f..0e70258345 100644 --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c +++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c @@ -168,7 +168,7 @@ static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) { int ret; - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; /* * Headset buttons map to the google Reference headset. @@ -194,7 +194,7 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) { struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -212,7 +212,7 @@ static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) { struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -230,7 +230,7 @@ static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) { struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -248,7 +248,7 @@ static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); @@ -307,8 +307,8 @@ static const struct snd_soc_ops skylake_nau8825_fe_ops = { static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c index 575604dc89..fadc25a536 100644 --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c +++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c @@ -172,12 +172,12 @@ static int skylake_ssm4567_codec_init(struct snd_soc_pcm_runtime *rtd) int ret; /* Slot 1 for left */ - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0x01, 0x01, 2, 48); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_codec(rtd, 0), 0x01, 0x01, 2, 48); if (ret < 0) return ret; /* Slot 2 for right */ - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 1), 0x02, 0x02, 2, 48); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_codec(rtd, 1), 0x02, 0x02, 2, 48); if (ret < 0) return ret; @@ -187,7 +187,7 @@ static int skylake_ssm4567_codec_init(struct snd_soc_pcm_runtime *rtd) static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) { int ret; - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; /* * 4 buttons here map to the google Reference headset @@ -213,7 +213,7 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) { struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -231,7 +231,7 @@ static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) { struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -250,7 +250,7 @@ static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) { struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -268,7 +268,7 @@ static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); @@ -359,8 +359,8 @@ static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c index 4f3d655e2b..c59c60e280 100644 --- a/sound/soc/intel/boards/skl_rt286.c +++ b/sound/soc/intel/boards/skl_rt286.c @@ -112,7 +112,7 @@ static const struct snd_soc_dapm_route skylake_rt286_map[] = { static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); @@ -122,7 +122,7 @@ static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd) static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; int ret; ret = snd_soc_card_jack_new_pins(rtd->card, "Headset", @@ -143,7 +143,7 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -228,8 +228,8 @@ static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, static int skylake_rt286_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, diff --git a/sound/soc/intel/boards/sof_board_helpers.c b/sound/soc/intel/boards/sof_board_helpers.c new file mode 100644 index 0000000000..ce2967850c --- /dev/null +++ b/sound/soc/intel/boards/sof_board_helpers.c @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. + +#include <sound/soc.h> +#include "hda_dsp_common.h" +#include "sof_board_helpers.h" + +/* + * Intel HDMI DAI Link + */ +static int hdmi_init(struct snd_soc_pcm_runtime *rtd) +{ + struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); + + ctx->hdmi.hdmi_comp = dai->component; + + return 0; +} + +int sof_intel_board_card_late_probe(struct snd_soc_card *card) +{ + struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); + + if (!ctx->hdmi_num) + return 0; + + if (!ctx->hdmi.idisp_codec) + return 0; + + if (!ctx->hdmi.hdmi_comp) + return -EINVAL; + + return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp); +} +EXPORT_SYMBOL_NS(sof_intel_board_card_late_probe, SND_SOC_INTEL_SOF_BOARD_HELPERS); + +/* + * DMIC DAI Link + */ +static const struct snd_soc_dapm_widget dmic_widgets[] = { + SND_SOC_DAPM_MIC("SoC DMIC", NULL), +}; + +static const struct snd_soc_dapm_route dmic_routes[] = { + {"DMic", NULL, "SoC DMIC"}, +}; + +static int dmic_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, + ARRAY_SIZE(dmic_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add dmic widgets, ret %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, dmic_routes, + ARRAY_SIZE(dmic_routes)); + if (ret) { + dev_err(rtd->dev, "fail to add dmic routes, ret %d\n", ret); + return ret; + } + + return 0; +} + +/* + * DAI Link Helpers + */ +static struct snd_soc_dai_link_component dmic_component[] = { + { + .name = "dmic-codec", + .dai_name = "dmic-hifi", + } +}; + +static struct snd_soc_dai_link_component platform_component[] = { + { + /* name might be overridden during probe */ + .name = "0000:00:1f.3" + } +}; + +int sof_intel_board_set_dmic_link(struct device *dev, + struct snd_soc_dai_link *link, int be_id, + enum sof_dmic_be_type be_type) +{ + struct snd_soc_dai_link_component *cpus; + + /* cpus */ + cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component), + GFP_KERNEL); + if (!cpus) + return -ENOMEM; + + switch (be_type) { + case SOF_DMIC_01: + dev_dbg(dev, "link %d: dmic01\n", be_id); + + link->name = "dmic01"; + cpus->dai_name = "DMIC01 Pin"; + break; + case SOF_DMIC_16K: + dev_dbg(dev, "link %d: dmic16k\n", be_id); + + link->name = "dmic16k"; + cpus->dai_name = "DMIC16k Pin"; + break; + default: + dev_err(dev, "invalid be type %d\n", be_type); + return -EINVAL; + } + + link->cpus = cpus; + link->num_cpus = 1; + + /* codecs */ + link->codecs = dmic_component; + link->num_codecs = ARRAY_SIZE(dmic_component); + + /* platforms */ + link->platforms = platform_component; + link->num_platforms = ARRAY_SIZE(platform_component); + + link->id = be_id; + if (be_type == SOF_DMIC_01) + link->init = dmic_init; + link->ignore_suspend = 1; + link->no_pcm = 1; + link->dpcm_capture = 1; + + return 0; +} +EXPORT_SYMBOL_NS(sof_intel_board_set_dmic_link, SND_SOC_INTEL_SOF_BOARD_HELPERS); + +int sof_intel_board_set_intel_hdmi_link(struct device *dev, + struct snd_soc_dai_link *link, int be_id, + int hdmi_id, bool idisp_codec) +{ + struct snd_soc_dai_link_component *cpus, *codecs; + + dev_dbg(dev, "link %d: intel hdmi, hdmi id %d, idisp codec %d\n", + be_id, hdmi_id, idisp_codec); + + /* link name */ + link->name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", hdmi_id); + if (!link->name) + return -ENOMEM; + + /* cpus */ + cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component), + GFP_KERNEL); + if (!cpus) + return -ENOMEM; + + cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", hdmi_id); + if (!cpus->dai_name) + return -ENOMEM; + + link->cpus = cpus; + link->num_cpus = 1; + + /* codecs */ + if (idisp_codec) { + codecs = devm_kzalloc(dev, + sizeof(struct snd_soc_dai_link_component), + GFP_KERNEL); + if (!codecs) + return -ENOMEM; + + codecs->name = "ehdaudio0D2"; + codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, + "intel-hdmi-hifi%d", hdmi_id); + if (!codecs->dai_name) + return -ENOMEM; + + link->codecs = codecs; + } else { + link->codecs = &snd_soc_dummy_dlc; + } + link->num_codecs = 1; + + /* platforms */ + link->platforms = platform_component; + link->num_platforms = ARRAY_SIZE(platform_component); + + link->id = be_id; + link->init = (hdmi_id == 1) ? hdmi_init : NULL; + link->no_pcm = 1; + link->dpcm_playback = 1; + + return 0; +} +EXPORT_SYMBOL_NS(sof_intel_board_set_intel_hdmi_link, SND_SOC_INTEL_SOF_BOARD_HELPERS); + +MODULE_DESCRIPTION("ASoC Intel SOF Machine Driver Board Helpers"); +MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); diff --git a/sound/soc/intel/boards/sof_board_helpers.h b/sound/soc/intel/boards/sof_board_helpers.h new file mode 100644 index 0000000000..df99f576c1 --- /dev/null +++ b/sound/soc/intel/boards/sof_board_helpers.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2023 Intel Corporation. + */ + +#ifndef __SOF_INTEL_BOARD_HELPERS_H +#define __SOF_INTEL_BOARD_HELPERS_H + +#include <sound/soc.h> +#include "sof_hdmi_common.h" +#include "sof_ssp_common.h" + +/* + * sof_rt5682_private: private data for rt5682 machine driver + * + * @mclk: mclk clock data + * @is_legacy_cpu: true for BYT/CHT boards + */ +struct sof_rt5682_private { + struct clk *mclk; + bool is_legacy_cpu; +}; + +/* + * sof_card_private: common data for machine drivers + * + * @headset_jack: headset jack data + * @hdmi: init data for hdmi dai link + * @codec_type: type of headset codec + * @amp_type: type of speaker amplifier + * @dmic_be_num: number of Intel PCH DMIC BE link + * @hdmi_num: number of Intel HDMI BE link + * @rt5682: private data for rt5682 machine driver + */ +struct sof_card_private { + struct snd_soc_jack headset_jack; + struct sof_hdmi_private hdmi; + + enum sof_ssp_codec codec_type; + enum sof_ssp_codec amp_type; + + int dmic_be_num; + int hdmi_num; + + union { + struct sof_rt5682_private rt5682; + }; +}; + +enum sof_dmic_be_type { + SOF_DMIC_01, + SOF_DMIC_16K, +}; + +int sof_intel_board_card_late_probe(struct snd_soc_card *card); + +int sof_intel_board_set_dmic_link(struct device *dev, + struct snd_soc_dai_link *link, int be_id, + enum sof_dmic_be_type be_type); +int sof_intel_board_set_intel_hdmi_link(struct device *dev, + struct snd_soc_dai_link *link, int be_id, + int hdmi_id, bool idisp_codec); + +#endif /* __SOF_INTEL_BOARD_HELPERS_H */ diff --git a/sound/soc/intel/boards/sof_cirrus_common.c b/sound/soc/intel/boards/sof_cirrus_common.c index 8b8b07e4f2..e71e09124b 100644 --- a/sound/soc/intel/boards/sof_cirrus_common.c +++ b/sound/soc/intel/boards/sof_cirrus_common.c @@ -91,7 +91,7 @@ static const struct { static int cs35l41_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int clk_freq, i, ret; diff --git a/sound/soc/intel/boards/sof_cirrus_common.h b/sound/soc/intel/boards/sof_cirrus_common.h index ca438c12c3..d4ecf8d023 100644 --- a/sound/soc/intel/boards/sof_cirrus_common.h +++ b/sound/soc/intel/boards/sof_cirrus_common.h @@ -9,15 +9,16 @@ #define __SOF_CIRRUS_COMMON_H #include <sound/soc.h> +#include "sof_ssp_common.h" /* * Cirrus Logic CS35L41/CS35L53 */ #define CS35L41_CODEC_DAI "cs35l41-pcm" -#define CS35L41_DEV0_NAME "i2c-CSC3541:00" -#define CS35L41_DEV1_NAME "i2c-CSC3541:01" -#define CS35L41_DEV2_NAME "i2c-CSC3541:02" -#define CS35L41_DEV3_NAME "i2c-CSC3541:03" +#define CS35L41_DEV0_NAME "i2c-" CS35L41_ACPI_HID ":00" +#define CS35L41_DEV1_NAME "i2c-" CS35L41_ACPI_HID ":01" +#define CS35L41_DEV2_NAME "i2c-" CS35L41_ACPI_HID ":02" +#define CS35L41_DEV3_NAME "i2c-" CS35L41_ACPI_HID ":03" void cs35l41_set_dai_link(struct snd_soc_dai_link *link); void cs35l41_set_codec_conf(struct snd_soc_card *card); diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c index e6695e77d5..1f760fc4ca 100644 --- a/sound/soc/intel/boards/sof_cs42l42.c +++ b/sound/soc/intel/boards/sof_cs42l42.c @@ -19,16 +19,13 @@ #include <sound/sof.h> #include <sound/soc-acpi.h> #include <dt-bindings/sound/cs42l42.h> -#include "../../codecs/hdac_hdmi.h" #include "../common/soc-intel-quirks.h" -#include "hda_dsp_common.h" +#include "sof_board_helpers.h" #include "sof_maxim_common.h" - -#define NAME_SIZE 32 +#include "sof_ssp_common.h" #define SOF_CS42L42_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0)) #define SOF_CS42L42_SSP_CODEC_MASK (GENMASK(2, 0)) -#define SOF_SPEAKER_AMP_PRESENT BIT(3) #define SOF_CS42L42_SSP_AMP_SHIFT 4 #define SOF_CS42L42_SSP_AMP_MASK (GENMASK(6, 4)) #define SOF_CS42L42_SSP_AMP(quirk) \ @@ -46,8 +43,6 @@ #define SOF_CS42L42_SSP_BT_MASK (GENMASK(28, 26)) #define SOF_CS42L42_SSP_BT(quirk) \ (((quirk) << SOF_CS42L42_SSP_BT_SHIFT) & SOF_CS42L42_SSP_BT_MASK) -#define SOF_MAX98357A_SPEAKER_AMP_PRESENT BIT(29) -#define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(30) enum { LINK_NONE = 0, @@ -72,42 +67,10 @@ static struct snd_soc_jack_pin jack_pins[] = { /* Default: SSP2 */ static unsigned long sof_cs42l42_quirk = SOF_CS42L42_SSP_CODEC(2); -struct sof_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - struct snd_soc_jack hdmi_jack; - int device; -}; - -struct sof_card_private { - struct snd_soc_jack headset_jack; - struct list_head hdmi_pcm_list; - bool common_hdmi_codec_drv; -}; - -static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) -{ - struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); - struct sof_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; -} - static int sof_cs42l42_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_jack *jack = &ctx->headset_jack; int ret; @@ -143,7 +106,7 @@ static int sof_cs42l42_init(struct snd_soc_pcm_runtime *rtd) static void sof_cs42l42_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(component, NULL, NULL); } @@ -151,8 +114,8 @@ static void sof_cs42l42_exit(struct snd_soc_pcm_runtime *rtd) static int sof_cs42l42_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int clk_freq, ret; clk_freq = sof_dai_get_bclk(rtd); /* BCLK freq */ @@ -184,39 +147,7 @@ static struct snd_soc_dai_link_component platform_component[] = { static int sof_card_late_probe(struct snd_soc_card *card) { - struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component = NULL; - char jack_name[NAME_SIZE]; - struct sof_hdmi_pcm *pcm; - int err; - - if (list_empty(&ctx->hdmi_pcm_list)) - return -EINVAL; - - if (ctx->common_hdmi_codec_drv) { - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, - head); - component = pcm->codec_dai->component; - return hda_dsp_hdmi_build_controls(card, component); - } - - 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, &pcm->hdmi_jack); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &pcm->hdmi_jack); - if (err < 0) - return err; - } - - return hdac_hdmi_jack_port_init(component, &card->dapm); + return sof_intel_board_card_late_probe(card); } static const struct snd_kcontrol_new sof_controls[] = { @@ -229,10 +160,6 @@ static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_MIC("Headset Mic", NULL), }; -static const struct snd_soc_dapm_widget dmic_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - static const struct snd_soc_dapm_route sof_map[] = { /* HP jack connectors - unknown if we have jack detection */ {"Headphone Jack", NULL, "HP"}, @@ -241,33 +168,6 @@ static const struct snd_soc_dapm_route sof_map[] = { {"HS", NULL, "Headset Mic"}, }; -static const struct snd_soc_dapm_route dmic_map[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - -static int dmic_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, - ARRAY_SIZE(dmic_widgets)); - if (ret) { - dev_err(card->dev, "DMic widget addition failed: %d\n", ret); - /* Don't need to add routes if widget addition failed */ - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, - ARRAY_SIZE(dmic_map)); - - if (ret) - dev_err(card->dev, "DMic map addition failed: %d\n", ret); - - return ret; -} - /* sof audio machine driver for cs42l42 codec */ static struct snd_soc_card sof_audio_card_cs42l42 = { .name = "cs42l42", /* the sof- prefix is added by the core */ @@ -289,22 +189,16 @@ static struct snd_soc_dai_link_component cs42l42_component[] = { } }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - static int create_spk_amp_dai_links(struct device *dev, struct snd_soc_dai_link *links, struct snd_soc_dai_link_component *cpus, - int *id, int ssp_amp) + int *id, enum sof_ssp_codec amp_type, + int ssp_amp) { int ret = 0; /* speaker amp */ - if (!(sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT)) + if (amp_type == CODEC_NONE) return 0; links[*id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", @@ -316,14 +210,16 @@ static int create_spk_amp_dai_links(struct device *dev, links[*id].id = *id; - if (sof_cs42l42_quirk & SOF_MAX98357A_SPEAKER_AMP_PRESENT) { + switch (amp_type) { + case CODEC_MAX98357A: max_98357a_dai_link(&links[*id]); - } else if (sof_cs42l42_quirk & SOF_MAX98360A_SPEAKER_AMP_PRESENT) { + break; + case CODEC_MAX98360A: max_98360a_dai_link(&links[*id]); - } else { - dev_err(dev, "no amp defined\n"); - ret = -EINVAL; - goto devm_err; + break; + default: + dev_err(dev, "invalid amp type %d\n", amp_type); + return -EINVAL; } links[*id].platforms = platform_component; @@ -388,106 +284,6 @@ devm_err: return -ENOMEM; } -static int create_dmic_dai_links(struct device *dev, - struct snd_soc_dai_link *links, - struct snd_soc_dai_link_component *cpus, - int *id, int dmic_be_num) -{ - int i; - - /* dmic */ - if (dmic_be_num <= 0) - return 0; - - /* at least we have dmic01 */ - links[*id].name = "dmic01"; - links[*id].cpus = &cpus[*id]; - links[*id].cpus->dai_name = "DMIC01 Pin"; - links[*id].init = dmic_init; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[*id + 1].name = "dmic16k"; - links[*id + 1].cpus = &cpus[*id + 1]; - links[*id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } - - for (i = 0; i < dmic_be_num; i++) { - links[*id].id = *id; - links[*id].num_cpus = 1; - links[*id].codecs = dmic_component; - links[*id].num_codecs = ARRAY_SIZE(dmic_component); - links[*id].platforms = platform_component; - links[*id].num_platforms = ARRAY_SIZE(platform_component); - links[*id].ignore_suspend = 1; - links[*id].dpcm_capture = 1; - links[*id].no_pcm = 1; - - (*id)++; - } - - return 0; -} - -static int create_hdmi_dai_links(struct device *dev, - struct snd_soc_dai_link *links, - struct snd_soc_dai_link_component *cpus, - int *id, int hdmi_num) -{ - struct snd_soc_dai_link_component *idisp_components; - int i; - - /* HDMI */ - if (hdmi_num <= 0) - return 0; - - idisp_components = devm_kcalloc(dev, - hdmi_num, - sizeof(struct snd_soc_dai_link_component), GFP_KERNEL); - if (!idisp_components) - goto devm_err; - - for (i = 1; i <= hdmi_num; i++) { - links[*id].name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d", i); - if (!links[*id].name) - goto devm_err; - - links[*id].id = *id; - links[*id].cpus = &cpus[*id]; - links[*id].num_cpus = 1; - links[*id].cpus->dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "iDisp%d Pin", - i); - if (!links[*id].cpus->dai_name) - goto devm_err; - - idisp_components[i - 1].name = "ehdaudio0D2"; - idisp_components[i - 1].dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "intel-hdmi-hifi%d", - i); - if (!idisp_components[i - 1].dai_name) - goto devm_err; - - links[*id].codecs = &idisp_components[i - 1]; - links[*id].num_codecs = 1; - links[*id].platforms = platform_component; - links[*id].num_platforms = ARRAY_SIZE(platform_component); - links[*id].init = sof_hdmi_init; - links[*id].dpcm_playback = 1; - links[*id].no_pcm = 1; - - (*id)++; - } - - return 0; - -devm_err: - return -ENOMEM; -} - static int create_bt_offload_dai_links(struct device *dev, struct snd_soc_dai_link *links, struct snd_soc_dai_link_component *cpus, @@ -503,7 +299,7 @@ static int create_bt_offload_dai_links(struct device *dev, goto devm_err; links[*id].id = *id; - links[*id].codecs = &asoc_dummy_dlc; + links[*id].codecs = &snd_soc_dummy_dlc; links[*id].num_codecs = 1; links[*id].platforms = platform_component; links[*id].num_platforms = ARRAY_SIZE(platform_component); @@ -528,16 +324,17 @@ devm_err: return -ENOMEM; } -static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, - int ssp_codec, - int ssp_amp, - int ssp_bt, - int dmic_be_num, - int hdmi_num) +static struct snd_soc_dai_link * +sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type, + int ssp_codec, int ssp_amp, int ssp_bt, + int dmic_be_num, int hdmi_num, bool idisp_codec) { struct snd_soc_dai_link_component *cpus; struct snd_soc_dai_link *links; - int ret, id = 0, link_seq; + int ret; + int id = 0; + int link_seq; + int i; links = devm_kcalloc(dev, sof_audio_card_cs42l42.num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL); @@ -561,7 +358,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, } break; case LINK_SPK: - ret = create_spk_amp_dai_links(dev, links, cpus, &id, ssp_amp); + ret = create_spk_amp_dai_links(dev, links, cpus, &id, + amp_type, ssp_amp); if (ret < 0) { dev_err(dev, "fail to create spk amp dai links, ret %d\n", ret); @@ -569,19 +367,49 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, } break; case LINK_DMIC: - ret = create_dmic_dai_links(dev, links, cpus, &id, dmic_be_num); - if (ret < 0) { - dev_err(dev, "fail to create dmic dai links, ret %d\n", - ret); - goto devm_err; + if (dmic_be_num > 0) { + /* at least we have dmic01 */ + ret = sof_intel_board_set_dmic_link(dev, + &links[id], + id, + SOF_DMIC_01); + if (ret) { + dev_err(dev, "fail to create dmic01 link, ret %d\n", + ret); + goto devm_err; + } + + id++; + } + + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + ret = sof_intel_board_set_dmic_link(dev, + &links[id], + id, + SOF_DMIC_16K); + if (ret) { + dev_err(dev, "fail to create dmic16k link, ret %d\n", + ret); + goto devm_err; + } + + id++; } break; case LINK_HDMI: - ret = create_hdmi_dai_links(dev, links, cpus, &id, hdmi_num); - if (ret < 0) { - dev_err(dev, "fail to create hdmi dai links, ret %d\n", - ret); - goto devm_err; + for (i = 1; i <= hdmi_num; i++) { + ret = sof_intel_board_set_intel_hdmi_link(dev, + &links[id], + id, i, + idisp_codec); + if (ret) { + dev_err(dev, "fail to create hdmi link, ret %d\n", + ret); + goto devm_err; + } + + id++; } break; case LINK_BT: @@ -609,10 +437,9 @@ devm_err: static int sof_audio_probe(struct platform_device *pdev) { + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_dai_link *dai_links; - struct snd_soc_acpi_mach *mach; struct sof_card_private *ctx; - int dmic_be_num, hdmi_num; int ret, ssp_bt, ssp_amp, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -622,20 +449,24 @@ static int sof_audio_probe(struct platform_device *pdev) if (pdev->id_entry && pdev->id_entry->driver_data) sof_cs42l42_quirk = (unsigned long)pdev->id_entry->driver_data; - mach = pdev->dev.platform_data; + ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev); + ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); if (soc_intel_is_glk()) { - dmic_be_num = 1; - hdmi_num = 3; + ctx->dmic_be_num = 1; + ctx->hdmi_num = 3; } else { - dmic_be_num = 2; - hdmi_num = (sof_cs42l42_quirk & SOF_CS42L42_NUM_HDMIDEV_MASK) >> + ctx->dmic_be_num = 2; + ctx->hdmi_num = (sof_cs42l42_quirk & SOF_CS42L42_NUM_HDMIDEV_MASK) >> SOF_CS42L42_NUM_HDMIDEV_SHIFT; /* default number of HDMI DAI's */ - if (!hdmi_num) - hdmi_num = 3; + if (!ctx->hdmi_num) + ctx->hdmi_num = 3; } + if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) + ctx->hdmi.idisp_codec = true; + dev_dbg(&pdev->dev, "sof_cs42l42_quirk = %lx\n", sof_cs42l42_quirk); ssp_bt = (sof_cs42l42_quirk & SOF_CS42L42_SSP_BT_MASK) >> @@ -647,22 +478,22 @@ static int sof_audio_probe(struct platform_device *pdev) ssp_codec = sof_cs42l42_quirk & SOF_CS42L42_SSP_CODEC_MASK; /* compute number of dai links */ - sof_audio_card_cs42l42.num_links = 1 + dmic_be_num + hdmi_num; + sof_audio_card_cs42l42.num_links = 1 + ctx->dmic_be_num + ctx->hdmi_num; - if (sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT) + if (ctx->amp_type != CODEC_NONE) sof_audio_card_cs42l42.num_links++; if (sof_cs42l42_quirk & SOF_BT_OFFLOAD_PRESENT) sof_audio_card_cs42l42.num_links++; - dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, - ssp_bt, dmic_be_num, hdmi_num); + dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type, + ssp_codec, ssp_amp, ssp_bt, + ctx->dmic_be_num, ctx->hdmi_num, + ctx->hdmi.idisp_codec); if (!dai_links) return -ENOMEM; sof_audio_card_cs42l42.dai_link = dai_links; - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - sof_audio_card_cs42l42.dev = &pdev->dev; /* set platform name for each dailink */ @@ -671,8 +502,6 @@ static int sof_audio_probe(struct platform_device *pdev) if (ret) return ret; - ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; - snd_soc_card_set_drvdata(&sof_audio_card_cs42l42, ctx); return devm_snd_soc_register_card(&pdev->dev, @@ -683,24 +512,18 @@ static const struct platform_device_id board_ids[] = { { .name = "glk_cs4242_mx98357a", .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(2) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98357A_SPEAKER_AMP_PRESENT | SOF_CS42L42_SSP_AMP(1)) | SOF_CS42L42_DAILINK(LINK_SPK, LINK_HP, LINK_DMIC, LINK_HDMI, LINK_NONE), }, { .name = "jsl_cs4242_mx98360a", .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_CS42L42_SSP_AMP(1)) | SOF_CS42L42_DAILINK(LINK_HP, LINK_DMIC, LINK_HDMI, LINK_SPK, LINK_NONE), }, { .name = "adl_mx98360a_cs4242", .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_CS42L42_SSP_AMP(1) | SOF_CS42L42_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_PRESENT | @@ -725,5 +548,6 @@ module_platform_driver(sof_audio) MODULE_DESCRIPTION("SOF Audio Machine driver for CS42L42"); MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON); diff --git a/sound/soc/intel/boards/sof_da7219_max98373.c b/sound/soc/intel/boards/sof_da7219.c index bbd47e7e43..6eb5a6144e 100644 --- a/sound/soc/intel/boards/sof_da7219_max98373.c +++ b/sound/soc/intel/boards/sof_da7219.c @@ -2,7 +2,7 @@ // Copyright(c) 2019 Intel Corporation. /* - * Intel SOF Machine driver for DA7219 + MAX98373/MAX98360A codec + * Intel SOF Machine driver for Dialog headphone codec */ #include <linux/input.h> @@ -13,24 +13,25 @@ #include <linux/platform_device.h> #include <sound/soc.h> #include <sound/soc-acpi.h> +#include <sound/sof.h> #include "../../codecs/da7219.h" #include "hda_dsp_common.h" +#include "sof_hdmi_common.h" +#include "sof_maxim_common.h" +#include "sof_ssp_common.h" -#define DIALOG_CODEC_DAI "da7219-hifi" -#define MAX98373_CODEC_DAI "max98373-aif1" -#define MAXIM_DEV0_NAME "i2c-MX98373:00" -#define MAXIM_DEV1_NAME "i2c-MX98373:01" +/* Board Quirks */ +#define SOF_DA7219_JSL_BOARD BIT(2) -struct hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; +#define DIALOG_CODEC_DAI "da7219-hifi" struct card_private { - struct snd_soc_jack headset; - struct list_head hdmi_pcm_list; - struct snd_soc_jack hdmi[3]; + struct snd_soc_jack headset_jack; + struct sof_hdmi_private hdmi; + enum sof_ssp_codec codec_type; + enum sof_ssp_codec amp_type; + + unsigned int pll_bypass:1; }; static int platform_clock_control(struct snd_soc_dapm_widget *w, @@ -38,9 +39,14 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, { struct snd_soc_dapm_context *dapm = w->dapm; struct snd_soc_card *card = dapm->card; + struct card_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_dai *codec_dai; int ret = 0; + if (ctx->pll_bypass) + return ret; + + /* PLL SRM mode */ codec_dai = snd_soc_card_get_codec_dai(card, DIALOG_CODEC_DAI); if (!codec_dai) { dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n"); @@ -53,6 +59,8 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, if (ret) dev_err(card->dev, "failed to stop PLL: %d\n", ret); } else if (SND_SOC_DAPM_EVENT_ON(event)) { + dev_dbg(card->dev, "pll srm mode\n"); + ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304); if (ret) @@ -70,14 +78,6 @@ static const struct snd_kcontrol_new controls[] = { SOC_DAPM_PIN_SWITCH("Right Spk"), }; -static const struct snd_kcontrol_new m98360a_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Line Out"), - SOC_DAPM_PIN_SWITCH("Spk"), -}; - -/* For MAX98373 amp */ static const struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), @@ -103,40 +103,6 @@ static const struct snd_soc_dapm_route audio_map[] = { { "Headset Mic", NULL, "Platform Clock" }, { "Line Out", NULL, "Platform Clock" }, - { "Left Spk", NULL, "Left BE_OUT" }, - { "Right Spk", NULL, "Right BE_OUT" }, - - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - -/* For MAX98360A amp */ -static const struct snd_soc_dapm_widget max98360a_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_LINE("Line Out", NULL), - - SND_SOC_DAPM_SPK("Spk", NULL), - - SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, - platform_clock_control, SND_SOC_DAPM_POST_PMD | - SND_SOC_DAPM_PRE_PMU), - - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - -static const struct snd_soc_dapm_route max98360a_map[] = { - { "Headphone Jack", NULL, "HPL" }, - { "Headphone Jack", NULL, "HPR" }, - - { "MIC", NULL, "Headset Mic" }, - - { "Headphone Jack", NULL, "Platform Clock" }, - { "Headset Mic", NULL, "Platform Clock" }, - { "Line Out", NULL, "Platform Clock" }, - - {"Spk", NULL, "Speaker"}, - /* digital mics */ {"DMic", NULL, "SoC DMIC"}, }; @@ -156,24 +122,45 @@ static struct snd_soc_jack_pin jack_pins[] = { }, }; -static struct snd_soc_jack headset; - static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; - struct snd_soc_jack *jack; - int ret; + struct snd_soc_jack *jack = &ctx->headset_jack; + int mclk_rate, ret; + + mclk_rate = sof_dai_get_mclk(rtd); + if (mclk_rate <= 0) { + dev_err(rtd->dev, "invalid mclk freq %d\n", mclk_rate); + return -EINVAL; + } - /* Configure sysclk for codec */ - ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 24000000, + ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, mclk_rate, SND_SOC_CLOCK_IN); if (ret) { - dev_err(rtd->dev, "can't set codec sysclk configuration\n"); + dev_err(rtd->dev, "fail to set sysclk, ret %d\n", ret); return ret; } /* + * Use PLL bypass mode if MCLK is available, be sure to set the + * frequency of MCLK to 12.288 or 24.576MHz on topology side. + */ + if (mclk_rate == 12288000 || mclk_rate == 24576000) { + /* PLL bypass mode */ + dev_dbg(rtd->dev, "pll bypass mode, mclk rate %d\n", mclk_rate); + + ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0); + if (ret) { + dev_err(rtd->dev, "fail to set pll, ret %d\n", ret); + return ret; + } + + ctx->pll_bypass = 1; + } + + /* * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ @@ -181,34 +168,36 @@ static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, - &headset, - jack_pins, - ARRAY_SIZE(jack_pins)); + jack, jack_pins, ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); return ret; } - jack = &headset; snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - snd_soc_component_set_jack(component, jack, NULL); + + ret = snd_soc_component_set_jack(component, jack, NULL); + if (ret) { + dev_err(rtd->dev, "fail to set component jack, ret %d\n", ret); + return ret; + } return ret; } -static int ssp1_hw_params(struct snd_pcm_substream *substream, +static int max98373_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *runtime = snd_soc_substream_to_rtd(substream); int ret, j; for (j = 0; j < runtime->dai_link->num_codecs; j++) { - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, j); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, j); - if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) { + if (!strcmp(codec_dai->component->name, MAX_98373_DEV0_NAME)) { /* vmon_slot_no = 0 imon_slot_no = 1 for TX slots */ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 3, 4, 16); if (ret < 0) { @@ -216,7 +205,7 @@ static int ssp1_hw_params(struct snd_pcm_substream *substream, return ret; } } - if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { + if (!strcmp(codec_dai->component->name, MAX_98373_DEV1_NAME)) { /* vmon_slot_no = 2 imon_slot_no = 3 for TX slots */ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC, 3, 4, 16); if (ret < 0) { @@ -229,35 +218,16 @@ static int ssp1_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops ssp1_ops = { - .hw_params = ssp1_hw_params, -}; - -static struct snd_soc_codec_conf max98373_codec_conf[] = { - { - .dlc = COMP_CODEC_CONF(MAXIM_DEV0_NAME), - .name_prefix = "Right", - }, - { - .dlc = COMP_CODEC_CONF(MAXIM_DEV1_NAME), - .name_prefix = "Left", - }, +static const struct snd_soc_ops max98373_ops = { + .hw_params = max98373_hw_params, }; static int hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); - struct hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); - pcm->device = dai->id; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); + ctx->hdmi.hdmi_comp = dai->component; return 0; } @@ -265,17 +235,14 @@ static int hdmi_init(struct snd_soc_pcm_runtime *rtd) static int card_late_probe(struct snd_soc_card *card) { struct card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_acpi_mach *mach = (card->dev)->platform_data; - struct hdmi_pcm *pcm; - - if (mach->mach_params.common_hdmi_codec_drv) { - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm, - head); - return hda_dsp_hdmi_build_controls(card, - pcm->codec_dai->component); - } - return -EINVAL; + if (!ctx->hdmi.idisp_codec) + return 0; + + if (!ctx->hdmi.hdmi_comp) + return -EINVAL; + + return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp); } SND_SOC_DAILINK_DEF(ssp0_pin, @@ -285,13 +252,11 @@ SND_SOC_DAILINK_DEF(ssp0_codec, SND_SOC_DAILINK_DEF(ssp1_pin, DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); -SND_SOC_DAILINK_DEF(ssp1_amps, - DAILINK_COMP_ARRAY( - /* Left */ COMP_CODEC(MAXIM_DEV0_NAME, MAX98373_CODEC_DAI), - /* Right */ COMP_CODEC(MAXIM_DEV1_NAME, MAX98373_CODEC_DAI))); -SND_SOC_DAILINK_DEF(ssp1_m98360a, - DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi"))); +SND_SOC_DAILINK_DEF(ssp2_pin, + DAILINK_COMP_ARRAY(COMP_CPU("SSP2 Pin"))); +SND_SOC_DAILINK_DEF(dummy_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai"))); SND_SOC_DAILINK_DEF(dmic_pin, DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); @@ -316,10 +281,15 @@ SND_SOC_DAILINK_DEF(idisp3_pin, SND_SOC_DAILINK_DEF(idisp3_codec, DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); +SND_SOC_DAILINK_DEF(idisp4_pin, + DAILINK_COMP_ARRAY(COMP_CPU("iDisp4 Pin"))); +SND_SOC_DAILINK_DEF(idisp4_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi4"))); + SND_SOC_DAILINK_DEF(platform, /* subject to be overridden during probe */ DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); -static struct snd_soc_dai_link dais[] = { +static struct snd_soc_dai_link jsl_dais[] = { /* Back End DAI links */ { .name = "SSP1-Codec", @@ -328,8 +298,7 @@ static struct snd_soc_dai_link dais[] = { .no_pcm = 1, .dpcm_playback = 1, .dpcm_capture = 1, /* IV feedback */ - .ops = &ssp1_ops, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_amps, platform), + SND_SOC_DAILINK_REG(ssp1_pin, max_98373_components, platform), }, { .name = "SSP0-Codec", @@ -383,83 +352,198 @@ static struct snd_soc_dai_link dais[] = { } }; -static struct snd_soc_card card_da7219_m98373 = { - .name = "da7219max", +static struct snd_soc_dai_link adl_dais[] = { + /* Back End DAI links */ + { + .name = "SSP0-Codec", + .id = 0, + .no_pcm = 1, + .init = da7219_codec_init, + .ignore_pmdown_time = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform), + }, + { + .name = "dmic01", + .id = 1, + .ignore_suspend = 1, + .dpcm_capture = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), + }, + { + .name = "dmic16k", + .id = 2, + .ignore_suspend = 1, + .dpcm_capture = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(dmic16k_pin, dmic_codec, platform), + }, + { + .name = "iDisp1", + .id = 3, + .init = hdmi_init, + .dpcm_playback = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), + }, + { + .name = "iDisp2", + .id = 4, + .init = hdmi_init, + .dpcm_playback = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), + }, + { + .name = "iDisp3", + .id = 5, + .init = hdmi_init, + .dpcm_playback = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), + }, + { + .name = "iDisp4", + .id = 6, + .init = hdmi_init, + .dpcm_playback = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(idisp4_pin, idisp4_codec, platform), + }, + { + .name = "SSP1-Codec", + .id = 7, + .no_pcm = 1, + .dpcm_playback = 1, + /* feedback stream or firmware-generated echo reference */ + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(ssp1_pin, max_98373_components, platform), + }, + { + .name = "SSP2-BT", + .id = 8, + .no_pcm = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(ssp2_pin, dummy_codec, platform), + }, +}; + +static struct snd_soc_card card_da7219 = { + .name = "da7219", /* the sof- prefix is added by the core */ .owner = THIS_MODULE, - .dai_link = dais, - .num_links = ARRAY_SIZE(dais), .controls = controls, .num_controls = ARRAY_SIZE(controls), .dapm_widgets = widgets, .num_dapm_widgets = ARRAY_SIZE(widgets), .dapm_routes = audio_map, .num_dapm_routes = ARRAY_SIZE(audio_map), - .codec_conf = max98373_codec_conf, - .num_configs = ARRAY_SIZE(max98373_codec_conf), - .fully_routed = true, - .late_probe = card_late_probe, -}; - -static struct snd_soc_card card_da7219_m98360a = { - .name = "da7219max98360a", - .owner = THIS_MODULE, - .dai_link = dais, - .num_links = ARRAY_SIZE(dais), - .controls = m98360a_controls, - .num_controls = ARRAY_SIZE(m98360a_controls), - .dapm_widgets = max98360a_widgets, - .num_dapm_widgets = ARRAY_SIZE(max98360a_widgets), - .dapm_routes = max98360a_map, - .num_dapm_routes = ARRAY_SIZE(max98360a_map), .fully_routed = true, .late_probe = card_late_probe, }; static int audio_probe(struct platform_device *pdev) { - static struct snd_soc_card *card; - struct snd_soc_acpi_mach *mach; + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; + struct snd_soc_dai_link *dai_links; struct card_private *ctx; - int ret; + unsigned long board_quirk = 0; + int ret, amp_idx; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; - /* By default dais[0] is configured for max98373 */ - if (!strcmp(pdev->name, "sof_da7219_mx98360a")) { - dais[0] = (struct snd_soc_dai_link) { - .name = "SSP1-Codec", - .id = 0, - .no_pcm = 1, - .dpcm_playback = 1, - .ignore_pmdown_time = 1, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_m98360a, platform) }; + if (pdev->id_entry && pdev->id_entry->driver_data) + board_quirk = (unsigned long)pdev->id_entry->driver_data; + + ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev); + ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); + + if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) + ctx->hdmi.idisp_codec = true; + + if (board_quirk & SOF_DA7219_JSL_BOARD) { + /* backward-compatible with existing devices */ + switch (ctx->amp_type) { + case CODEC_MAX98360A: + card_da7219.name = devm_kstrdup(&pdev->dev, + "da7219max98360a", + GFP_KERNEL); + break; + case CODEC_MAX98373: + card_da7219.name = devm_kstrdup(&pdev->dev, "da7219max", + GFP_KERNEL); + break; + default: + break; + } + + dai_links = jsl_dais; + amp_idx = 0; + + card_da7219.num_links = ARRAY_SIZE(jsl_dais); + } else { + dai_links = adl_dais; + amp_idx = 7; + + card_da7219.num_links = ARRAY_SIZE(adl_dais); } - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - card = (struct snd_soc_card *)pdev->id_entry->driver_data; - card->dev = &pdev->dev; + dev_dbg(&pdev->dev, "board_quirk = %lx\n", board_quirk); + + /* speaker amp */ + switch (ctx->amp_type) { + case CODEC_MAX98360A: + max_98360a_dai_link(&dai_links[amp_idx]); + break; + case CODEC_MAX98373: + dai_links[amp_idx].codecs = max_98373_components; + dai_links[amp_idx].num_codecs = ARRAY_SIZE(max_98373_components); + dai_links[amp_idx].init = max_98373_spk_codec_init; + if (board_quirk & SOF_DA7219_JSL_BOARD) { + dai_links[amp_idx].ops = &max98373_ops; /* use local ops */ + } else { + /* TBD: implement the amp for later platform */ + dev_err(&pdev->dev, "max98373 not support yet\n"); + return -EINVAL; + } + + max_98373_set_codec_conf(&card_da7219); + break; + default: + dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type); + return -EINVAL; + } - mach = pdev->dev.platform_data; - ret = snd_soc_fixup_dai_links_platform_name(card, + card_da7219.dai_link = dai_links; + + card_da7219.dev = &pdev->dev; + + ret = snd_soc_fixup_dai_links_platform_name(&card_da7219, mach->mach_params.platform); if (ret) return ret; - snd_soc_card_set_drvdata(card, ctx); + snd_soc_card_set_drvdata(&card_da7219, ctx); - return devm_snd_soc_register_card(&pdev->dev, card); + return devm_snd_soc_register_card(&pdev->dev, &card_da7219); } static const struct platform_device_id board_ids[] = { { - .name = "sof_da7219_mx98373", - .driver_data = (kernel_ulong_t)&card_da7219_m98373, + .name = "jsl_mx98373_da7219", + .driver_data = (kernel_ulong_t)(SOF_DA7219_JSL_BOARD), + }, + { + .name = "jsl_mx98360_da7219", + .driver_data = (kernel_ulong_t)(SOF_DA7219_JSL_BOARD), }, { - .name = "sof_da7219_mx98360a", - .driver_data = (kernel_ulong_t)&card_da7219_m98360a, + .name = "adl_mx98360_da7219", + /* no quirk needed for this board */ }, { } }; @@ -468,7 +552,7 @@ MODULE_DEVICE_TABLE(platform, board_ids); static struct platform_driver audio = { .probe = audio_probe, .driver = { - .name = "sof_da7219_max98_360a_373", + .name = "sof_da7219", .pm = &snd_soc_pm_ops, }, .id_table = board_ids, @@ -476,7 +560,10 @@ static struct platform_driver audio = { module_platform_driver(audio) /* Module information */ -MODULE_DESCRIPTION("ASoC Intel(R) SOF Machine driver"); +MODULE_DESCRIPTION("ASoC Intel(R) SOF Machine driver for Dialog codec"); MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>"); +MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); MODULE_LICENSE("GPL v2"); MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON); diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c index 9904a9e33c..c1fcc156a5 100644 --- a/sound/soc/intel/boards/sof_es8336.c +++ b/sound/soc/intel/boards/sof_es8336.c @@ -126,7 +126,7 @@ static void pcm_pop_work_events(struct work_struct *work) static int sof_8336_trigger(struct snd_pcm_substream *substream, int cmd) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); @@ -251,7 +251,7 @@ static int dmic_init(struct snd_soc_pcm_runtime *runtime) static int sof_hdmi_init(struct snd_soc_pcm_runtime *runtime) { struct sof_es8336_private *priv = snd_soc_card_get_drvdata(runtime->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(runtime, 0); struct sof_hdmi_pcm *pcm; pcm = devm_kzalloc(runtime->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -269,7 +269,7 @@ static int sof_hdmi_init(struct snd_soc_pcm_runtime *runtime) static int sof_es8316_init(struct snd_soc_pcm_runtime *runtime) { - struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component; struct snd_soc_card *card = runtime->card; struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; @@ -308,7 +308,7 @@ static int sof_es8316_init(struct snd_soc_pcm_runtime *runtime) static void sof_es8316_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(component, NULL, NULL); } @@ -355,8 +355,8 @@ static const struct dmi_system_id sof_es8336_quirk_table[] = { static int sof_es8336_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); const int sysclk = 19200000; int ret; @@ -565,7 +565,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, if (!links[id].name) return NULL; links[id].id = id + hdmi_id_offset; - links[id].codecs = &asoc_dummy_dlc; + links[id].codecs = &snd_soc_dummy_dlc; links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); diff --git a/sound/soc/intel/boards/sof_hdmi_common.h b/sound/soc/intel/boards/sof_hdmi_common.h new file mode 100644 index 0000000000..1573e089c0 --- /dev/null +++ b/sound/soc/intel/boards/sof_hdmi_common.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2023 Intel Corporation. + */ + +#ifndef __SOF_HDMI_COMMON_H +#define __SOF_HDMI_COMMON_H + +#include <sound/soc.h> + +#define IDISP_CODEC_MASK 0x4 + +/* + * sof_hdmi_private: data for Intel HDMI dai link (idisp) initialization + * + * @hdmi_comp: ASoC component of idisp codec + * @idisp_codec: true to indicate idisp codec is present + */ +struct sof_hdmi_private { + struct snd_soc_component *hdmi_comp; + bool idisp_codec; +}; + +#endif /* __SOF_HDMI_COMMON_H */ diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c index 628b6d5d3e..3c00afc328 100644 --- a/sound/soc/intel/boards/sof_maxim_common.c +++ b/sound/soc/intel/boards/sof_maxim_common.c @@ -59,7 +59,7 @@ EXPORT_SYMBOL_NS(max_98373_components, SND_SOC_INTEL_SOF_MAXIM_COMMON); static int max_98373_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int j; @@ -78,7 +78,7 @@ static int max_98373_hw_params(struct snd_pcm_substream *substream, int max_98373_trigger(struct snd_pcm_substream *substream, int cmd) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai; int j; @@ -88,7 +88,7 @@ int max_98373_trigger(struct snd_pcm_substream *substream, int cmd) if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) return 0; - cpu_dai = asoc_rtd_to_cpu(rtd, 0); + cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); for_each_rtd_codec_dais(rtd, j, codec_dai) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cpu_dai->component); @@ -223,7 +223,7 @@ static const struct { static int max_98390_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int i, ret; diff --git a/sound/soc/intel/boards/sof_maxim_common.h b/sound/soc/intel/boards/sof_maxim_common.h index a095b47b85..fe0212fbad 100644 --- a/sound/soc/intel/boards/sof_maxim_common.h +++ b/sound/soc/intel/boards/sof_maxim_common.h @@ -11,10 +11,14 @@ #define __SOF_MAXIM_COMMON_H #include <sound/soc.h> +#include "sof_ssp_common.h" +/* + * Maxim MAX98373 + */ #define MAX_98373_CODEC_DAI "max98373-aif1" -#define MAX_98373_DEV0_NAME "i2c-MX98373:00" -#define MAX_98373_DEV1_NAME "i2c-MX98373:01" +#define MAX_98373_DEV0_NAME "i2c-" MAX_98373_ACPI_HID ":00" +#define MAX_98373_DEV1_NAME "i2c-" MAX_98373_ACPI_HID ":01" extern struct snd_soc_dai_link_component max_98373_components[2]; extern struct snd_soc_ops max_98373_ops; @@ -27,7 +31,6 @@ int max_98373_trigger(struct snd_pcm_substream *substream, int cmd); /* * Maxim MAX98390 */ -#define MAX_98390_ACPI_HID "MX98390" #define MAX_98390_CODEC_DAI "max98390-aif1" #define MAX_98390_DEV0_NAME "i2c-" MAX_98390_ACPI_HID ":00" #define MAX_98390_DEV1_NAME "i2c-" MAX_98390_ACPI_HID ":01" @@ -41,8 +44,8 @@ void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card); * Maxim MAX98357A/MAX98360A */ #define MAX_98357A_CODEC_DAI "HiFi" -#define MAX_98357A_DEV0_NAME "MX98357A:00" -#define MAX_98360A_DEV0_NAME "MX98360A:00" +#define MAX_98357A_DEV0_NAME MAX_98357A_ACPI_HID ":00" +#define MAX_98360A_DEV0_NAME MAX_98360A_ACPI_HID ":00" void max_98357a_dai_link(struct snd_soc_dai_link *link); void max_98360a_dai_link(struct snd_soc_dai_link *link); diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index 46b7ecf6f9..dc2821a012 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -20,15 +20,14 @@ #include <sound/soc-acpi.h> #include "../../codecs/nau8825.h" #include "../common/soc-intel-quirks.h" -#include "hda_dsp_common.h" +#include "sof_board_helpers.h" #include "sof_realtek_common.h" #include "sof_maxim_common.h" - -#define NAME_SIZE 32 +#include "sof_nuvoton_common.h" +#include "sof_ssp_common.h" #define SOF_NAU8825_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0)) #define SOF_NAU8825_SSP_CODEC_MASK (GENMASK(2, 0)) -#define SOF_SPEAKER_AMP_PRESENT BIT(3) #define SOF_NAU8825_SSP_AMP_SHIFT 4 #define SOF_NAU8825_SSP_AMP_MASK (GENMASK(6, 4)) #define SOF_NAU8825_SSP_AMP(quirk) \ @@ -44,45 +43,9 @@ #define SOF_BT_OFFLOAD_SSP(quirk) \ (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK) #define SOF_SSP_BT_OFFLOAD_PRESENT BIT(13) -#define SOF_RT1019P_SPEAKER_AMP_PRESENT BIT(14) -#define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(15) -#define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(16) -#define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(17) -#define SOF_NAU8318_SPEAKER_AMP_PRESENT BIT(18) static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0); -struct sof_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct sof_card_private { - struct clk *mclk; - struct snd_soc_jack sof_headset; - struct list_head hdmi_pcm_list; -}; - -static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) -{ - struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); - struct sof_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; -} - static struct snd_soc_jack_pin jack_pins[] = { { .pin = "Headphone Jack", @@ -97,9 +60,8 @@ static struct snd_soc_jack_pin jack_pins[] = { static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; - - struct snd_soc_jack *jack; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_jack *jack = &ctx->headset_jack; int ret; /* @@ -110,7 +72,7 @@ static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, - &ctx->sof_headset, + jack, jack_pins, ARRAY_SIZE(jack_pins)); if (ret) { @@ -118,14 +80,12 @@ static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } - jack = &ctx->sof_headset; - snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); - ret = snd_soc_component_set_jack(component, jack, NULL); + ret = snd_soc_component_set_jack(component, jack, NULL); if (ret) { dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); return ret; @@ -136,7 +96,7 @@ static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) static void sof_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(component, NULL, NULL); } @@ -144,8 +104,8 @@ static void sof_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd) static int sof_nau8825_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int clk_freq, ret; clk_freq = sof_dai_get_bclk(rtd); /* BCLK freq */ @@ -189,10 +149,9 @@ static int sof_card_late_probe(struct snd_soc_card *card) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_dapm_context *dapm = &card->dapm; - struct sof_hdmi_pcm *pcm; int err; - if (sof_nau8825_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) { + if (ctx->amp_type == CODEC_MAX98373) { /* Disable Left and Right Spk pin after boot */ snd_soc_dapm_disable_pin(dapm, "Left Spk"); snd_soc_dapm_disable_pin(dapm, "Right Spk"); @@ -201,12 +160,7 @@ static int sof_card_late_probe(struct snd_soc_card *card) return err; } - if (list_empty(&ctx->hdmi_pcm_list)) - return -EINVAL; - - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, head); - - return hda_dsp_hdmi_build_controls(card, pcm->codec_dai->component); + return sof_intel_board_card_late_probe(card); } static const struct snd_kcontrol_new sof_controls[] = { @@ -216,10 +170,6 @@ static const struct snd_kcontrol_new sof_controls[] = { SOC_DAPM_PIN_SWITCH("Right Spk"), }; -static const struct snd_kcontrol_new speaker_controls[] = { - SOC_DAPM_PIN_SWITCH("Spk"), -}; - static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), @@ -227,14 +177,6 @@ static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_SPK("Right Spk", NULL), }; -static const struct snd_soc_dapm_widget speaker_widgets[] = { - SND_SOC_DAPM_SPK("Spk", NULL), -}; - -static const struct snd_soc_dapm_widget dmic_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - static const struct snd_soc_dapm_route sof_map[] = { /* HP jack connectors - unknown if we have jack detection */ { "Headphone Jack", NULL, "HPOL" }, @@ -244,66 +186,6 @@ static const struct snd_soc_dapm_route sof_map[] = { { "MIC", NULL, "Headset Mic" }, }; -static const struct snd_soc_dapm_route speaker_map[] = { - /* speaker */ - { "Spk", NULL, "Speaker" }, -}; - -static const struct snd_soc_dapm_route dmic_map[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - -static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_new_controls(&card->dapm, speaker_widgets, - ARRAY_SIZE(speaker_widgets)); - if (ret) { - dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); - /* Don't need to add routes if widget addition failed */ - return ret; - } - - ret = snd_soc_add_card_controls(card, speaker_controls, - ARRAY_SIZE(speaker_controls)); - if (ret) { - dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map, - ARRAY_SIZE(speaker_map)); - - if (ret) - dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); - return ret; -} - -static int dmic_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, - ARRAY_SIZE(dmic_widgets)); - if (ret) { - dev_err(card->dev, "DMic widget addition failed: %d\n", ret); - /* Don't need to add routes if widget addition failed */ - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, - ARRAY_SIZE(dmic_map)); - - if (ret) - dev_err(card->dev, "DMic map addition failed: %d\n", ret); - - return ret; -} - /* sof audio machine driver for nau8825 codec */ static struct snd_soc_card sof_audio_card_nau8825 = { .name = "nau8825", /* the sof- prefix is added by the core */ @@ -325,37 +207,16 @@ static struct snd_soc_dai_link_component nau8825_component[] = { } }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - -static struct snd_soc_dai_link_component rt1019p_component[] = { - { - .name = "RTL1019:00", - .dai_name = "HiFi", - } -}; - -static struct snd_soc_dai_link_component nau8318_components[] = { - { - .name = "NVTN2012:00", - .dai_name = "nau8315-hifi", - } -}; - -static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, - int ssp_codec, - int ssp_amp, - int dmic_be_num, - int hdmi_num) +static struct snd_soc_dai_link * +sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type, + int ssp_codec, int ssp_amp, int dmic_be_num, + int hdmi_num, bool idisp_codec) { - struct snd_soc_dai_link_component *idisp_components; struct snd_soc_dai_link_component *cpus; struct snd_soc_dai_link *links; - int i, id = 0; + int i; + int id = 0; + int ret; links = devm_kcalloc(dev, sof_audio_card_nau8825.num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL); @@ -395,103 +256,65 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, /* dmic */ if (dmic_be_num > 0) { /* at least we have dmic01 */ - links[id].name = "dmic01"; - links[id].cpus = &cpus[id]; - links[id].cpus->dai_name = "DMIC01 Pin"; - links[id].init = dmic_init; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[id + 1].name = "dmic16k"; - links[id + 1].cpus = &cpus[id + 1]; - links[id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } + ret = sof_intel_board_set_dmic_link(dev, &links[id], id, + SOF_DMIC_01); + if (ret) + return NULL; + + id++; } - for (i = 0; i < dmic_be_num; i++) { - links[id].id = id; - links[id].num_cpus = 1; - links[id].codecs = dmic_component; - links[id].num_codecs = ARRAY_SIZE(dmic_component); - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].ignore_suspend = 1; - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + ret = sof_intel_board_set_dmic_link(dev, &links[id], id, + SOF_DMIC_16K); + if (ret) + return NULL; + id++; } /* HDMI */ - if (hdmi_num > 0) { - idisp_components = devm_kcalloc(dev, - hdmi_num, - sizeof(struct snd_soc_dai_link_component), - GFP_KERNEL); - if (!idisp_components) - goto devm_err; - } for (i = 1; i <= hdmi_num; i++) { - links[id].name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d", i); - if (!links[id].name) - goto devm_err; - - links[id].id = id; - links[id].cpus = &cpus[id]; - links[id].num_cpus = 1; - links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d Pin", i); - if (!links[id].cpus->dai_name) - goto devm_err; - - idisp_components[i - 1].name = "ehdaudio0D2"; - idisp_components[i - 1].dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "intel-hdmi-hifi%d", - i); - if (!idisp_components[i - 1].dai_name) - goto devm_err; + ret = sof_intel_board_set_intel_hdmi_link(dev, &links[id], id, + i, idisp_codec); + if (ret) + return NULL; - links[id].codecs = &idisp_components[i - 1]; - links[id].num_codecs = 1; - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].init = sof_hdmi_init; - links[id].dpcm_playback = 1; - links[id].no_pcm = 1; id++; } /* speaker amp */ - if (sof_nau8825_quirk & SOF_SPEAKER_AMP_PRESENT) { + if (amp_type != CODEC_NONE) { links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_amp); if (!links[id].name) goto devm_err; links[id].id = id; - if (sof_nau8825_quirk & SOF_RT1019P_SPEAKER_AMP_PRESENT) { - links[id].codecs = rt1019p_component; - links[id].num_codecs = ARRAY_SIZE(rt1019p_component); - links[id].init = speaker_codec_init; - } else if (sof_nau8825_quirk & - SOF_MAX98373_SPEAKER_AMP_PRESENT) { + + switch (amp_type) { + case CODEC_MAX98360A: + max_98360a_dai_link(&links[id]); + break; + case CODEC_MAX98373: links[id].codecs = max_98373_components; links[id].num_codecs = ARRAY_SIZE(max_98373_components); links[id].init = max_98373_spk_codec_init; links[id].ops = &max_98373_ops; - } else if (sof_nau8825_quirk & - SOF_MAX98360A_SPEAKER_AMP_PRESENT) { - max_98360a_dai_link(&links[id]); - } else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) { + break; + case CODEC_NAU8318: + nau8318_set_dai_link(&links[id]); + break; + case CODEC_RT1015P: sof_rt1015p_dai_link(&links[id]); - } else if (sof_nau8825_quirk & - SOF_NAU8318_SPEAKER_AMP_PRESENT) { - links[id].codecs = nau8318_components; - links[id].num_codecs = ARRAY_SIZE(nau8318_components); - links[id].init = speaker_codec_init; - } else { - goto devm_err; + break; + case CODEC_RT1019P: + sof_rt1019p_dai_link(&links[id]); + break; + default: + dev_err(dev, "invalid amp type %d\n", amp_type); + return NULL; } links[id].platforms = platform_component; @@ -525,7 +348,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); if (!links[id].name) goto devm_err; - links[id].codecs = &asoc_dummy_dlc; + links[id].codecs = &snd_soc_dummy_dlc; links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); @@ -542,10 +365,9 @@ devm_err: static int sof_audio_probe(struct platform_device *pdev) { + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_dai_link *dai_links; - struct snd_soc_acpi_mach *mach; struct sof_card_private *ctx; - int dmic_be_num, hdmi_num; int ret, ssp_amp, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -555,23 +377,21 @@ static int sof_audio_probe(struct platform_device *pdev) if (pdev->id_entry && pdev->id_entry->driver_data) sof_nau8825_quirk = (unsigned long)pdev->id_entry->driver_data; - mach = pdev->dev.platform_data; - - /* A speaker amp might not be present when the quirk claims one is. - * Detect this via whether the machine driver match includes quirk_data. - */ - if ((sof_nau8825_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data) - sof_nau8825_quirk &= ~SOF_SPEAKER_AMP_PRESENT; + ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev); + ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); dev_dbg(&pdev->dev, "sof_nau8825_quirk = %lx\n", sof_nau8825_quirk); /* default number of DMIC DAI's */ - dmic_be_num = 2; - hdmi_num = (sof_nau8825_quirk & SOF_NAU8825_NUM_HDMIDEV_MASK) >> + ctx->dmic_be_num = 2; + ctx->hdmi_num = (sof_nau8825_quirk & SOF_NAU8825_NUM_HDMIDEV_MASK) >> SOF_NAU8825_NUM_HDMIDEV_SHIFT; /* default number of HDMI DAI's */ - if (!hdmi_num) - hdmi_num = 3; + if (!ctx->hdmi_num) + ctx->hdmi_num = 3; + + if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) + ctx->hdmi.idisp_codec = true; ssp_amp = (sof_nau8825_quirk & SOF_NAU8825_SSP_AMP_MASK) >> SOF_NAU8825_SSP_AMP_SHIFT; @@ -579,27 +399,41 @@ static int sof_audio_probe(struct platform_device *pdev) ssp_codec = sof_nau8825_quirk & SOF_NAU8825_SSP_CODEC_MASK; /* compute number of dai links */ - sof_audio_card_nau8825.num_links = 1 + dmic_be_num + hdmi_num; + sof_audio_card_nau8825.num_links = 1 + ctx->dmic_be_num + ctx->hdmi_num; - if (sof_nau8825_quirk & SOF_SPEAKER_AMP_PRESENT) + if (ctx->amp_type != CODEC_NONE) sof_audio_card_nau8825.num_links++; - if (sof_nau8825_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) - max_98373_set_codec_conf(&sof_audio_card_nau8825); - else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) - sof_rt1015p_codec_conf(&sof_audio_card_nau8825); - if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) sof_audio_card_nau8825.num_links++; - dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, - dmic_be_num, hdmi_num); + dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type, + ssp_codec, ssp_amp, + ctx->dmic_be_num, ctx->hdmi_num, + ctx->hdmi.idisp_codec); if (!dai_links) return -ENOMEM; sof_audio_card_nau8825.dai_link = dai_links; - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); + /* update codec_conf */ + switch (ctx->amp_type) { + case CODEC_MAX98373: + max_98373_set_codec_conf(&sof_audio_card_nau8825); + break; + case CODEC_RT1015P: + sof_rt1015p_codec_conf(&sof_audio_card_nau8825); + break; + case CODEC_NONE: + case CODEC_MAX98360A: + case CODEC_NAU8318: + case CODEC_RT1019P: + /* no codec conf required */ + break; + default: + dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type); + return -EINVAL; + } sof_audio_card_nau8825.dev = &pdev->dev; @@ -627,16 +461,12 @@ static const struct platform_device_id board_ids[] = { { .name = "adl_rt1019p_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1019P_SPEAKER_AMP_PRESENT | SOF_NAU8825_SSP_AMP(2) | SOF_NAU8825_NUM_HDMIDEV(4)), }, { .name = "adl_max98373_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | SOF_NAU8825_SSP_AMP(1) | SOF_NAU8825_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -646,8 +476,6 @@ static const struct platform_device_id board_ids[] = { /* The limitation of length of char array, shorten the name */ .name = "adl_mx98360a_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_NAU8825_SSP_AMP(1) | SOF_NAU8825_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -657,8 +485,6 @@ static const struct platform_device_id board_ids[] = { { .name = "adl_rt1015p_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1015P_SPEAKER_AMP_PRESENT | SOF_NAU8825_SSP_AMP(1) | SOF_NAU8825_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -667,8 +493,6 @@ static const struct platform_device_id board_ids[] = { { .name = "adl_nau8318_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_NAU8318_SPEAKER_AMP_PRESENT | SOF_NAU8825_SSP_AMP(1) | SOF_NAU8825_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -677,8 +501,14 @@ static const struct platform_device_id board_ids[] = { { .name = "rpl_max98373_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | + SOF_NAU8825_SSP_AMP(1) | + SOF_NAU8825_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, + { + .name = "rpl_mx98360a_8825", + .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | SOF_NAU8825_SSP_AMP(1) | SOF_NAU8825_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -687,8 +517,6 @@ static const struct platform_device_id board_ids[] = { { .name = "rpl_nau8318_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_NAU8318_SPEAKER_AMP_PRESENT | SOF_NAU8825_SSP_AMP(1) | SOF_NAU8825_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -712,7 +540,10 @@ module_platform_driver(sof_audio) MODULE_DESCRIPTION("SOF Audio Machine driver for NAU8825"); MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>"); MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); +MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_NUVOTON_COMMON); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON); diff --git a/sound/soc/intel/boards/sof_nuvoton_common.c b/sound/soc/intel/boards/sof_nuvoton_common.c new file mode 100644 index 0000000000..549a412f5d --- /dev/null +++ b/sound/soc/intel/boards/sof_nuvoton_common.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * This file defines data structures and functions used in Machine + * Driver for Intel platforms with Nuvoton Codecs. + * + * Copyright 2023 Intel Corporation. + */ +#include <linux/module.h> +#include <sound/sof.h> +#include "sof_nuvoton_common.h" + +/* + * Nuvoton NAU8318 + */ +static const struct snd_kcontrol_new nau8318_kcontrols[] = { + SOC_DAPM_PIN_SWITCH("Spk"), +}; + +static const struct snd_soc_dapm_widget nau8318_widgets[] = { + SND_SOC_DAPM_SPK("Spk", NULL), +}; + +static const struct snd_soc_dapm_route nau8318_routes[] = { + { "Spk", NULL, "Speaker" }, +}; + +static struct snd_soc_dai_link_component nau8318_components[] = { + { + .name = NAU8318_DEV0_NAME, + .dai_name = NAU8318_CODEC_DAI, + } +}; + +static int nau8318_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_dapm_new_controls(&card->dapm, nau8318_widgets, + ARRAY_SIZE(nau8318_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add nau8318 widgets, ret %d\n", ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, nau8318_kcontrols, + ARRAY_SIZE(nau8318_kcontrols)); + if (ret) { + dev_err(rtd->dev, "fail to add nau8318 kcontrols, ret %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, nau8318_routes, + ARRAY_SIZE(nau8318_routes)); + + if (ret) { + dev_err(rtd->dev, "fail to add nau8318 routes, ret %d\n", ret); + return ret; + } + + return ret; +} + +void nau8318_set_dai_link(struct snd_soc_dai_link *link) +{ + link->codecs = nau8318_components; + link->num_codecs = ARRAY_SIZE(nau8318_components); + link->init = nau8318_init; +} +EXPORT_SYMBOL_NS(nau8318_set_dai_link, SND_SOC_INTEL_SOF_NUVOTON_COMMON); + +MODULE_DESCRIPTION("ASoC Intel SOF Nuvoton helpers"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/boards/sof_nuvoton_common.h b/sound/soc/intel/boards/sof_nuvoton_common.h new file mode 100644 index 0000000000..53a84f9a67 --- /dev/null +++ b/sound/soc/intel/boards/sof_nuvoton_common.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * This file defines data structures used in Machine Driver for Intel + * platforms with Nuvoton Codecs. + * + * Copyright 2023 Intel Corporation. + */ +#ifndef __SOF_NUVOTON_COMMON_H +#define __SOF_NUVOTON_COMMON_H + +#include <sound/soc.h> +#include "sof_ssp_common.h" + +/* + * Nuvoton NAU8318 + */ +#define NAU8318_CODEC_DAI "nau8315-hifi" +#define NAU8318_DEV0_NAME "i2c-" NAU8318_ACPI_HID ":00" + +void nau8318_set_dai_link(struct snd_soc_dai_link *link); + +#endif /* __SOF_NUVOTON_COMMON_H */ diff --git a/sound/soc/intel/boards/sof_pcm512x.c b/sound/soc/intel/boards/sof_pcm512x.c index 9f673ccf81..b01cb23295 100644 --- a/sound/soc/intel/boards/sof_pcm512x.c +++ b/sound/soc/intel/boards/sof_pcm512x.c @@ -71,7 +71,7 @@ static const struct dmi_system_id sof_pcm512x_quirk_table[] = { static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct sof_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -89,7 +89,7 @@ static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) static int sof_pcm512x_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); snd_soc_component_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); @@ -101,8 +101,8 @@ static int sof_pcm512x_codec_init(struct snd_soc_pcm_runtime *rtd) static int aif1_startup(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); @@ -112,8 +112,8 @@ static int aif1_startup(struct snd_pcm_substream *substream) static void aif1_shutdown(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x00); @@ -331,7 +331,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, devm_kasprintf(dev, GFP_KERNEL, "intel-hdmi-hifi%d", i); } else { - idisp_components[i - 1] = asoc_dummy_dlc; + idisp_components[i - 1] = snd_soc_dummy_dlc; } if (!idisp_components[i - 1].dai_name) goto devm_err; diff --git a/sound/soc/intel/boards/sof_realtek_common.c b/sound/soc/intel/boards/sof_realtek_common.c index 6c12ca92f3..80c8687cd1 100644 --- a/sound/soc/intel/boards/sof_realtek_common.c +++ b/sound/soc/intel/boards/sof_realtek_common.c @@ -68,7 +68,7 @@ static const struct { static int rt1011_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int srate, i, ret = 0; @@ -264,7 +264,7 @@ static const struct { static int rt1015_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai_link *dai_link = rtd->dai_link; struct snd_soc_dai *codec_dai; int i, clk_freq; @@ -423,9 +423,9 @@ static int rt1308_init(struct snd_soc_pcm_runtime *rtd) static int rt1308_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int clk_id, clk_freq, pll_out; int ret; diff --git a/sound/soc/intel/boards/sof_realtek_common.h b/sound/soc/intel/boards/sof_realtek_common.h index 3ae99d8239..e3fa2924c1 100644 --- a/sound/soc/intel/boards/sof_realtek_common.h +++ b/sound/soc/intel/boards/sof_realtek_common.h @@ -11,36 +11,53 @@ #define __SOF_REALTEK_COMMON_H #include <sound/soc.h> +#include "sof_ssp_common.h" + +/* + * Realtek ALC1011 + */ #define RT1011_CODEC_DAI "rt1011-aif" -#define RT1011_DEV0_NAME "i2c-10EC1011:00" -#define RT1011_DEV1_NAME "i2c-10EC1011:01" -#define RT1011_DEV2_NAME "i2c-10EC1011:02" -#define RT1011_DEV3_NAME "i2c-10EC1011:03" +#define RT1011_DEV0_NAME "i2c-" RT1011_ACPI_HID ":00" +#define RT1011_DEV1_NAME "i2c-" RT1011_ACPI_HID ":01" +#define RT1011_DEV2_NAME "i2c-" RT1011_ACPI_HID ":02" +#define RT1011_DEV3_NAME "i2c-" RT1011_ACPI_HID ":03" void sof_rt1011_dai_link(struct snd_soc_dai_link *link); void sof_rt1011_codec_conf(struct snd_soc_card *card); +/* + * Realtek ALC1015 (AUTO) + */ #define RT1015P_CODEC_DAI "HiFi" -#define RT1015P_DEV0_NAME "RTL1015:00" -#define RT1015P_DEV1_NAME "RTL1015:01" +#define RT1015P_DEV0_NAME RT1015P_ACPI_HID ":00" +#define RT1015P_DEV1_NAME RT1015P_ACPI_HID ":01" void sof_rt1015p_dai_link(struct snd_soc_dai_link *link); void sof_rt1015p_codec_conf(struct snd_soc_card *card); +/* + * Realtek ALC1015 (I2C) + */ #define RT1015_CODEC_DAI "rt1015-aif" -#define RT1015_DEV0_NAME "i2c-10EC1015:00" -#define RT1015_DEV1_NAME "i2c-10EC1015:01" +#define RT1015_DEV0_NAME "i2c-" RT1015_ACPI_HID ":00" +#define RT1015_DEV1_NAME "i2c-" RT1015_ACPI_HID ":01" void sof_rt1015_dai_link(struct snd_soc_dai_link *link); void sof_rt1015_codec_conf(struct snd_soc_card *card); +/* + * Realtek ALC1308 + */ #define RT1308_CODEC_DAI "rt1308-aif" -#define RT1308_DEV0_NAME "i2c-10EC1308:00" +#define RT1308_DEV0_NAME "i2c-" RT1308_ACPI_HID ":00" void sof_rt1308_dai_link(struct snd_soc_dai_link *link); +/* + * Realtek ALC1019 + */ #define RT1019P_CODEC_DAI "HiFi" -#define RT1019P_DEV0_NAME "RTL1019:00" +#define RT1019P_DEV0_NAME RT1019P_ACPI_HID ":00" void sof_rt1019p_dai_link(struct snd_soc_dai_link *link); diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index fae091b9b5..06ad15af46 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -23,19 +23,15 @@ #include "../../codecs/rt5682.h" #include "../../codecs/rt5682s.h" #include "../../codecs/rt5645.h" -#include "../../codecs/hdac_hdmi.h" #include "../common/soc-intel-quirks.h" -#include "hda_dsp_common.h" +#include "sof_board_helpers.h" #include "sof_maxim_common.h" #include "sof_realtek_common.h" - -#define NAME_SIZE 32 +#include "sof_ssp_common.h" #define SOF_RT5682_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0)) #define SOF_RT5682_SSP_CODEC_MASK (GENMASK(2, 0)) #define SOF_RT5682_MCLK_EN BIT(3) -#define SOF_RT5682_MCLK_24MHZ BIT(4) -#define SOF_SPEAKER_AMP_PRESENT BIT(5) #define SOF_RT5682_SSP_AMP_SHIFT 6 #define SOF_RT5682_SSP_AMP_MASK (GENMASK(8, 6)) #define SOF_RT5682_SSP_AMP(quirk) \ @@ -45,11 +41,6 @@ #define SOF_RT5682_NUM_HDMIDEV_MASK (GENMASK(12, 10)) #define SOF_RT5682_NUM_HDMIDEV(quirk) \ ((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK) -#define SOF_RT1011_SPEAKER_AMP_PRESENT BIT(13) -#define SOF_RT1015_SPEAKER_AMP_PRESENT BIT(14) -#define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(16) -#define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(17) -#define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(18) /* BT audio offload: reserve 3 bits for future */ #define SOF_BT_OFFLOAD_SSP_SHIFT 19 @@ -57,10 +48,6 @@ #define SOF_BT_OFFLOAD_SSP(quirk) \ (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK) #define SOF_SSP_BT_OFFLOAD_PRESENT BIT(22) -#define SOF_RT5682S_HEADPHONE_CODEC_PRESENT BIT(23) -#define SOF_MAX98390_SPEAKER_AMP_PRESENT BIT(24) -#define SOF_RT1019_SPEAKER_AMP_PRESENT BIT(26) -#define SOF_RT5650_HEADPHONE_CODEC_PRESENT BIT(27) /* HDMI capture*/ #define SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT 27 @@ -72,23 +59,6 @@ static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0); -static int is_legacy_cpu; - -struct sof_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - struct snd_soc_jack hdmi_jack; - int device; -}; - -struct sof_card_private { - struct clk *mclk; - struct snd_soc_jack sof_headset; - struct list_head hdmi_pcm_list; - bool common_hdmi_codec_drv; - bool idisp_codec; -}; - static int sof_rt5682_quirk_cb(const struct dmi_system_id *id) { sof_rt5682_quirk = (unsigned long)id->driver_data; @@ -119,35 +89,15 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"), }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(1)), }, { - /* - * Dooly is hatch family but using rt1015 amp so it - * requires a quirk before "Google_Hatch". - */ - .callback = sof_rt5682_quirk_cb, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "Dooly"), - }, - .driver_data = (void *)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | - SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1015_SPEAKER_AMP_PRESENT | - SOF_RT5682_SSP_AMP(1)), - }, - { .callback = sof_rt5682_quirk_cb, .matches = { DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"), }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1)), }, { @@ -167,8 +117,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, @@ -181,8 +129,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, @@ -194,8 +140,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98390_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, @@ -207,8 +151,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, @@ -220,10 +162,22 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(2) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(0) | - SOF_RT5682_NUM_HDMIDEV(4) | + SOF_RT5682_NUM_HDMIDEV(3) | + SOF_BT_OFFLOAD_SSP(1) | + SOF_SSP_BT_OFFLOAD_PRESENT + ), + }, + { + .callback = sof_rt5682_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"), + DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_DISCRETE_I2S_BT"), + }, + .driver_data = (void *)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(2) | + SOF_RT5682_SSP_AMP(0) | + SOF_RT5682_NUM_HDMIDEV(3) | SOF_BT_OFFLOAD_SSP(1) | SOF_SSP_BT_OFFLOAD_PRESENT ), @@ -236,8 +190,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(2) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1019_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(0) | SOF_RT5682_NUM_HDMIDEV(3) ), @@ -249,9 +201,8 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(2) | - SOF_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(0) | - SOF_RT5682_NUM_HDMIDEV(4) | + SOF_RT5682_NUM_HDMIDEV(3) | SOF_BT_OFFLOAD_SSP(1) | SOF_SSP_BT_OFFLOAD_PRESENT ), @@ -259,25 +210,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { {} }; -static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) -{ - struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); - struct sof_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; -} - static struct snd_soc_jack_pin jack_pins[] = { { .pin = "Headphone Jack", @@ -292,54 +224,72 @@ static struct snd_soc_jack_pin jack_pins[] = { static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_jack *jack; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_jack *jack = &ctx->headset_jack; int extra_jack_data; - int ret; - - /* need to enable ASRC function for 24MHz mclk rate */ - if ((sof_rt5682_quirk & SOF_RT5682_MCLK_EN) && - (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ)) { - if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) - rt5682s_sel_asrc_clk_src(component, - RT5682S_DA_STEREO1_FILTER | - RT5682S_AD_STEREO1_FILTER, - RT5682S_CLK_SEL_I2S1_ASRC); - else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) { - rt5645_sel_asrc_clk_src(component, - RT5645_DA_STEREO_FILTER | - RT5645_AD_STEREO_FILTER, - RT5645_CLK_SEL_I2S1_ASRC); - rt5645_sel_asrc_clk_src(component, - RT5645_DA_MONO_L_FILTER | - RT5645_DA_MONO_R_FILTER, - RT5645_CLK_SEL_I2S2_ASRC); - } else - rt5682_sel_asrc_clk_src(component, - RT5682_DA_STEREO1_FILTER | - RT5682_AD_STEREO1_FILTER, - RT5682_CLK_SEL_I2S1_ASRC); - } + int ret, mclk_freq; - if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { - /* - * The firmware might enable the clock at - * boot (this information may or may not - * be reflected in the enable clock register). - * To change the rate we must disable the clock - * first to cover these cases. Due to common - * clock framework restrictions that do not allow - * to disable a clock that has not been enabled, - * we need to enable the clock first. - */ - ret = clk_prepare_enable(ctx->mclk); - if (!ret) - clk_disable_unprepare(ctx->mclk); + if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) { + mclk_freq = sof_dai_get_mclk(rtd); + if (mclk_freq <= 0) { + dev_err(rtd->dev, "invalid mclk freq %d\n", mclk_freq); + return -EINVAL; + } - ret = clk_set_rate(ctx->mclk, 19200000); + /* need to enable ASRC function for 24MHz mclk rate */ + if (mclk_freq == 24000000) { + dev_info(rtd->dev, "enable ASRC\n"); + + switch (ctx->codec_type) { + case CODEC_RT5650: + rt5645_sel_asrc_clk_src(component, + RT5645_DA_STEREO_FILTER | + RT5645_AD_STEREO_FILTER, + RT5645_CLK_SEL_I2S1_ASRC); + rt5645_sel_asrc_clk_src(component, + RT5645_DA_MONO_L_FILTER | + RT5645_DA_MONO_R_FILTER, + RT5645_CLK_SEL_I2S2_ASRC); + break; + case CODEC_RT5682: + rt5682_sel_asrc_clk_src(component, + RT5682_DA_STEREO1_FILTER | + RT5682_AD_STEREO1_FILTER, + RT5682_CLK_SEL_I2S1_ASRC); + break; + case CODEC_RT5682S: + rt5682s_sel_asrc_clk_src(component, + RT5682S_DA_STEREO1_FILTER | + RT5682S_AD_STEREO1_FILTER, + RT5682S_CLK_SEL_I2S1_ASRC); + break; + default: + dev_err(rtd->dev, "invalid codec type %d\n", + ctx->codec_type); + return -EINVAL; + } + } - if (ret) - dev_err(rtd->dev, "unable to set MCLK rate\n"); + if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { + /* + * The firmware might enable the clock at + * boot (this information may or may not + * be reflected in the enable clock register). + * To change the rate we must disable the clock + * first to cover these cases. Due to common + * clock framework restrictions that do not allow + * to disable a clock that has not been enabled, + * we need to enable the clock first. + */ + ret = clk_prepare_enable(ctx->rt5682.mclk); + if (!ret) + clk_disable_unprepare(ctx->rt5682.mclk); + + ret = clk_set_rate(ctx->rt5682.mclk, 19200000); + + if (ret) + dev_err(rtd->dev, "unable to set MCLK rate\n"); + } } /* @@ -350,7 +300,7 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, - &ctx->sof_headset, + jack, jack_pins, ARRAY_SIZE(jack_pins)); if (ret) { @@ -358,14 +308,12 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } - jack = &ctx->sof_headset; - snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); - if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) { + if (ctx->codec_type == CODEC_RT5650) { extra_jack_data = SND_JACK_MICROPHONE | SND_JACK_BTN_0; ret = snd_soc_component_set_jack(component, jack, &extra_jack_data); } else @@ -381,7 +329,7 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(component, NULL, NULL); } @@ -389,14 +337,14 @@ static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd) static int sof_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int pll_id, pll_source, pll_in, pll_out, clk_id, ret; if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) { if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { - ret = clk_prepare_enable(ctx->mclk); + ret = clk_prepare_enable(ctx->rt5682.mclk); if (ret < 0) { dev_err(rtd->dev, "could not configure MCLK state"); @@ -404,55 +352,86 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream, } } - if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) - pll_source = RT5682S_PLL_S_MCLK; - else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) + switch (ctx->codec_type) { + case CODEC_RT5650: pll_source = RT5645_PLL1_S_MCLK; - else + break; + case CODEC_RT5682: pll_source = RT5682_PLL1_S_MCLK; + break; + case CODEC_RT5682S: + pll_source = RT5682S_PLL_S_MCLK; + break; + default: + dev_err(rtd->dev, "invalid codec type %d\n", + ctx->codec_type); + return -EINVAL; + } /* get the tplg configured mclk. */ pll_in = sof_dai_get_mclk(rtd); - - /* mclk from the quirk is the first choice */ - if (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ) { - if (pll_in != 24000000) - dev_warn(rtd->dev, "configure wrong mclk in tplg, please use 24MHz.\n"); - pll_in = 24000000; - } else if (pll_in == 0) { - /* use default mclk if not specified correct in topology */ - pll_in = 19200000; - } else if (pll_in < 0) { - return pll_in; + if (pll_in <= 0) { + dev_err(rtd->dev, "invalid mclk freq %d\n", pll_in); + return -EINVAL; } } else { - if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) - pll_source = RT5682S_PLL_S_BCLK1; - else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) + switch (ctx->codec_type) { + case CODEC_RT5650: pll_source = RT5645_PLL1_S_BCLK1; - else + break; + case CODEC_RT5682: pll_source = RT5682_PLL1_S_BCLK1; + break; + case CODEC_RT5682S: + pll_source = RT5682S_PLL_S_BCLK1; + break; + default: + dev_err(rtd->dev, "invalid codec type %d\n", + ctx->codec_type); + return -EINVAL; + } pll_in = params_rate(params) * 50; } - if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) { - pll_id = RT5682S_PLL2; - clk_id = RT5682S_SCLK_S_PLL2; - } else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) { + switch (ctx->codec_type) { + case CODEC_RT5650: pll_id = 0; /* not used in codec driver */ clk_id = RT5645_SCLK_S_PLL1; - } else { + break; + case CODEC_RT5682: pll_id = RT5682_PLL1; clk_id = RT5682_SCLK_S_PLL1; + break; + case CODEC_RT5682S: + pll_id = RT5682S_PLL2; + clk_id = RT5682S_SCLK_S_PLL2; + break; + default: + dev_err(rtd->dev, "invalid codec type %d\n", ctx->codec_type); + return -EINVAL; } pll_out = params_rate(params) * 512; /* when MCLK is 512FS, no need to set PLL configuration additionally. */ - if (pll_in == pll_out) - clk_id = RT5682S_SCLK_S_MCLK; - else { + if (pll_in == pll_out) { + switch (ctx->codec_type) { + case CODEC_RT5650: + clk_id = RT5645_SCLK_S_MCLK; + break; + case CODEC_RT5682: + clk_id = RT5682_SCLK_S_MCLK; + break; + case CODEC_RT5682S: + clk_id = RT5682S_SCLK_S_MCLK; + break; + default: + dev_err(rtd->dev, "invalid codec type %d\n", + ctx->codec_type); + return -EINVAL; + } + } else { /* Configure pll for codec */ ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, pll_in, pll_out); @@ -494,13 +473,10 @@ static struct snd_soc_dai_link_component platform_component[] = { static int sof_card_late_probe(struct snd_soc_card *card) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component = NULL; struct snd_soc_dapm_context *dapm = &card->dapm; - char jack_name[NAME_SIZE]; - struct sof_hdmi_pcm *pcm; int err; - if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) { + if (ctx->amp_type == CODEC_MAX98373) { /* Disable Left and Right Spk pin after boot */ snd_soc_dapm_disable_pin(dapm, "Left Spk"); snd_soc_dapm_disable_pin(dapm, "Right Spk"); @@ -509,37 +485,7 @@ static int sof_card_late_probe(struct snd_soc_card *card) return err; } - /* HDMI is not supported by SOF on Baytrail/CherryTrail */ - if (is_legacy_cpu || !ctx->idisp_codec) - return 0; - - if (list_empty(&ctx->hdmi_pcm_list)) - return -EINVAL; - - if (ctx->common_hdmi_codec_drv) { - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, - head); - component = pcm->codec_dai->component; - return hda_dsp_hdmi_build_controls(card, component); - } - - 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, &pcm->hdmi_jack); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &pcm->hdmi_jack); - if (err < 0) - return err; - } - - return hdac_hdmi_jack_port_init(component, &card->dapm); + return sof_intel_board_card_late_probe(card); } static const struct snd_kcontrol_new sof_controls[] = { @@ -557,10 +503,6 @@ static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_SPK("Right Spk", NULL), }; -static const struct snd_soc_dapm_widget dmic_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - static const struct snd_soc_dapm_route sof_map[] = { /* HP jack connectors - unknown if we have jack detection */ { "Headphone Jack", NULL, "HPOL" }, @@ -576,11 +518,6 @@ static const struct snd_soc_dapm_route rt5650_spk_dapm_routes[] = { { "Right Spk", NULL, "SPOR" }, }; -static const struct snd_soc_dapm_route dmic_map[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; @@ -594,28 +531,6 @@ static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd) return ret; } -static int dmic_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, - ARRAY_SIZE(dmic_widgets)); - if (ret) { - dev_err(card->dev, "DMic widget addition failed: %d\n", ret); - /* Don't need to add routes if widget addition failed */ - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, - ARRAY_SIZE(dmic_map)); - - if (ret) - dev_err(card->dev, "DMic map addition failed: %d\n", ret); - - return ret; -} - /* sof audio machine driver for rt5682 codec */ static struct snd_soc_card sof_audio_card_rt5682 = { .name = "rt5682", /* the sof- prefix is added by the core */ @@ -655,26 +570,17 @@ static struct snd_soc_dai_link_component rt5650_components[] = { } }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - -#define IDISP_CODEC_MASK 0x4 - -static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, - int ssp_codec, - int ssp_amp, - int dmic_be_num, - int hdmi_num, - bool idisp_codec) +static struct snd_soc_dai_link * +sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec codec_type, + enum sof_ssp_codec amp_type, int ssp_codec, + int ssp_amp, int dmic_be_num, int hdmi_num, + bool idisp_codec, bool is_legacy_cpu) { - struct snd_soc_dai_link_component *idisp_components; struct snd_soc_dai_link_component *cpus; struct snd_soc_dai_link *links; - int i, id = 0; + int i; + int id = 0; + int ret; int hdmi_id_offset = 0; links = devm_kcalloc(dev, sof_audio_card_rt5682.num_links, @@ -691,16 +597,25 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, goto devm_err; links[id].id = id; - if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) { - links[id].codecs = rt5682s_component; - links[id].num_codecs = ARRAY_SIZE(rt5682s_component); - } else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) { + + switch (codec_type) { + case CODEC_RT5650: links[id].codecs = &rt5650_components[0]; links[id].num_codecs = 1; - } else { + break; + case CODEC_RT5682: links[id].codecs = rt5682_component; links[id].num_codecs = ARRAY_SIZE(rt5682_component); + break; + case CODEC_RT5682S: + links[id].codecs = rt5682s_component; + links[id].num_codecs = ARRAY_SIZE(rt5682s_component); + break; + default: + dev_err(dev, "invalid codec type %d\n", codec_type); + return NULL; } + links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].init = sof_rt5682_codec_init; @@ -739,114 +654,83 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, /* dmic */ if (dmic_be_num > 0) { /* at least we have dmic01 */ - links[id].name = "dmic01"; - links[id].cpus = &cpus[id]; - links[id].cpus->dai_name = "DMIC01 Pin"; - links[id].init = dmic_init; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[id + 1].name = "dmic16k"; - links[id + 1].cpus = &cpus[id + 1]; - links[id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } + ret = sof_intel_board_set_dmic_link(dev, &links[id], id, + SOF_DMIC_01); + if (ret) + return NULL; + + id++; } - for (i = 0; i < dmic_be_num; i++) { - links[id].id = id; - links[id].num_cpus = 1; - links[id].codecs = dmic_component; - links[id].num_codecs = ARRAY_SIZE(dmic_component); - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].ignore_suspend = 1; - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + ret = sof_intel_board_set_dmic_link(dev, &links[id], id, + SOF_DMIC_16K); + if (ret) + return NULL; + id++; } /* HDMI */ - if (hdmi_num > 0) { - idisp_components = devm_kcalloc(dev, - hdmi_num, - sizeof(struct snd_soc_dai_link_component), - GFP_KERNEL); - if (!idisp_components) - goto devm_err; - } for (i = 1; i <= hdmi_num; i++) { - links[id].name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d", i); - if (!links[id].name) - goto devm_err; - - links[id].id = id; - links[id].cpus = &cpus[id]; - links[id].num_cpus = 1; - links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d Pin", i); - if (!links[id].cpus->dai_name) - goto devm_err; - - if (idisp_codec) { - idisp_components[i - 1].name = "ehdaudio0D2"; - idisp_components[i - 1].dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "intel-hdmi-hifi%d", - i); - if (!idisp_components[i - 1].dai_name) - goto devm_err; - } else { - idisp_components[i - 1] = asoc_dummy_dlc; - } + ret = sof_intel_board_set_intel_hdmi_link(dev, &links[id], id, + i, idisp_codec); + if (ret) + return NULL; - links[id].codecs = &idisp_components[i - 1]; - links[id].num_codecs = 1; - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].init = sof_hdmi_init; - links[id].dpcm_playback = 1; - links[id].no_pcm = 1; id++; } /* speaker amp */ - if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) { + if (amp_type != CODEC_NONE) { links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_amp); if (!links[id].name) goto devm_err; links[id].id = id; - if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) { - sof_rt1015_dai_link(&links[id]); - } else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) { - sof_rt1015p_dai_link(&links[id]); - } else if (sof_rt5682_quirk & SOF_RT1019_SPEAKER_AMP_PRESENT) { - sof_rt1019p_dai_link(&links[id]); - } else if (sof_rt5682_quirk & - SOF_MAX98373_SPEAKER_AMP_PRESENT) { + + switch (amp_type) { + case CODEC_MAX98357A: + max_98357a_dai_link(&links[id]); + break; + case CODEC_MAX98360A: + max_98360a_dai_link(&links[id]); + break; + case CODEC_MAX98373: links[id].codecs = max_98373_components; links[id].num_codecs = ARRAY_SIZE(max_98373_components); links[id].init = max_98373_spk_codec_init; links[id].ops = &max_98373_ops; - } else if (sof_rt5682_quirk & - SOF_MAX98360A_SPEAKER_AMP_PRESENT) { - max_98360a_dai_link(&links[id]); - } else if (sof_rt5682_quirk & - SOF_RT1011_SPEAKER_AMP_PRESENT) { - sof_rt1011_dai_link(&links[id]); - } else if (sof_rt5682_quirk & - SOF_MAX98390_SPEAKER_AMP_PRESENT) { + break; + case CODEC_MAX98390: max_98390_dai_link(dev, &links[id]); - } else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) { + break; + case CODEC_RT1011: + sof_rt1011_dai_link(&links[id]); + break; + case CODEC_RT1015: + sof_rt1015_dai_link(&links[id]); + break; + case CODEC_RT1015P: + sof_rt1015p_dai_link(&links[id]); + break; + case CODEC_RT1019P: + sof_rt1019p_dai_link(&links[id]); + break; + case CODEC_RT5650: + /* use AIF2 to support speaker pipeline */ links[id].codecs = &rt5650_components[1]; links[id].num_codecs = 1; links[id].init = rt5650_spk_init; links[id].ops = &sof_rt5682_ops; - } else { - max_98357a_dai_link(&links[id]); + break; + default: + dev_err(dev, "invalid amp type %d\n", amp_type); + return NULL; } + links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].dpcm_playback = 1; @@ -887,7 +771,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); if (!links[id].name) goto devm_err; - links[id].codecs = &asoc_dummy_dlc; + links[id].codecs = &snd_soc_dummy_dlc; links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); @@ -914,7 +798,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, if (!links[id].name) return NULL; links[id].id = id + hdmi_id_offset; - links[id].codecs = &asoc_dummy_dlc; + links[id].codecs = &snd_soc_dummy_dlc; links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); @@ -932,10 +816,9 @@ devm_err: static int sof_audio_probe(struct platform_device *pdev) { + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_dai_link *dai_links; - struct snd_soc_acpi_mach *mach; struct sof_card_private *ctx; - int dmic_be_num, hdmi_num; int ret, ssp_amp, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -947,49 +830,44 @@ static int sof_audio_probe(struct platform_device *pdev) dmi_check_system(sof_rt5682_quirk_table); - mach = pdev->dev.platform_data; - - /* A speaker amp might not be present when the quirk claims one is. - * Detect this via whether the machine driver match includes quirk_data. - */ - if ((sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data) - sof_rt5682_quirk &= ~SOF_SPEAKER_AMP_PRESENT; - - /* Detect the headset codec variant */ - if (acpi_dev_present("RTL5682", NULL, -1)) - sof_rt5682_quirk |= SOF_RT5682S_HEADPHONE_CODEC_PRESENT; - else if (acpi_dev_present("10EC5650", NULL, -1)) { - sof_rt5682_quirk |= SOF_RT5650_HEADPHONE_CODEC_PRESENT; + ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev); + ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); + if (ctx->codec_type == CODEC_RT5650) { sof_audio_card_rt5682.name = devm_kstrdup(&pdev->dev, "rt5650", GFP_KERNEL); + + /* create speaker dai link also */ + if (ctx->amp_type == CODEC_NONE) + ctx->amp_type = CODEC_RT5650; } if (soc_intel_is_byt() || soc_intel_is_cht()) { - is_legacy_cpu = 1; - dmic_be_num = 0; - hdmi_num = 0; + ctx->rt5682.is_legacy_cpu = true; + ctx->dmic_be_num = 0; + /* HDMI is not supported by SOF on Baytrail/CherryTrail */ + ctx->hdmi_num = 0; /* default quirk for legacy cpu */ sof_rt5682_quirk = SOF_RT5682_MCLK_EN | SOF_RT5682_MCLK_BYTCHT_EN | SOF_RT5682_SSP_CODEC(2); } else { - dmic_be_num = 2; - hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >> + ctx->dmic_be_num = 2; + ctx->hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >> SOF_RT5682_NUM_HDMIDEV_SHIFT; /* default number of HDMI DAI's */ - if (!hdmi_num) - hdmi_num = 3; + if (!ctx->hdmi_num) + ctx->hdmi_num = 3; if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) - ctx->idisp_codec = true; + ctx->hdmi.idisp_codec = true; } /* need to get main clock from pmc */ if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { - ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); - if (IS_ERR(ctx->mclk)) { - ret = PTR_ERR(ctx->mclk); + ctx->rt5682.mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (IS_ERR(ctx->rt5682.mclk)) { + ret = PTR_ERR(ctx->rt5682.mclk); dev_err(&pdev->dev, "Failed to get MCLK from pmc_plt_clk_3: %d\n", @@ -997,7 +875,7 @@ static int sof_audio_probe(struct platform_device *pdev) return ret; } - ret = clk_prepare_enable(ctx->mclk); + ret = clk_prepare_enable(ctx->rt5682.mclk); if (ret < 0) { dev_err(&pdev->dev, "could not configure MCLK state"); @@ -1013,21 +891,11 @@ static int sof_audio_probe(struct platform_device *pdev) ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK; /* compute number of dai links */ - sof_audio_card_rt5682.num_links = 1 + dmic_be_num + hdmi_num; + sof_audio_card_rt5682.num_links = 1 + ctx->dmic_be_num + ctx->hdmi_num; - if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) + if (ctx->amp_type != CODEC_NONE) sof_audio_card_rt5682.num_links++; - if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) - max_98373_set_codec_conf(&sof_audio_card_rt5682); - else if (sof_rt5682_quirk & SOF_RT1011_SPEAKER_AMP_PRESENT) - sof_rt1011_codec_conf(&sof_audio_card_rt5682); - else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) - sof_rt1015p_codec_conf(&sof_audio_card_rt5682); - else if (sof_rt5682_quirk & SOF_MAX98390_SPEAKER_AMP_PRESENT) { - max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682); - } - if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) sof_audio_card_rt5682.num_links++; @@ -1036,17 +904,44 @@ static int sof_audio_probe(struct platform_device *pdev) hweight32((sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) >> SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT); - dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, - dmic_be_num, hdmi_num, ctx->idisp_codec); + dai_links = sof_card_dai_links_create(&pdev->dev, ctx->codec_type, + ctx->amp_type, ssp_codec, ssp_amp, + ctx->dmic_be_num, ctx->hdmi_num, + ctx->hdmi.idisp_codec, + ctx->rt5682.is_legacy_cpu); if (!dai_links) return -ENOMEM; sof_audio_card_rt5682.dai_link = dai_links; - if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) + /* update codec_conf */ + switch (ctx->amp_type) { + case CODEC_MAX98373: + max_98373_set_codec_conf(&sof_audio_card_rt5682); + break; + case CODEC_MAX98390: + max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682); + break; + case CODEC_RT1011: + sof_rt1011_codec_conf(&sof_audio_card_rt5682); + break; + case CODEC_RT1015: sof_rt1015_codec_conf(&sof_audio_card_rt5682); - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); + break; + case CODEC_RT1015P: + sof_rt1015p_codec_conf(&sof_audio_card_rt5682); + break; + case CODEC_NONE: + case CODEC_MAX98357A: + case CODEC_MAX98360A: + case CODEC_RT1019P: + case CODEC_RT5650: + /* no codec conf required */ + break; + default: + dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type); + return -EINVAL; + } sof_audio_card_rt5682.dev = &pdev->dev; @@ -1056,8 +951,6 @@ static int sof_audio_probe(struct platform_device *pdev) if (ret) return ret; - ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; - snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx); return devm_snd_soc_register_card(&pdev->dev, @@ -1071,50 +964,42 @@ static const struct platform_device_id board_ids[] = { { .name = "cml_rt1015_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1015_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1)), }, { .name = "jsl_rt5682_rt1015", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1015_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1)), }, { .name = "jsl_rt5682_mx98360", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1)), }, { .name = "jsl_rt5682_rt1015p", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1015P_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1)), }, { .name = "jsl_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0)), }, { + .name = "jsl_rt5650", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(0) | + SOF_RT5682_SSP_AMP(1)), + }, + { .name = "tgl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1124,8 +1009,6 @@ static const struct platform_device_id board_ids[] = { .name = "tgl_rt1011_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1011_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1135,8 +1018,6 @@ static const struct platform_device_id board_ids[] = { .name = "tgl_mx98373_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1146,8 +1027,6 @@ static const struct platform_device_id board_ids[] = { .name = "adl_mx98373_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1157,7 +1036,6 @@ static const struct platform_device_id board_ids[] = { .name = "adl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, @@ -1165,8 +1043,6 @@ static const struct platform_device_id board_ids[] = { .name = "adl_max98390_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98390_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1176,8 +1052,6 @@ static const struct platform_device_id board_ids[] = { .name = "adl_mx98360_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1195,8 +1069,6 @@ static const struct platform_device_id board_ids[] = { .name = "adl_rt1019_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1019_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1211,10 +1083,18 @@ static const struct platform_device_id board_ids[] = { SOF_HDMI_CAPTURE_SSP_MASK(0x5)), }, { + .name = "adl_rt5650", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(0) | + SOF_RT5682_SSP_AMP(1) | + SOF_RT5682_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, + { .name = "rpl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, @@ -1222,8 +1102,6 @@ static const struct platform_device_id board_ids[] = { .name = "rpl_mx98360_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1233,20 +1111,25 @@ static const struct platform_device_id board_ids[] = { .name = "rpl_rt1019_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1019_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | SOF_SSP_BT_OFFLOAD_PRESENT), }, { + .name = "rpl_rt5682_c1_h02", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(1) | + SOF_RT5682_NUM_HDMIDEV(3) | + /* SSP 0 and SSP 2 are used for HDMI IN */ + SOF_HDMI_CAPTURE_SSP_MASK(0x5)), + }, + { .name = "mtl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | - SOF_RT5682_NUM_HDMIDEV(4) | + SOF_RT5682_NUM_HDMIDEV(3) | SOF_BT_OFFLOAD_SSP(2) | SOF_SSP_BT_OFFLOAD_PRESENT), }, @@ -1254,28 +1137,16 @@ static const struct platform_device_id board_ids[] = { .name = "mtl_mx98360_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | - SOF_RT5682_NUM_HDMIDEV(4)), + SOF_RT5682_NUM_HDMIDEV(3)), }, { .name = "mtl_rt1019_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(2) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1019_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(0) | SOF_RT5682_NUM_HDMIDEV(3)), }, - { - .name = "jsl_rt5650", - .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | - SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT5682_SSP_AMP(1)), - }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); @@ -1297,6 +1168,7 @@ MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>"); MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON); diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 9ed572141f..1e788859c8 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -20,13 +20,6 @@ static int quirk_override = -1; module_param_named(quirk, quirk_override, int, 0444); MODULE_PARM_DESC(quirk, "Board-specific quirk override"); -#define INC_ID(BE, CPU, LINK) do { (BE)++; (CPU)++; (LINK)++; } while (0) - -#define SDW_MAX_LINKS 4 - -/* To store SDW Pin index for each SoundWire link */ -static unsigned int sdw_pin_index[SDW_MAX_LINKS]; - static void log_quirks(struct device *dev) { if (SOF_JACK_JDSRC(sof_sdw_quirk)) @@ -409,7 +402,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .callback = sof_sdw_quirk_cb, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"), + DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | RT711_JD2), @@ -503,13 +496,6 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { {} }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - static struct snd_soc_dai_link_component platform_component[] = { { /* name might be overridden during probe */ @@ -525,12 +511,12 @@ int sdw_startup(struct snd_pcm_substream *substream) int sdw_prepare(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sdw_stream_runtime *sdw_stream; struct snd_soc_dai *dai; /* Find stream from first CPU DAI */ - dai = asoc_rtd_to_cpu(rtd, 0); + dai = snd_soc_rtd_to_cpu(rtd, 0); sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); if (IS_ERR(sdw_stream)) { @@ -543,13 +529,13 @@ int sdw_prepare(struct snd_pcm_substream *substream) int sdw_trigger(struct snd_pcm_substream *substream, int cmd) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sdw_stream_runtime *sdw_stream; struct snd_soc_dai *dai; int ret; /* Find stream from first CPU DAI */ - dai = asoc_rtd_to_cpu(rtd, 0); + dai = snd_soc_rtd_to_cpu(rtd, 0); sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); if (IS_ERR(sdw_stream)) { @@ -583,7 +569,7 @@ int sdw_trigger(struct snd_pcm_substream *substream, int cmd) int sdw_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); int ch = params_channels(params); struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai; @@ -631,12 +617,12 @@ int sdw_hw_params(struct snd_pcm_substream *substream, int sdw_hw_free(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sdw_stream_runtime *sdw_stream; struct snd_soc_dai *dai; /* Find stream from first CPU DAI */ - dai = asoc_rtd_to_cpu(rtd, 0); + dai = snd_soc_rtd_to_cpu(rtd, 0); sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); if (IS_ERR(sdw_stream)) { @@ -940,6 +926,33 @@ static struct sof_sdw_codec_info codec_info_list[] = { .dai_num = 1, }, { + .part_id = 0x4243, + .codec_name = "cs42l43-codec", + .dais = { + { + .direction = {true, false}, + .dai_name = "cs42l43-dp5", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, + .init = sof_sdw_cs42l43_hs_init, + }, + { + .direction = {false, true}, + .dai_name = "cs42l43-dp1", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_cs42l43_dmic_init, + }, + { + .direction = {false, true}, + .dai_name = "cs42l43-dp2", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_UNUSED_DAI_ID, SDW_JACK_IN_DAI_ID}, + }, + }, + .dai_num = 3, + }, + { .part_id = 0xaaaa, /* generic codec mockup */ .version_id = 0, .dais = { @@ -1039,7 +1052,7 @@ static inline int find_codec_info_acpi(const u8 *acpi_id) */ static int get_dailink_info(struct device *dev, const struct snd_soc_acpi_link_adr *adr_link, - int *sdw_be_num, int *sdw_cpu_dai_num, int *codecs_num) + int *sdw_be_num, int *codecs_num) { bool group_visited[SDW_MAX_GROUPS]; bool no_aggregation; @@ -1047,7 +1060,6 @@ static int get_dailink_info(struct device *dev, int j; no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; - *sdw_cpu_dai_num = 0; *sdw_be_num = 0; if (!adr_link) @@ -1096,8 +1108,6 @@ static int get_dailink_info(struct device *dev, if (!codec_info->dais[j].direction[stream]) continue; - (*sdw_cpu_dai_num)++; - /* count BE for each non-aggregated slave or group */ if (!endpoint->aggregated || no_aggregation || !group_visited[endpoint->group_id]) @@ -1114,14 +1124,14 @@ static int get_dailink_info(struct device *dev, } static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, - int be_id, char *name, int playback, int capture, + int *be_id, char *name, int playback, int capture, struct snd_soc_dai_link_component *cpus, int cpus_num, struct snd_soc_dai_link_component *codecs, int codecs_num, int (*init)(struct snd_soc_pcm_runtime *rtd), const struct snd_soc_ops *ops) { - dev_dbg(dev, "create dai link %s, id %d\n", name, be_id); - dai_links->id = be_id; + dev_dbg(dev, "create dai link %s, id %d\n", name, *be_id); + dai_links->id = (*be_id)++; dai_links->name = name; dai_links->platforms = platform_component; dai_links->num_platforms = ARRAY_SIZE(platform_component); @@ -1136,6 +1146,31 @@ static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links dai_links->ops = ops; } +static int init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, + int *be_id, char *name, int playback, int capture, + const char *cpu_dai_name, + const char *codec_name, const char *codec_dai_name, + int (*init)(struct snd_soc_pcm_runtime *rtd), + const struct snd_soc_ops *ops) +{ + struct snd_soc_dai_link_component *dlc; + + /* Allocate two DLCs one for the CPU, one for the CODEC */ + dlc = devm_kcalloc(dev, 2, sizeof(*dlc), GFP_KERNEL); + if (!dlc || !name || !cpu_dai_name || !codec_name || !codec_dai_name) + return -ENOMEM; + + dlc[0].dai_name = cpu_dai_name; + + dlc[1].name = codec_name; + dlc[1].dai_name = codec_dai_name; + + init_dai_link(dev, dai_links, be_id, name, playback, capture, + &dlc[0], 1, &dlc[1], 1, init, ops); + + return 0; +} + static bool is_unique_device(const struct snd_soc_acpi_link_adr *adr_link, unsigned int sdw_version, unsigned int mfg_id, @@ -1329,11 +1364,9 @@ static void set_dailink_map(struct snd_soc_dai_link_codec_ch_map *sdw_codec_ch_m static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"}; static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, - struct snd_soc_dai_link *dai_links, - int sdw_be_num, int sdw_cpu_dai_num, - struct snd_soc_dai_link_component *cpus, + struct snd_soc_dai_link *dai_links, int sdw_be_num, const struct snd_soc_acpi_link_adr *adr_link, - int *cpu_id, struct snd_soc_codec_conf *codec_conf, + struct snd_soc_codec_conf *codec_conf, int codec_count, int *be_id, int *codec_conf_index, bool *ignore_pch_dmic, @@ -1341,12 +1374,14 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, int adr_index, int dai_index) { + struct mc_private *ctx = snd_soc_card_get_drvdata(card); struct device *dev = card->dev; const struct snd_soc_acpi_link_adr *adr_link_next; struct snd_soc_dai_link_component *codecs; + struct snd_soc_dai_link_component *cpus; struct sof_sdw_codec_info *codec_info; int cpu_dai_id[SDW_MAX_CPU_DAIS]; - int cpu_dai_num, cpu_dai_index; + int cpu_dai_num; unsigned int group_id; int codec_dlc_index = 0; int codec_index; @@ -1417,7 +1452,6 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, if (codec_info->ignore_pch_dmic) *ignore_pch_dmic = true; - cpu_dai_index = *cpu_id; for_each_pcm_streams(stream) { struct snd_soc_dai_link_codec_ch_map *sdw_codec_ch_maps; char *name, *cpu_name; @@ -1455,6 +1489,10 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, if (!name) return -ENOMEM; + cpus = devm_kcalloc(dev, cpu_dai_num, sizeof(*cpus), GFP_KERNEL); + if (!cpus) + return -ENOMEM; + /* * generate CPU DAI name base on the sdw link ID and * PIN ID with offset of 2 according to sdw dai driver. @@ -1462,17 +1500,11 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, for (k = 0; k < cpu_dai_num; k++) { cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SDW%d Pin%d", cpu_dai_id[k], - sdw_pin_index[cpu_dai_id[k]]++); + ctx->sdw_pin_index[cpu_dai_id[k]]++); if (!cpu_name) return -ENOMEM; - if (cpu_dai_index >= sdw_cpu_dai_num) { - dev_err(dev, "invalid cpu dai index %d\n", - cpu_dai_index); - return -EINVAL; - } - - cpus[cpu_dai_index++].dai_name = cpu_name; + cpus[k].dai_name = cpu_name; } /* @@ -1484,17 +1516,11 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, return -EINVAL; } - if (*cpu_id >= sdw_cpu_dai_num) { - dev_err(dev, "invalid cpu dai index %d\n", *cpu_id); - return -EINVAL; - } - playback = (stream == SNDRV_PCM_STREAM_PLAYBACK); capture = (stream == SNDRV_PCM_STREAM_CAPTURE); - init_dai_link(dev, dai_links + *link_index, (*be_id)++, name, - playback, capture, - cpus + *cpu_id, cpu_dai_num, - codecs, codec_num, + + init_dai_link(dev, dai_links + *link_index, be_id, name, + playback, capture, cpus, cpu_dai_num, codecs, codec_num, NULL, &sdw_ops); /* @@ -1511,27 +1537,20 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, dev_err(dev, "failed to init codec %d\n", codec_index); return ret; } - - *cpu_id += cpu_dai_num; } return 0; } -#define IDISP_CODEC_MASK 0x4 - static int sof_card_dai_links_create(struct snd_soc_card *card) { struct device *dev = card->dev; struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev); - int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, hdmi_num = 0, bt_num = 0; + int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, bt_num = 0; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai_link_component *idisp_components; - struct snd_soc_dai_link_component *ssp_components; struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; const struct snd_soc_acpi_link_adr *adr_link = mach_params->links; bool aggregation = !(sof_sdw_quirk & SOF_SDW_NO_AGGREGATION); - struct snd_soc_dai_link_component *cpus; struct snd_soc_codec_conf *codec_conf; bool append_dai_type = false; bool ignore_pch_dmic = false; @@ -1541,16 +1560,14 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) int ssp_codec_index, ssp_mask; struct snd_soc_dai_link *dai_links; int num_links, link_index = 0; - char *name, *cpu_name; - int total_cpu_dai_num; - int sdw_cpu_dai_num; + char *name, *cpu_dai_name; + char *codec_name, *codec_dai_name; int i, j, be_id = 0; int codec_index; - int cpu_id = 0; + int hdmi_num; int ret; - ret = get_dailink_info(dev, adr_link, &sdw_be_num, &sdw_cpu_dai_num, - &codec_conf_num); + ret = get_dailink_info(dev, adr_link, &sdw_be_num, &codec_conf_num); if (ret < 0) { dev_err(dev, "failed to get sdw link info %d\n", ret); return ret; @@ -1568,14 +1585,13 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) ssp_num = hweight_long(ssp_mask); } - if (mach_params->codec_mask & IDISP_CODEC_MASK) { - ctx->idisp_codec = true; + if (mach_params->codec_mask & IDISP_CODEC_MASK) + ctx->hdmi.idisp_codec = true; - if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) - hdmi_num = SOF_TGL_HDMI_COUNT; - else - hdmi_num = SOF_PRE_TGL_HDMI_COUNT; - } + if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) + hdmi_num = SOF_TGL_HDMI_COUNT; + else + hdmi_num = SOF_PRE_TGL_HDMI_COUNT; /* enable dmic01 & dmic16k */ if (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) @@ -1585,7 +1601,8 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) bt_num = 1; dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d, bt: %d\n", - sdw_be_num, ssp_num, dmic_num, hdmi_num, bt_num); + sdw_be_num, ssp_num, dmic_num, + ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num); /* allocate BE dailinks */ num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num; @@ -1593,12 +1610,6 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) if (!dai_links) return -ENOMEM; - /* allocated CPU DAIs */ - total_cpu_dai_num = sdw_cpu_dai_num + ssp_num + dmic_num + hdmi_num + bt_num; - cpus = devm_kcalloc(dev, total_cpu_dai_num, sizeof(*cpus), GFP_KERNEL); - if (!cpus) - return -ENOMEM; - /* allocate codec conf, will be populated when dailinks are created */ codec_conf = devm_kcalloc(dev, codec_conf_num, sizeof(*codec_conf), GFP_KERNEL); @@ -1610,7 +1621,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) goto SSP; for (i = 0; i < SDW_MAX_LINKS; i++) - sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE; + ctx->sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE; for (; adr_link->num_adr; adr_link++) { /* @@ -1660,8 +1671,7 @@ out: for (j = 0; j < codec_info_list[codec_index].dai_num ; j++) { ret = create_sdw_dailink(card, &link_index, dai_links, - sdw_be_num, sdw_cpu_dai_num, cpus, - adr_link, &cpu_id, + sdw_be_num, adr_link, codec_conf, codec_conf_num, &be_id, &codec_conf_index, &ignore_pch_dmic, append_dai_type, i, j); @@ -1684,49 +1694,32 @@ SSP: for (i = 0, j = 0; ssp_mask; i++, ssp_mask >>= 1) { struct sof_sdw_codec_info *info; int playback, capture; - char *codec_name; if (!(ssp_mask & 0x1)) continue; - name = devm_kasprintf(dev, GFP_KERNEL, - "SSP%d-Codec", i); - if (!name) - return -ENOMEM; - - cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i); - if (!cpu_name) - return -ENOMEM; - - ssp_components = devm_kzalloc(dev, sizeof(*ssp_components), - GFP_KERNEL); - if (!ssp_components) - return -ENOMEM; - info = &codec_info_list[ssp_codec_index]; + + name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", i); + cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i); codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d", info->acpi_id, j++); - if (!codec_name) - return -ENOMEM; - - ssp_components->name = codec_name; - /* TODO: support multi codec dai on SSP when it is needed */ - ssp_components->dai_name = info->dais[0].dai_name; - cpus[cpu_id].dai_name = cpu_name; playback = info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK]; capture = info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE]; - init_dai_link(dev, dai_links + link_index, be_id, name, - playback, capture, - cpus + cpu_id, 1, - ssp_components, 1, - NULL, info->ops); + + ret = init_simple_dai_link(dev, dai_links + link_index, &be_id, name, + playback, capture, cpu_dai_name, + codec_name, info->dais[0].dai_name, + NULL, info->ops); + if (ret) + return ret; ret = info->dais[0].init(card, NULL, dai_links + link_index, info, 0); if (ret < 0) return ret; - INC_ID(be_id, cpu_id, link_index); + link_index++; } DMIC: @@ -1736,64 +1729,50 @@ DMIC: dev_warn(dev, "Ignoring PCH DMIC\n"); goto HDMI; } - cpus[cpu_id].dai_name = "DMIC01 Pin"; - init_dai_link(dev, dai_links + link_index, be_id, "dmic01", - 0, 1, // DMIC only supports capture - cpus + cpu_id, 1, - dmic_component, 1, - sof_sdw_dmic_init, NULL); - INC_ID(be_id, cpu_id, link_index); - - cpus[cpu_id].dai_name = "DMIC16k Pin"; - init_dai_link(dev, dai_links + link_index, be_id, "dmic16k", - 0, 1, // DMIC only supports capture - cpus + cpu_id, 1, - dmic_component, 1, - /* don't call sof_sdw_dmic_init() twice */ - NULL, NULL); - INC_ID(be_id, cpu_id, link_index); + + ret = init_simple_dai_link(dev, dai_links + link_index, &be_id, "dmic01", + 0, 1, // DMIC only supports capture + "DMIC01 Pin", "dmic-codec", "dmic-hifi", + sof_sdw_dmic_init, NULL); + if (ret) + return ret; + + link_index++; + + ret = init_simple_dai_link(dev, dai_links + link_index, &be_id, "dmic16k", + 0, 1, // DMIC only supports capture + "DMIC16k Pin", "dmic-codec", "dmic-hifi", + /* don't call sof_sdw_dmic_init() twice */ + NULL, NULL); + if (ret) + return ret; + + link_index++; } HDMI: /* HDMI */ - if (hdmi_num > 0) { - idisp_components = devm_kcalloc(dev, hdmi_num, - sizeof(*idisp_components), - GFP_KERNEL); - if (!idisp_components) - return -ENOMEM; - } - for (i = 0; i < hdmi_num; i++) { - name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d", i + 1); - if (!name) - return -ENOMEM; + name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", i + 1); + cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", i + 1); - if (ctx->idisp_codec) { - idisp_components[i].name = "ehdaudio0D2"; - idisp_components[i].dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "intel-hdmi-hifi%d", - i + 1); - if (!idisp_components[i].dai_name) - return -ENOMEM; + if (ctx->hdmi.idisp_codec) { + codec_name = "ehdaudio0D2"; + codec_dai_name = devm_kasprintf(dev, GFP_KERNEL, + "intel-hdmi-hifi%d", i + 1); } else { - idisp_components[i] = asoc_dummy_dlc; + codec_name = "snd-soc-dummy"; + codec_dai_name = "snd-soc-dummy-dai"; } - cpu_name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d Pin", i + 1); - if (!cpu_name) - return -ENOMEM; + ret = init_simple_dai_link(dev, dai_links + link_index, &be_id, name, + 1, 0, // HDMI only supports playback + cpu_dai_name, codec_name, codec_dai_name, + i == 0 ? sof_sdw_hdmi_init : NULL, NULL); + if (ret) + return ret; - cpus[cpu_id].dai_name = cpu_name; - init_dai_link(dev, dai_links + link_index, be_id, name, - 1, 0, // HDMI only supports playback - cpus + cpu_id, 1, - idisp_components + i, 1, - sof_sdw_hdmi_init, NULL); - INC_ID(be_id, cpu_id, link_index); + link_index++; } if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) { @@ -1801,16 +1780,13 @@ HDMI: SOF_BT_OFFLOAD_SSP_SHIFT; name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); - if (!name) - return -ENOMEM; - - cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port); - if (!cpu_name) - return -ENOMEM; + cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port); - cpus[cpu_id].dai_name = cpu_name; - init_dai_link(dev, dai_links + link_index, be_id, name, 1, 1, - cpus + cpu_id, 1, &asoc_dummy_dlc, 1, NULL, NULL); + ret = init_simple_dai_link(dev, dai_links + link_index, &be_id, name, + 1, 1, cpu_dai_name, snd_soc_dummy_dlc.name, + snd_soc_dummy_dlc.dai_name, NULL, NULL); + if (ret) + return ret; } card->dai_link = dai_links; @@ -1837,7 +1813,7 @@ static int sof_sdw_card_late_probe(struct snd_soc_card *card) } } - if (ctx->idisp_codec) + if (ctx->hdmi.idisp_codec) ret = sof_sdw_hdmi_card_late_probe(card); return ret; @@ -1916,8 +1892,6 @@ static int mc_probe(struct platform_device *pdev) if (!ctx) return -ENOMEM; - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - snd_soc_card_set_drvdata(card, ctx); dmi_check_system(sof_sdw_quirk_table); diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index 2f4fe6bc3d..e6b98523b4 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -12,6 +12,7 @@ #include <linux/bits.h> #include <linux/types.h> #include <sound/soc.h> +#include "sof_hdmi_common.h" #define MAX_NO_PROPS 2 #define MAX_HDMI_NUM 4 @@ -24,6 +25,8 @@ #define SDW_MAX_CPU_DAIS 16 #define SDW_INTEL_BIDIR_PDI_BASE 2 +#define SDW_MAX_LINKS 4 + /* 8 combinations with 4 links + unused group 0 */ #define SDW_MAX_GROUPS 9 @@ -92,11 +95,12 @@ struct sof_sdw_codec_info { }; struct mc_private { - struct list_head hdmi_pcm_list; - bool idisp_codec; struct snd_soc_jack sdw_headset; + struct sof_hdmi_private hdmi; struct device *headset_codec_dev; /* only one headset per card */ struct device *amp_dev1, *amp_dev2; + /* To store SDW Pin index for each SoundWire link */ + unsigned int sdw_pin_index[SDW_MAX_LINKS]; }; extern unsigned long sof_sdw_quirk; @@ -206,6 +210,19 @@ int sof_sdw_cs42l42_init(struct snd_soc_card *card, struct sof_sdw_codec_info *info, bool playback); +/* CS42L43 support */ +int sof_sdw_cs42l43_hs_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + +int sof_sdw_cs42l43_dmic_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + /* CS AMP support */ int sof_sdw_cs_amp_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, diff --git a/sound/soc/intel/boards/sof_sdw_cs42l42.c b/sound/soc/intel/boards/sof_sdw_cs42l42.c index ad130d9134..436f41086d 100644 --- a/sound/soc/intel/boards/sof_sdw_cs42l42.c +++ b/sound/soc/intel/boards/sof_sdw_cs42l42.c @@ -50,7 +50,7 @@ static int cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_jack *jack; int ret; diff --git a/sound/soc/intel/boards/sof_sdw_cs42l43.c b/sound/soc/intel/boards/sof_sdw_cs42l43.c new file mode 100644 index 0000000000..360f11b72a --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_cs42l43.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Based on sof_sdw_rt5682.c +// Copyright (c) 2023 Intel Corporation + +/* + * sof_sdw_cs42l43 - Helpers to handle CS42L43 from generic machine driver + */ +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/input.h> +#include <sound/jack.h> +#include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_type.h> +#include <sound/cs42l43.h> +#include <sound/control.h> +#include <sound/soc.h> +#include <sound/soc-acpi.h> +#include <sound/soc-dapm.h> +#include "sof_sdw_common.h" + +static const struct snd_soc_dapm_widget cs42l43_hs_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_soc_dapm_route cs42l43_hs_map[] = { + { "Headphone", NULL, "cs42l43 AMP3_OUT" }, + { "Headphone", NULL, "cs42l43 AMP4_OUT" }, + { "cs42l43 ADC1_IN1_P", NULL, "Headset Mic" }, + { "cs42l43 ADC1_IN1_N", NULL, "Headset Mic" }, +}; + +static const struct snd_soc_dapm_widget cs42l43_dmic_widgets[] = { + SND_SOC_DAPM_MIC("DMIC", NULL), +}; + +static const struct snd_soc_dapm_route cs42l43_dmic_map[] = { + { "cs42l43 PDM1_DIN", NULL, "DMIC" }, + { "cs42l43 PDM2_DIN", NULL, "DMIC" }, +}; + +static struct snd_soc_jack_pin sof_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct mc_private *ctx = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &ctx->sdw_headset; + struct snd_soc_card *card = rtd->card; + int ret; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s hs:cs42l43", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_dapm_new_controls(&card->dapm, cs42l43_hs_widgets, + ARRAY_SIZE(cs42l43_hs_widgets)); + if (ret) { + dev_err(card->dev, "cs42l43 hs widgets addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, cs42l43_hs_map, + ARRAY_SIZE(cs42l43_hs_map)); + if (ret) { + dev_err(card->dev, "cs42l43 hs map addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_card_jack_new_pins(card, "Jack", + SND_JACK_MECHANICAL | SND_JACK_AVOUT | + SND_JACK_HEADSET | SND_JACK_LINEOUT | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3, + jack, sof_jack_pins, + ARRAY_SIZE(sof_jack_pins)); + if (ret) { + dev_err(card->dev, "Failed to create jack: %d\n", ret); + return ret; + } + + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + + ret = snd_soc_component_set_jack(component, jack, NULL); + if (ret) { + dev_err(card->dev, "Failed to register jack: %d\n", ret); + return ret; + } + + ret = snd_soc_component_set_sysclk(component, CS42L43_SYSCLK, CS42L43_SYSCLK_SDW, + 0, SND_SOC_CLOCK_IN); + if (ret) + dev_err(card->dev, "Failed to set sysclk: %d\n", ret); + + return ret; +} + +int sof_sdw_cs42l43_hs_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, + bool playback) +{ + /* + * No need to test if (!playback) like other codecs as cs42l43 uses separated dai for + * playback and capture, and sof_sdw_cs42l43_init is only linked to the playback dai. + */ + dai_links->init = cs42l43_hs_rtd_init; + + return 0; +} + +static int cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s mic:cs42l43-dmic", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_dapm_new_controls(&card->dapm, cs42l43_dmic_widgets, + ARRAY_SIZE(cs42l43_dmic_widgets)); + if (ret) { + dev_err(card->dev, "cs42l43 dmic widgets addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, cs42l43_dmic_map, + ARRAY_SIZE(cs42l43_dmic_map)); + if (ret) + dev_err(card->dev, "cs42l43 dmic map addition failed: %d\n", ret); + + return ret; +} + +int sof_sdw_cs42l43_dmic_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, + bool playback) +{ + dai_links->init = cs42l43_dmic_rtd_init; + + return 0; +} diff --git a/sound/soc/intel/boards/sof_sdw_hdmi.c b/sound/soc/intel/boards/sof_sdw_hdmi.c index d47d8bf528..f34fabdf9d 100644 --- a/sound/soc/intel/boards/sof_sdw_hdmi.c +++ b/sound/soc/intel/boards/sof_sdw_hdmi.c @@ -15,47 +15,25 @@ #include "sof_sdw_common.h" #include "hda_dsp_common.h" -struct hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct mc_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); - struct hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); - /* 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); + ctx->hdmi.hdmi_comp = dai->component; return 0; } -#define NAME_SIZE 32 int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card) { struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct hdmi_pcm *pcm; - struct snd_soc_component *component = NULL; - if (!ctx->idisp_codec) + if (!ctx->hdmi.idisp_codec) return 0; - if (list_empty(&ctx->hdmi_pcm_list)) + if (!ctx->hdmi.hdmi_comp) return -EINVAL; - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm, - head); - component = pcm->codec_dai->component; - - return hda_dsp_hdmi_build_controls(card, component); + return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp); } diff --git a/sound/soc/intel/boards/sof_sdw_maxim.c b/sound/soc/intel/boards/sof_sdw_maxim.c index 414c4d8dac..e36b8d8c70 100644 --- a/sound/soc/intel/boards/sof_sdw_maxim.c +++ b/sound/soc/intel/boards/sof_sdw_maxim.c @@ -64,7 +64,7 @@ static int spk_init(struct snd_soc_pcm_runtime *rtd) static int mx8373_enable_spk_pin(struct snd_pcm_substream *substream, bool enable) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai; int ret; @@ -74,7 +74,7 @@ static int mx8373_enable_spk_pin(struct snd_pcm_substream *substream, bool enabl if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) return 0; - cpu_dai = asoc_rtd_to_cpu(rtd, 0); + cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); for_each_rtd_codec_dais(rtd, j, codec_dai) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cpu_dai->component); diff --git a/sound/soc/intel/boards/sof_sdw_rt5682.c b/sound/soc/intel/boards/sof_sdw_rt5682.c index 3a9be82115..7b7c9def39 100644 --- a/sound/soc/intel/boards/sof_sdw_rt5682.c +++ b/sound/soc/intel/boards/sof_sdw_rt5682.c @@ -49,7 +49,7 @@ static int rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_jack *jack; int ret; diff --git a/sound/soc/intel/boards/sof_sdw_rt700.c b/sound/soc/intel/boards/sof_sdw_rt700.c index c93b1f5b94..a1714afe85 100644 --- a/sound/soc/intel/boards/sof_sdw_rt700.c +++ b/sound/soc/intel/boards/sof_sdw_rt700.c @@ -49,7 +49,7 @@ static int rt700_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_jack *jack; int ret; diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c index 2b05e2a707..38782fdfcf 100644 --- a/sound/soc/intel/boards/sof_sdw_rt711.c +++ b/sound/soc/intel/boards/sof_sdw_rt711.c @@ -73,7 +73,7 @@ static int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_jack *jack; int ret; diff --git a/sound/soc/intel/boards/sof_sdw_rt712_sdca.c b/sound/soc/intel/boards/sof_sdw_rt712_sdca.c index 84c8025d24..3092029419 100644 --- a/sound/soc/intel/boards/sof_sdw_rt712_sdca.c +++ b/sound/soc/intel/boards/sof_sdw_rt712_sdca.c @@ -80,10 +80,12 @@ int sof_sdw_rt712_spk_init(struct snd_soc_card *card, static int rt712_sdca_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = codec_dai->component; card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s mic:rt712-sdca-dmic", - card->components); + "%s mic:%s", + card->components, component->name_prefix); if (!card->components) return -ENOMEM; diff --git a/sound/soc/intel/boards/sof_sdw_rt_amp.c b/sound/soc/intel/boards/sof_sdw_rt_amp.c index 26bf9e0dd3..436975b6bd 100644 --- a/sound/soc/intel/boards/sof_sdw_rt_amp.c +++ b/sound/soc/intel/boards/sof_sdw_rt_amp.c @@ -251,9 +251,9 @@ static int all_spk_init(struct snd_soc_pcm_runtime *rtd) static int rt1308_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int clk_id, clk_freq, pll_out; int err; diff --git a/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c b/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c index 890517eb63..49a513399d 100644 --- a/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c +++ b/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c @@ -83,7 +83,7 @@ static int rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_jack *jack; int ret; diff --git a/sound/soc/intel/boards/sof_ssp_amp.c b/sound/soc/intel/boards/sof_ssp_amp.c index 5aa16fd393..137ba64254 100644 --- a/sound/soc/intel/boards/sof_ssp_amp.c +++ b/sound/soc/intel/boards/sof_ssp_amp.c @@ -17,12 +17,10 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/sof.h> -#include "../../codecs/hdac_hdmi.h" -#include "hda_dsp_common.h" +#include "sof_board_helpers.h" #include "sof_realtek_common.h" #include "sof_cirrus_common.h" - -#define NAME_SIZE 32 +#include "sof_ssp_common.h" /* SSP port ID for speaker amplifier */ #define SOF_AMPLIFIER_SSP(quirk) ((quirk) & GENMASK(3, 0)) @@ -59,26 +57,9 @@ #define SOF_BT_OFFLOAD_SSP(quirk) \ (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK) -/* Speaker amplifiers */ -#define SOF_RT1308_SPEAKER_AMP_PRESENT BIT(21) -#define SOF_CS35L41_SPEAKER_AMP_PRESENT BIT(22) - /* Default: SSP2 */ static unsigned long sof_ssp_amp_quirk = SOF_AMPLIFIER_SSP(2); -struct sof_hdmi_pcm { - struct list_head head; - struct snd_soc_jack sof_hdmi; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct sof_card_private { - struct list_head hdmi_pcm_list; - bool common_hdmi_codec_drv; - bool idisp_codec; -}; - static const struct dmi_system_id chromebook_platforms[] = { { .ident = "Google Chromebooks", @@ -89,66 +70,14 @@ static const struct dmi_system_id chromebook_platforms[] = { {}, }; -static const struct snd_soc_dapm_widget sof_ssp_amp_dapm_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - -static const struct snd_soc_dapm_route sof_ssp_amp_dapm_routes[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - static int sof_card_late_probe(struct snd_soc_card *card) { - struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component = NULL; - char jack_name[NAME_SIZE]; - struct sof_hdmi_pcm *pcm; - int err; - - if (!(sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT)) - return 0; - - /* HDMI is not supported by SOF on Baytrail/CherryTrail */ - if (!ctx->idisp_codec) - return 0; - - if (list_empty(&ctx->hdmi_pcm_list)) - return -EINVAL; - - if (ctx->common_hdmi_codec_drv) { - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, - head); - component = pcm->codec_dai->component; - return hda_dsp_hdmi_build_controls(card, component); - } - - 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, &pcm->sof_hdmi); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &pcm->sof_hdmi); - if (err < 0) - return err; - } - - return hdac_hdmi_jack_port_init(component, &card->dapm); + return sof_intel_board_card_late_probe(card); } static struct snd_soc_card sof_ssp_amp_card = { .name = "ssp_amp", .owner = THIS_MODULE, - .dapm_widgets = sof_ssp_amp_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(sof_ssp_amp_dapm_widgets), - .dapm_routes = sof_ssp_amp_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(sof_ssp_amp_dapm_routes), .fully_routed = true, .late_probe = sof_card_late_probe, }; @@ -160,44 +89,25 @@ static struct snd_soc_dai_link_component platform_component[] = { } }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - -static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) +/* BE ID defined in sof-tgl-rt1308-hdmi-ssp.m4 */ +#define HDMI_IN_BE_ID 0 +#define SPK_BE_ID 2 +#define DMIC01_BE_ID 3 +#define DMIC16K_BE_ID 4 +#define INTEL_HDMI_BE_ID 5 + +static struct snd_soc_dai_link * +sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type, + int ssp_codec, int dmic_be_num, int hdmi_num, + bool idisp_codec) { - struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); - struct sof_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 IDISP_CODEC_MASK 0x4 - -static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, - int ssp_codec, - int dmic_be_num, - int hdmi_num, - bool idisp_codec) -{ - struct snd_soc_dai_link_component *idisp_components; struct snd_soc_dai_link_component *cpus; struct snd_soc_dai_link *links; - int i, id = 0; + int i; + int id = 0; + int ret; + bool fixed_be = false; + int be_id; links = devm_kcalloc(dev, sof_ssp_amp_card.num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL); @@ -211,6 +121,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, int num_of_hdmi_ssp = (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_CAPTURE_SSP_MASK) >> SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT; + /* the topology supports HDMI-IN uses fixed BE ID for DAI links */ + fixed_be = true; + for (i = 1; i <= num_of_hdmi_ssp; i++) { int port = (i == 1 ? (sof_ssp_amp_quirk & SOF_HDMI_CAPTURE_1_SSP_MASK) >> SOF_HDMI_CAPTURE_1_SSP_SHIFT : @@ -225,8 +138,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-HDMI", port); if (!links[id].name) return NULL; - links[id].id = id; - links[id].codecs = &asoc_dummy_dlc; + links[id].id = fixed_be ? (HDMI_IN_BE_ID + i - 1) : id; + links[id].codecs = &snd_soc_dummy_dlc; links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); @@ -238,104 +151,72 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, } /* codec SSP */ - links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_codec); - if (!links[id].name) - return NULL; + if (amp_type != CODEC_NONE) { + links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_codec); + if (!links[id].name) + return NULL; + + links[id].id = fixed_be ? SPK_BE_ID : id; + + switch (amp_type) { + case CODEC_CS35L41: + cs35l41_set_dai_link(&links[id]); + break; + case CODEC_RT1308: + sof_rt1308_dai_link(&links[id]); + break; + default: + dev_err(dev, "invalid amp type %d\n", amp_type); + return NULL; + } - links[id].id = id; - if (sof_ssp_amp_quirk & SOF_RT1308_SPEAKER_AMP_PRESENT) { - sof_rt1308_dai_link(&links[id]); - } else if (sof_ssp_amp_quirk & SOF_CS35L41_SPEAKER_AMP_PRESENT) { - cs35l41_set_dai_link(&links[id]); - } - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].dpcm_playback = 1; - /* feedback from amplifier or firmware-generated echo reference */ - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; - links[id].cpus = &cpus[id]; - links[id].num_cpus = 1; - links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_codec); - if (!links[id].cpus->dai_name) - return NULL; + links[id].platforms = platform_component; + links[id].num_platforms = ARRAY_SIZE(platform_component); + links[id].dpcm_playback = 1; + /* feedback from amplifier or firmware-generated echo reference */ + links[id].dpcm_capture = 1; + links[id].no_pcm = 1; + links[id].cpus = &cpus[id]; + links[id].num_cpus = 1; + links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_codec); + if (!links[id].cpus->dai_name) + return NULL; - id++; + id++; + } /* dmic */ if (dmic_be_num > 0) { /* at least we have dmic01 */ - links[id].name = "dmic01"; - links[id].cpus = &cpus[id]; - links[id].cpus->dai_name = "DMIC01 Pin"; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[id + 1].name = "dmic16k"; - links[id + 1].cpus = &cpus[id + 1]; - links[id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } + be_id = fixed_be ? DMIC01_BE_ID : id; + ret = sof_intel_board_set_dmic_link(dev, &links[id], be_id, + SOF_DMIC_01); + if (ret) + return NULL; + + id++; } - for (i = 0; i < dmic_be_num; i++) { - links[id].id = id; - links[id].num_cpus = 1; - links[id].codecs = dmic_component; - links[id].num_codecs = ARRAY_SIZE(dmic_component); - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].ignore_suspend = 1; - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + be_id = fixed_be ? DMIC16K_BE_ID : id; + ret = sof_intel_board_set_dmic_link(dev, &links[id], be_id, + SOF_DMIC_16K); + if (ret) + return NULL; + id++; } /* HDMI playback */ - if (sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT) { - /* HDMI */ - if (hdmi_num > 0) { - idisp_components = devm_kcalloc(dev, - hdmi_num, - sizeof(struct snd_soc_dai_link_component), - GFP_KERNEL); - if (!idisp_components) - goto devm_err; - } - for (i = 1; i <= hdmi_num; i++) { - links[id].name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d", i); - if (!links[id].name) - goto devm_err; + for (i = 1; i <= hdmi_num; i++) { + be_id = fixed_be ? (INTEL_HDMI_BE_ID + i - 1) : id; + ret = sof_intel_board_set_intel_hdmi_link(dev, &links[id], be_id, + i, idisp_codec); + if (ret) + return NULL; - links[id].id = id; - links[id].cpus = &cpus[id]; - links[id].num_cpus = 1; - links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d Pin", i); - if (!links[id].cpus->dai_name) - goto devm_err; - - if (idisp_codec) { - idisp_components[i - 1].name = "ehdaudio0D2"; - idisp_components[i - 1].dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "intel-hdmi-hifi%d", - i); - if (!idisp_components[i - 1].dai_name) - goto devm_err; - } else { - idisp_components[i - 1] = asoc_dummy_dlc; - } - - links[id].codecs = &idisp_components[i - 1]; - links[id].num_codecs = 1; - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].init = sof_hdmi_init; - links[id].dpcm_playback = 1; - links[id].no_pcm = 1; - id++; - } + id++; } /* BT audio offload */ @@ -352,7 +233,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); if (!links[id].name) goto devm_err; - links[id].codecs = &asoc_dummy_dlc; + links[id].codecs = &snd_soc_dummy_dlc; links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); @@ -370,10 +251,9 @@ devm_err: static int sof_ssp_amp_probe(struct platform_device *pdev) { + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_dai_link *dai_links; - struct snd_soc_acpi_mach *mach; struct sof_card_private *ctx; - int dmic_be_num = 0, hdmi_num = 0; int ret, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -383,49 +263,66 @@ static int sof_ssp_amp_probe(struct platform_device *pdev) if (pdev->id_entry && pdev->id_entry->driver_data) sof_ssp_amp_quirk = (unsigned long)pdev->id_entry->driver_data; - mach = pdev->dev.platform_data; + ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); if (dmi_check_system(chromebook_platforms) || mach->mach_params.dmic_num > 0) - dmic_be_num = 2; + ctx->dmic_be_num = 2; + else + ctx->dmic_be_num = 0; ssp_codec = sof_ssp_amp_quirk & SOF_AMPLIFIER_SSP_MASK; /* set number of dai links */ - sof_ssp_amp_card.num_links = 1 + dmic_be_num; + sof_ssp_amp_card.num_links = ctx->dmic_be_num; + + if (ctx->amp_type != CODEC_NONE) + sof_ssp_amp_card.num_links++; if (sof_ssp_amp_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT) sof_ssp_amp_card.num_links += (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_CAPTURE_SSP_MASK) >> SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT; if (sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT) { - hdmi_num = (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_PLAYBACK_MASK) >> + ctx->hdmi_num = (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_PLAYBACK_MASK) >> SOF_NO_OF_HDMI_PLAYBACK_SHIFT; /* default number of HDMI DAI's */ - if (!hdmi_num) - hdmi_num = 3; + if (!ctx->hdmi_num) + ctx->hdmi_num = 3; if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) - ctx->idisp_codec = true; + ctx->hdmi.idisp_codec = true; - sof_ssp_amp_card.num_links += hdmi_num; + sof_ssp_amp_card.num_links += ctx->hdmi_num; + } else { + ctx->hdmi_num = 0; } if (sof_ssp_amp_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) sof_ssp_amp_card.num_links++; - dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, dmic_be_num, hdmi_num, ctx->idisp_codec); + dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type, + ssp_codec, ctx->dmic_be_num, + ctx->hdmi_num, + ctx->hdmi.idisp_codec); if (!dai_links) return -ENOMEM; sof_ssp_amp_card.dai_link = dai_links; /* update codec_conf */ - if (sof_ssp_amp_quirk & SOF_CS35L41_SPEAKER_AMP_PRESENT) { + switch (ctx->amp_type) { + case CODEC_CS35L41: cs35l41_set_codec_conf(&sof_ssp_amp_card); + break; + case CODEC_NONE: + case CODEC_RT1308: + /* no codec conf required */ + break; + default: + dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type); + return -EINVAL; } - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - sof_ssp_amp_card.dev = &pdev->dev; /* set platform name for each dailink */ @@ -434,8 +331,6 @@ static int sof_ssp_amp_probe(struct platform_device *pdev) if (ret) return ret; - ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; - snd_soc_card_set_drvdata(&sof_ssp_amp_card, ctx); return devm_snd_soc_register_card(&pdev->dev, &sof_ssp_amp_card); @@ -451,8 +346,7 @@ static const struct platform_device_id board_ids[] = { SOF_NO_OF_HDMI_CAPTURE_SSP(2) | SOF_HDMI_CAPTURE_1_SSP(1) | SOF_HDMI_CAPTURE_2_SSP(5) | - SOF_SSP_HDMI_CAPTURE_PRESENT | - SOF_RT1308_SPEAKER_AMP_PRESENT), + SOF_SSP_HDMI_CAPTURE_PRESENT), }, { .name = "adl_cs35l41", @@ -460,8 +354,7 @@ static const struct platform_device_id board_ids[] = { SOF_NO_OF_HDMI_PLAYBACK(4) | SOF_HDMI_PLAYBACK_PRESENT | SOF_BT_OFFLOAD_SSP(2) | - SOF_SSP_BT_OFFLOAD_PRESENT | - SOF_CS35L41_SPEAKER_AMP_PRESENT), + SOF_SSP_BT_OFFLOAD_PRESENT), }, { .name = "adl_lt6911_hdmi_ssp", @@ -481,6 +374,15 @@ static const struct platform_device_id board_ids[] = { SOF_NO_OF_HDMI_PLAYBACK(3) | SOF_HDMI_PLAYBACK_PRESENT), }, + { + .name = "mtl_lt6911_hdmi_ssp", + .driver_data = (kernel_ulong_t)(SOF_NO_OF_HDMI_CAPTURE_SSP(2) | + SOF_HDMI_CAPTURE_1_SSP(0) | + SOF_HDMI_CAPTURE_2_SSP(2) | + SOF_SSP_HDMI_CAPTURE_PRESENT | + SOF_NO_OF_HDMI_PLAYBACK(3) | + SOF_HDMI_PLAYBACK_PRESENT), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); @@ -499,6 +401,7 @@ MODULE_DESCRIPTION("ASoC Intel(R) SOF Amplifier Machine driver"); MODULE_AUTHOR("Balamurugan C <balamurugan.c@intel.com>"); MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_CIRRUS_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON); diff --git a/sound/soc/intel/boards/sof_ssp_common.c b/sound/soc/intel/boards/sof_ssp_common.c new file mode 100644 index 0000000000..41a258e45a --- /dev/null +++ b/sound/soc/intel/boards/sof_ssp_common.c @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. + +#include <linux/device.h> +#include <sound/soc-acpi.h> +#include "sof_ssp_common.h" + +/* + * Codec probe function + */ +#define CODEC_MAP_ENTRY(n, h, t) \ + { \ + .name = n, \ + .acpi_hid = h, \ + .codec_type = t, \ + } + +struct codec_map { + const char *name; + const char *acpi_hid; + enum sof_ssp_codec codec_type; +}; + +static const struct codec_map codecs[] = { + /* Cirrus Logic */ + CODEC_MAP_ENTRY("CS42L42", CS42L42_ACPI_HID, CODEC_CS42L42), + + /* Dialog */ + CODEC_MAP_ENTRY("DA7219", DA7219_ACPI_HID, CODEC_DA7219), + + /* Everest */ + CODEC_MAP_ENTRY("ES8316", ES8316_ACPI_HID, CODEC_ES8316), + CODEC_MAP_ENTRY("ES8326", ES8326_ACPI_HID, CODEC_ES8326), + CODEC_MAP_ENTRY("ES8336", ES8336_ACPI_HID, CODEC_ES8336), + + /* Nuvoton */ + CODEC_MAP_ENTRY("NAU8825", NAU8825_ACPI_HID, CODEC_NAU8825), + + /* Realtek */ + CODEC_MAP_ENTRY("RT5650", RT5650_ACPI_HID, CODEC_RT5650), + CODEC_MAP_ENTRY("RT5682", RT5682_ACPI_HID, CODEC_RT5682), + CODEC_MAP_ENTRY("RT5682S", RT5682S_ACPI_HID, CODEC_RT5682S), +}; + +static const struct codec_map amps[] = { + /* Cirrus Logic */ + CODEC_MAP_ENTRY("CS35L41", CS35L41_ACPI_HID, CODEC_CS35L41), + + /* Maxim */ + CODEC_MAP_ENTRY("MAX98357A", MAX_98357A_ACPI_HID, CODEC_MAX98357A), + CODEC_MAP_ENTRY("MAX98360A", MAX_98360A_ACPI_HID, CODEC_MAX98360A), + CODEC_MAP_ENTRY("MAX98373", MAX_98373_ACPI_HID, CODEC_MAX98373), + CODEC_MAP_ENTRY("MAX98390", MAX_98390_ACPI_HID, CODEC_MAX98390), + + /* Nuvoton */ + CODEC_MAP_ENTRY("NAU8318", NAU8318_ACPI_HID, CODEC_NAU8318), + + /* Realtek */ + CODEC_MAP_ENTRY("RT1011", RT1011_ACPI_HID, CODEC_RT1011), + CODEC_MAP_ENTRY("RT1015", RT1015_ACPI_HID, CODEC_RT1015), + CODEC_MAP_ENTRY("RT1015P", RT1015P_ACPI_HID, CODEC_RT1015P), + CODEC_MAP_ENTRY("RT1019P", RT1019P_ACPI_HID, CODEC_RT1019P), + CODEC_MAP_ENTRY("RT1308", RT1308_ACPI_HID, CODEC_RT1308), +}; + +enum sof_ssp_codec sof_ssp_detect_codec_type(struct device *dev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(codecs); i++) { + if (!acpi_dev_present(codecs[i].acpi_hid, NULL, -1)) + continue; + + dev_dbg(dev, "codec %s found\n", codecs[i].name); + return codecs[i].codec_type; + } + + return CODEC_NONE; +} +EXPORT_SYMBOL_NS(sof_ssp_detect_codec_type, SND_SOC_INTEL_SOF_SSP_COMMON); + +enum sof_ssp_codec sof_ssp_detect_amp_type(struct device *dev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(amps); i++) { + if (!acpi_dev_present(amps[i].acpi_hid, NULL, -1)) + continue; + + dev_dbg(dev, "amp %s found\n", amps[i].name); + return amps[i].codec_type; + } + + return CODEC_NONE; +} +EXPORT_SYMBOL_NS(sof_ssp_detect_amp_type, SND_SOC_INTEL_SOF_SSP_COMMON); + +MODULE_DESCRIPTION("ASoC Intel SOF Common Machine Driver Helpers"); +MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/boards/sof_ssp_common.h b/sound/soc/intel/boards/sof_ssp_common.h new file mode 100644 index 0000000000..e3fd6fb1db --- /dev/null +++ b/sound/soc/intel/boards/sof_ssp_common.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2023 Intel Corporation. + */ + +#ifndef __SOF_SSP_COMMON_H +#define __SOF_SSP_COMMON_H + +/* Cirrus Logic */ +#define CS35L41_ACPI_HID "CSC3541" +#define CS42L42_ACPI_HID "10134242" + +/* Dialog */ +#define DA7219_ACPI_HID "DLGS7219" + +/* Everest */ +#define ES8316_ACPI_HID "ESSX8316" +#define ES8326_ACPI_HID "ESSX8326" +#define ES8336_ACPI_HID "ESSX8336" + +#define MAX_98357A_ACPI_HID "MX98357A" +#define MAX_98360A_ACPI_HID "MX98360A" +#define MAX_98373_ACPI_HID "MX98373" +#define MAX_98390_ACPI_HID "MX98390" + +/* Nuvoton */ +#define NAU8318_ACPI_HID "NVTN2012" +#define NAU8825_ACPI_HID "10508825" + +/* Realtek */ +#define RT1011_ACPI_HID "10EC1011" +#define RT1015_ACPI_HID "10EC1015" +#define RT1015P_ACPI_HID "RTL1015" +#define RT1019P_ACPI_HID "RTL1019" +#define RT1308_ACPI_HID "10EC1308" +#define RT5650_ACPI_HID "10EC5650" +#define RT5682_ACPI_HID "10EC5682" +#define RT5682S_ACPI_HID "RTL5682" + +enum sof_ssp_codec { + CODEC_NONE, + + /* headphone codec */ + CODEC_CS42L42, + CODEC_DA7219, + CODEC_ES8316, + CODEC_ES8326, + CODEC_ES8336, + CODEC_NAU8825, + CODEC_RT5650, + CODEC_RT5682, + CODEC_RT5682S, + + /* speaker amplifier */ + CODEC_CS35L41, + CODEC_MAX98357A, + CODEC_MAX98360A, + CODEC_MAX98373, + CODEC_MAX98390, + CODEC_NAU8318, + CODEC_RT1011, + CODEC_RT1015, + CODEC_RT1015P, + CODEC_RT1019P, + CODEC_RT1308, +}; + +enum sof_ssp_codec sof_ssp_detect_codec_type(struct device *dev); +enum sof_ssp_codec sof_ssp_detect_amp_type(struct device *dev); + +#endif /* __SOF_SSP_COMMON_H */ diff --git a/sound/soc/intel/boards/sof_wm8804.c b/sound/soc/intel/boards/sof_wm8804.c index 17224d26d9..4cb0d463bf 100644 --- a/sound/soc/intel/boards/sof_wm8804.c +++ b/sound/soc/intel/boards/sof_wm8804.c @@ -49,9 +49,9 @@ static const struct dmi_system_id sof_wm8804_quirk_table[] = { static int sof_wm8804_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *codec = codec_dai->component; const int sysclk = 27000000; /* This is fixed on this board */ int samplerate; |