diff options
Diffstat (limited to 'sound/soc/intel/boards')
72 files changed, 2519 insertions, 14976 deletions
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 18ac3ce0752e..2df7afa2f469 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -41,9 +41,6 @@ config SND_SOC_INTEL_SOF_CIRRUS_COMMON config SND_SOC_INTEL_SOF_NUVOTON_COMMON tristate -config SND_SOC_INTEL_SOF_SSP_COMMON - tristate - config SND_SOC_INTEL_SOF_BOARD_HELPERS tristate @@ -255,94 +252,6 @@ config SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH endif ## SND_SST_ATOM_HIFI2_PLATFORM -if SND_SOC_INTEL_SKL - -config SND_SOC_INTEL_SKL_RT286_MACH - tristate "SKL with RT286 I2S mode" - depends on I2C && ACPI - depends on MFD_INTEL_LPSS || COMPILE_TEST - select SND_SOC_RT286 - select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI - help - This adds support for ASoC machine driver for Skylake platforms - with RT286 I2S audio codec. - Say Y or m if you have such a device. - If unsure select "N". - -config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH - tristate "SKL with NAU88L25 and SSM4567 in I2S Mode" - depends on I2C && ACPI - depends on MFD_INTEL_LPSS || COMPILE_TEST - select SND_SOC_NAU8825 - select SND_SOC_SSM4567 - select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI - help - This adds support for ASoC Onboard Codec I2S machine driver. This will - create an alsa sound card for NAU88L25 + SSM4567. - Say Y or m if you have such a device. This is a recommended option. - If unsure select "N". - -config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH - tristate "SKL with NAU88L25 and MAX98357A in I2S Mode" - depends on I2C && ACPI - depends on MFD_INTEL_LPSS || COMPILE_TEST - select SND_SOC_NAU8825 - select SND_SOC_MAX98357A - select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI - help - This adds support for ASoC Onboard Codec I2S machine driver. This will - create an alsa sound card for NAU88L25 + MAX98357A. - Say Y or m if you have such a device. This is a recommended option. - If unsure select "N". - -endif ## SND_SOC_INTEL_SKL - -config SND_SOC_INTEL_DA7219_MAX98357A_GENERIC - tristate - select SND_SOC_DA7219 - select SND_SOC_MAX98357A - select SND_SOC_MAX98390 - select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI - select SND_SOC_INTEL_HDA_DSP_COMMON - -config SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON - tristate - select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC - -if SND_SOC_INTEL_APL - -config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH - tristate "Broxton with DA7219 and MAX98357A/MAX98390 in I2S Mode" - depends on I2C && ACPI - depends on MFD_INTEL_LPSS || COMPILE_TEST - depends on SND_HDA_CODEC_HDMI - select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON - help - This adds support for ASoC machine driver for Broxton-P platforms - with DA7219 + MAX98357A/MAX98390 I2S audio codec. - Say Y or m if you have such a device. This is a recommended option. - If unsure select "N". - -config SND_SOC_INTEL_BXT_RT298_MACH - tristate "Broxton with RT298 I2S mode" - depends on I2C && ACPI - depends on MFD_INTEL_LPSS || COMPILE_TEST - select SND_SOC_RT298 - select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI - select SND_SOC_INTEL_HDA_DSP_COMMON - help - This adds support for ASoC machine driver for Broxton platforms - with RT286 I2S audio codec. - Say Y or m if you have such a device. This is a recommended option. - If unsure select "N". - -endif ## SND_SOC_INTEL_APL - if SND_SOC_SOF_APOLLOLAKE config SND_SOC_INTEL_SOF_WM8804_MACH @@ -359,119 +268,37 @@ config SND_SOC_INTEL_SOF_WM8804_MACH endif ## SND_SOC_SOF_APOLLOLAKE -if SND_SOC_INTEL_KBL - -config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH - tristate "KBL with RT5663 and MAX98927 in I2S Mode" - depends on I2C && ACPI - depends on MFD_INTEL_LPSS || COMPILE_TEST - select SND_SOC_RT5663 - select SND_SOC_MAX98927 - select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI - select SND_SOC_INTEL_SKYLAKE_SSP_CLK - help - This adds support for ASoC Onboard Codec I2S machine driver. This will - create an alsa sound card for RT5663 + MAX98927. - Say Y or m if you have such a device. This is a recommended option. - If unsure select "N". - -config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH - tristate "KBL with RT5663, RT5514 and MAX98927 in I2S Mode" - depends on I2C && ACPI - depends on MFD_INTEL_LPSS || COMPILE_TEST - depends on SPI - select SND_SOC_RT5663 - select SND_SOC_RT5514 - select SND_SOC_RT5514_SPI - select SND_SOC_MAX98927 - select SND_SOC_HDAC_HDMI - select SND_SOC_INTEL_SKYLAKE_SSP_CLK - help - This adds support for ASoC Onboard Codec I2S machine driver. This will - create an alsa sound card for RT5663 + RT5514 + MAX98927. - Say Y or m if you have such a device. This is a recommended option. - If unsure select "N". - -config SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH - tristate "KBL with DA7219 and MAX98357A in I2S Mode" - depends on I2C && ACPI - depends on MFD_INTEL_LPSS || COMPILE_TEST - select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC - help - This adds support for ASoC Onboard Codec I2S machine driver. This will - create an alsa sound card for DA7219 + MAX98357A I2S audio codec. - Say Y if you have such a device. - -config SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH - tristate "KBL with DA7219 and MAX98927 in I2S Mode" - depends on I2C && ACPI - depends on MFD_INTEL_LPSS || COMPILE_TEST - select SND_SOC_DA7219 - select SND_SOC_MAX98927 - select SND_SOC_MAX98373_I2C - select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI - help - This adds support for ASoC Onboard Codec I2S machine driver. This will - create an alsa sound card for DA7219 + MAX98927 I2S audio codec. - Say Y if you have such a device. - If unsure select "N". - -config SND_SOC_INTEL_KBL_RT5660_MACH - tristate "KBL with RT5660 in I2S Mode" - depends on I2C && ACPI - depends on MFD_INTEL_LPSS || COMPILE_TEST - depends on GPIOLIB || COMPILE_TEST - select SND_SOC_RT5660 - select SND_SOC_HDAC_HDMI - help - This adds support for ASoC Onboard Codec I2S machine driver. This will - create an alsa sound card for RT5660 I2S audio codec. - Say Y if you have such a device. - -endif ## SND_SOC_INTEL_KBL - if SND_SOC_SOF_GEMINILAKE config SND_SOC_INTEL_GLK_DA7219_MAX98357A_MACH tristate "GLK with DA7219 and MAX98357A 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_BXT_DA7219_MAX98357A_COMMON + imply SND_SOC_INTEL_SOF_DA7219_MACH help This adds support for ASoC machine driver for Geminilake platforms - with DA7219 + MAX98357A I2S audio codec. + with DA7219 + MAX98357A I2S audio codec. This option is deprecated + and please use SND_SOC_INTEL_SOF_DA7219_MACH instead. Say Y or m if you have such a device. This is a recommended option. If unsure select "N". config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH tristate "GLK with RT5682 and MAX98357A 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_RT5682_I2C - select SND_SOC_RT5682S - select SND_SOC_MAX98357A - select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI - select SND_SOC_INTEL_HDA_DSP_COMMON + imply SND_SOC_INTEL_SOF_RT5682_MACH help This adds support for ASoC machine driver for Geminilake platforms - with RT5682 + MAX98357A I2S audio codec. + with RT5682 + MAX98357A I2S audio codec. This option is deprecated + and please use SND_SOC_INTEL_SOF_RT5682_MACH instead. Say Y if you have such a device. If unsure select "N". endif ## SND_SOC_SOF_GEMINILAKE -if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC || SND_SOC_SOF_HDA_AUDIO_CODEC +if SND_SOC_SOF_HDA_AUDIO_CODEC config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH tristate "Skylake+ with HDA Codecs" depends on SND_HDA_CODEC_HDMI - select SND_SOC_HDAC_HDMI select SND_SOC_INTEL_HDA_DSP_COMMON + select SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_DMIC # SND_SOC_HDAC_HDA is already selected help @@ -481,7 +308,7 @@ config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH Say Y or m if you have such a device. This is a recommended option. If unsure select "N". -endif ## SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC || SND_SOC_SOF_HDA_AUDIO_CODEC +endif ## SND_SOC_SOF_HDA_AUDIO_CODEC if SND_SOC_SOF_HDA_LINK || SND_SOC_SOF_BAYTRAIL config SND_SOC_INTEL_SOF_RT5682_MACH @@ -490,6 +317,7 @@ config SND_SOC_INTEL_SOF_RT5682_MACH depends on ((SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC) &&\ (MFD_INTEL_LPSS || COMPILE_TEST)) ||\ (SND_SOC_SOF_BAYTRAIL && (X86_INTEL_LPSS || COMPILE_TEST)) + select SND_SOC_MAX98357A select SND_SOC_MAX98373_I2C select SND_SOC_MAX98390 select SND_SOC_RT1011 @@ -503,7 +331,7 @@ config SND_SOC_INTEL_SOF_RT5682_MACH 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 + select SND_SOC_ACPI_INTEL_MATCH help This adds support for ASoC machine driver for SOF platforms with rt5650 or rt5682 codec. @@ -521,7 +349,7 @@ config SND_SOC_INTEL_SOF_CS42L42_MACH 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 + select SND_SOC_ACPI_INTEL_MATCH help This adds support for ASoC machine driver for SOF platforms with cs42l42 codec. @@ -574,7 +402,7 @@ config SND_SOC_INTEL_SOF_NAU8825_MACH 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 + select SND_SOC_ACPI_INTEL_MATCH help This adds support for ASoC machine driver for SOF platforms with nau8825 codec. @@ -587,28 +415,21 @@ if (SND_SOC_SOF_COMETLAKE && SND_SOC_SOF_HDA_LINK) config SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH tristate "CML_LP with DA7219 and MAX98357A in I2S Mode" - depends on I2C && ACPI - depends on MFD_INTEL_LPSS || COMPILE_TEST - select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON + imply SND_SOC_INTEL_SOF_DA7219_MACH help This adds support for ASoC machine driver for Cometlake platforms - with DA7219 + MAX98357A I2S audio codec. + with DA7219 + MAX98357A I2S audio codec. This option is deprecated + and please use SND_SOC_INTEL_SOF_DA7219_MACH instead. Say Y or m if you have such a device. This is a recommended option. If unsure select "N". config SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH tristate "CML with RT1011 and RT5682 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_RT1011 - select SND_SOC_RT5682_I2C - select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI - select SND_SOC_INTEL_HDA_DSP_COMMON + imply SND_SOC_INTEL_SOF_RT5682_MACH help This adds support for ASoC machine driver for SOF platform with - RT1011 + RT5682 I2S codec. + RT1011 + RT5682 I2S codec. This option is deprecated and please used + SND_SOC_INTEL_SOF_RT5682_MACH instead. Say Y if you have such a device. If unsure select "N". @@ -623,9 +444,11 @@ config SND_SOC_INTEL_SOF_DA7219_MACH select SND_SOC_DA7219 select SND_SOC_MAX98357A select SND_SOC_MAX98373_I2C + select SND_SOC_MAX98390 select SND_SOC_DMIC + select SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_INTEL_SOF_MAXIM_COMMON - select SND_SOC_INTEL_SOF_SSP_COMMON + select SND_SOC_ACPI_INTEL_MATCH help This adds support for ASoC machine driver for SOF platforms with Dialog DA7219 I2S audio codec. @@ -645,7 +468,7 @@ config SND_SOC_INTEL_SOF_SSP_AMP_MACH 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 + select SND_SOC_ACPI_INTEL_MATCH help This adds support for ASoC machine driver for SOF platforms with RT1308/CS35L41 I2S audio codec. @@ -673,11 +496,11 @@ if SND_SOC_SOF_INTEL_SOUNDWIRE config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH tristate "SoundWire generic machine driver" - depends on I2C && ACPI + depends on I2C && SPI_MASTER && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES || COMPILE_TEST depends on SOUNDWIRE - select SND_SOC_INTEL_SOF_BOARD_HELPERS + select SND_SOC_SDW_UTILS select SND_SOC_MAX98363 select SND_SOC_MAX98373_I2C select SND_SOC_MAX98373_SDW @@ -688,21 +511,25 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH select SND_SOC_RT712_SDCA_DMIC_SDW select SND_SOC_RT715_SDW select SND_SOC_RT715_SDCA_SDW + select SND_SOC_RT721_SDCA_SDW select SND_SOC_RT722_SDCA_SDW select SND_SOC_RT1308_SDW select SND_SOC_RT1308 select SND_SOC_RT1316_SDW select SND_SOC_RT1318_SDW + select SND_SOC_RT1320_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 PINCTRL_CS42L43 + select SPI_CS42L43 + select SND_SOC_CS35L56_SPI select SND_SOC_CS35L56_SDW select SND_SOC_DMIC select SND_SOC_INTEL_HDA_DSP_COMMON - select SND_SOC_INTEL_SOF_MAXIM_COMMON imply SND_SOC_SDW_MOCKUP help Add support for Intel SoundWire-based platforms connected to diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index bbf796a5f7ba..fcd517d6c279 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -1,50 +1,30 @@ # SPDX-License-Identifier: GPL-2.0-only -snd-soc-hsw-rt5640-objs := hsw_rt5640.o -snd-soc-sst-bdw-rt5650-mach-objs := bdw-rt5650.o -snd-soc-sst-bdw-rt5677-mach-objs := bdw-rt5677.o -snd-soc-bdw-rt286-objs := bdw_rt286.o -snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o -snd-soc-sst-bxt-rt298-objs := bxt_rt298.o -snd-soc-sst-sof-pcm512x-objs := sof_pcm512x.o -snd-soc-sst-sof-wm8804-objs := sof_wm8804.o -snd-soc-sst-glk-rt5682_max98357a-objs := glk_rt5682_max98357a.o -snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o -snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o -snd-soc-sst-bytcr-wm5102-objs := bytcr_wm5102.o -snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o -snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o -snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o -snd-soc-sst-cht-bsw-nau8824-objs := cht_bsw_nau8824.o -snd-soc-sst-byt-cht-cx2072x-objs := bytcht_cx2072x.o -snd-soc-sst-byt-cht-da7213-objs := bytcht_da7213.o -snd-soc-sst-byt-cht-es8316-objs := bytcht_es8316.o -snd-soc-sst-byt-cht-nocodec-objs := bytcht_nocodec.o -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 -snd-soc-kbl_rt5663_max98927-objs := kbl_rt5663_max98927.o -snd-soc-kbl_rt5663_rt5514_max98927-objs := kbl_rt5663_rt5514_max98927.o -snd-soc-kbl_rt5660-objs := kbl_rt5660.o -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-ehl-rt5660-objs := ehl_rt5660.o -snd-soc-sof-ssp-amp-objs := sof_ssp_amp.o -snd-soc-sof-sdw-objs += sof_sdw.o \ - sof_sdw_maxim.o sof_sdw_rt_amp.o \ - sof_sdw_rt5682.o sof_sdw_rt700.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_rt722_sdca.o \ - sof_sdw_cs42l42.o sof_sdw_cs42l43.o \ - sof_sdw_cs_amp.o \ - sof_sdw_dmic.o \ +snd-soc-hsw-rt5640-y := hsw_rt5640.o +snd-soc-sst-bdw-rt5650-mach-y := bdw-rt5650.o +snd-soc-sst-bdw-rt5677-mach-y := bdw-rt5677.o +snd-soc-bdw-rt286-y := bdw_rt286.o +snd-soc-sst-sof-pcm512x-y := sof_pcm512x.o +snd-soc-sst-sof-wm8804-y := sof_wm8804.o +snd-soc-sst-bytcr-rt5640-y := bytcr_rt5640.o +snd-soc-sst-bytcr-rt5651-y := bytcr_rt5651.o +snd-soc-sst-bytcr-wm5102-y := bytcr_wm5102.o +snd-soc-sst-cht-bsw-rt5672-y := cht_bsw_rt5672.o +snd-soc-sst-cht-bsw-rt5645-y := cht_bsw_rt5645.o +snd-soc-sst-cht-bsw-max98090_ti-y := cht_bsw_max98090_ti.o +snd-soc-sst-cht-bsw-nau8824-y := cht_bsw_nau8824.o +snd-soc-sst-byt-cht-cx2072x-y := bytcht_cx2072x.o +snd-soc-sst-byt-cht-da7213-y := bytcht_da7213.o +snd-soc-sst-byt-cht-es8316-y := bytcht_es8316.o +snd-soc-sst-byt-cht-nocodec-y := bytcht_nocodec.o +snd-soc-sof_rt5682-y := sof_rt5682.o +snd-soc-sof_cs42l42-y := sof_cs42l42.o +snd-soc-sof_es8336-y := sof_es8336.o +snd-soc-sof_nau8825-y := sof_nau8825.o +snd-soc-sof_da7219-y := sof_da7219.o +snd-soc-skl_hda_dsp-y := skl_hda_dsp_generic.o +snd-soc-ehl-rt5660-y := ehl_rt5660.o +snd-soc-sof-ssp-amp-y := sof_ssp_amp.o +snd-soc-sof-sdw-y += sof_sdw.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 @@ -52,11 +32,8 @@ 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 obj-$(CONFIG_SND_SOC_INTEL_SOF_PCM512x_MACH) += snd-soc-sst-sof-pcm512x.o obj-$(CONFIG_SND_SOC_INTEL_SOF_WM8804_MACH) += snd-soc-sst-sof-wm8804.o -obj-$(CONFIG_SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH) += snd-soc-sst-glk-rt5682_max98357a.o obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-bdw-rt286.o obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5650_MACH) += snd-soc-sst-bdw-rt5650-mach.o obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH) += snd-soc-sst-bdw-rt5677-mach.o @@ -71,38 +48,26 @@ obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_CX2072X_MACH) += snd-soc-sst-byt-cht-cx2072x. obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH) += snd-soc-sst-byt-cht-da7213.o obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH) += snd-soc-sst-byt-cht-es8316.o obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) += snd-soc-sst-byt-cht-nocodec.o -obj-$(CONFIG_SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH) += snd-soc-cml_rt1011_rt5682.o -obj-$(CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH) += snd-soc-kbl_da7219_max98357a.o -obj-$(CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH) += snd-soc-kbl_da7219_max98927.o -obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH) += snd-soc-kbl_rt5663_max98927.o -obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH) += snd-soc-kbl_rt5663_rt5514_max98927.o -obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH) += snd-soc-kbl_rt5660.o -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_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 # common modules -snd-soc-intel-hda-dsp-common-objs := hda_dsp_common.o +snd-soc-intel-hda-dsp-common-y := hda_dsp_common.o obj-$(CONFIG_SND_SOC_INTEL_HDA_DSP_COMMON) += snd-soc-intel-hda-dsp-common.o -snd-soc-intel-sof-maxim-common-objs += sof_maxim_common.o +snd-soc-intel-sof-maxim-common-y += sof_maxim_common.o obj-$(CONFIG_SND_SOC_INTEL_SOF_MAXIM_COMMON) += snd-soc-intel-sof-maxim-common.o -snd-soc-intel-sof-realtek-common-objs += sof_realtek_common.o +snd-soc-intel-sof-realtek-common-y += sof_realtek_common.o obj-$(CONFIG_SND_SOC_INTEL_SOF_REALTEK_COMMON) += snd-soc-intel-sof-realtek-common.o -snd-soc-intel-sof-cirrus-common-objs += sof_cirrus_common.o +snd-soc-intel-sof-cirrus-common-y += 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 +snd-soc-intel-sof-nuvoton-common-y += 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 +snd-soc-intel-sof-board-helpers-y += 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 3ae26f21458f..d25a7188f603 100644 --- a/sound/soc/intel/boards/bdw-rt5650.c +++ b/sound/soc/intel/boards/bdw-rt5650.c @@ -131,7 +131,7 @@ static int bdw_rt5650_hw_params(struct snd_pcm_substream *substream, return ret; } -static struct snd_soc_ops bdw_rt5650_ops = { +static const struct snd_soc_ops bdw_rt5650_ops = { .hw_params = bdw_rt5650_hw_params, }; @@ -239,8 +239,6 @@ static struct snd_soc_dai_link bdw_rt5650_dais[] = { SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST }, - .dpcm_playback = 1, - .dpcm_capture = 1, SND_SOC_DAILINK_REG(fe, dummy, platform), }, @@ -256,8 +254,6 @@ static struct snd_soc_dai_link bdw_rt5650_dais[] = { .ignore_pmdown_time = 1, .be_hw_params_fixup = broadwell_ssp0_fixup, .ops = &bdw_rt5650_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, .init = bdw_rt5650_init, SND_SOC_DAILINK_REG(ssp0_port, be, platform), }, diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c index 304af3d06d01..9484f3410787 100644 --- a/sound/soc/intel/boards/bdw-rt5677.c +++ b/sound/soc/intel/boards/bdw-rt5677.c @@ -329,8 +329,6 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = { SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST }, - .dpcm_capture = 1, - .dpcm_playback = 1, .ops = &bdw_rt5677_fe_ops, SND_SOC_DAILINK_REG(fe, dummy, platform), }, @@ -356,8 +354,6 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = { .ignore_pmdown_time = 1, .be_hw_params_fixup = broadwell_ssp0_fixup, .ops = &bdw_rt5677_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, .init = bdw_rt5677_init, .exit = bdw_rt5677_exit, SND_SOC_DAILINK_REG(ssp0_port, be, platform), diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index 7f20159c23e5..523ade9f31ab 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -2,7 +2,7 @@ /* * Sound card driver for Intel Broadwell Wildcat Point with Realtek 286 * - * Copyright (C) 2013, Intel Corporation. All rights reserved. + * Copyright (C) 2013, Intel Corporation */ #include <linux/module.h> @@ -133,8 +133,6 @@ static struct snd_soc_dai_link card_dai_links[] = { .nonatomic = 1, .dynamic = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .dpcm_capture = 1, SND_SOC_DAILINK_REG(system, dummy, platform), }, { @@ -143,7 +141,7 @@ static struct snd_soc_dai_link card_dai_links[] = { .nonatomic = 1, .dynamic = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, + .playback_only = 1, SND_SOC_DAILINK_REG(offload0, dummy, platform), }, { @@ -152,7 +150,7 @@ static struct snd_soc_dai_link card_dai_links[] = { .nonatomic = 1, .dynamic = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, + .playback_only = 1, SND_SOC_DAILINK_REG(offload1, dummy, platform), }, { @@ -161,7 +159,7 @@ static struct snd_soc_dai_link card_dai_links[] = { .nonatomic = 1, .dynamic = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, + .capture_only = 1, SND_SOC_DAILINK_REG(loopback, dummy, platform), }, /* Back End DAI links */ @@ -177,8 +175,6 @@ static struct snd_soc_dai_link card_dai_links[] = { .ignore_pmdown_time = 1, .be_hw_params_fixup = codec_link_hw_params_fixup, .ops = &codec_link_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, SND_SOC_DAILINK_REG(ssp0_port, codec, platform), }, }; diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c deleted file mode 100644 index 540f7a29310a..000000000000 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ /dev/null @@ -1,894 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel Broxton-P I2S Machine Driver - * - * Copyright (C) 2016, Intel Corporation. All rights reserved. - * - * Modified from: - * Intel Skylake I2S Machine driver - */ - -#include <linux/input.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/jack.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include "../../codecs/hdac_hdmi.h" -#include "../../codecs/da7219.h" -#include "../common/soc-intel-quirks.h" -#include "hda_dsp_common.h" - -#define BXT_DIALOG_CODEC_DAI "da7219-hifi" -#define BXT_MAXIM_CODEC_DAI "HiFi" -#define MAX98390_DEV0_NAME "i2c-MX98390:00" -#define MAX98390_DEV1_NAME "i2c-MX98390:01" -#define DUAL_CHANNEL 2 -#define QUAD_CHANNEL 4 - -#define SPKAMP_MAX98357A 1 -#define SPKAMP_MAX98390 2 - -static struct snd_soc_jack broxton_headset; -static struct snd_soc_jack broxton_hdmi[3]; - -struct bxt_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct bxt_card_private { - struct list_head hdmi_pcm_list; - bool common_hdmi_codec_drv; - int spkamp; -}; - -enum { - BXT_DPCM_AUDIO_PB = 0, - BXT_DPCM_AUDIO_CP, - BXT_DPCM_AUDIO_HS_PB, - BXT_DPCM_AUDIO_REF_CP, - BXT_DPCM_AUDIO_DMIC_CP, - BXT_DPCM_AUDIO_HDMI1_PB, - BXT_DPCM_AUDIO_HDMI2_PB, - BXT_DPCM_AUDIO_HDMI3_PB, -}; - -static int platform_clock_control(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - int ret = 0; - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; - struct snd_soc_dai *codec_dai; - - codec_dai = snd_soc_card_get_codec_dai(card, BXT_DIALOG_CODEC_DAI); - if (!codec_dai) { - dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n"); - return -EIO; - } - - if (SND_SOC_DAPM_EVENT_OFF(event)) { - ret = snd_soc_dai_set_pll(codec_dai, 0, - DA7219_SYSCLK_MCLK, 0, 0); - if (ret) - dev_err(card->dev, "failed to stop PLL: %d\n", ret); - } else if(SND_SOC_DAPM_EVENT_ON(event)) { - ret = snd_soc_dai_set_pll(codec_dai, 0, - DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304); - if (ret) - dev_err(card->dev, "failed to start PLL: %d\n", ret); - } - - return ret; -} - -static const struct snd_kcontrol_new broxton_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Line Out"), -}; - -static const struct snd_kcontrol_new max98357a_controls[] = { - SOC_DAPM_PIN_SWITCH("Spk"), -}; - -static const struct snd_kcontrol_new max98390_controls[] = { - SOC_DAPM_PIN_SWITCH("Left Spk"), - SOC_DAPM_PIN_SWITCH("Right Spk"), -}; - -static const struct snd_soc_dapm_widget broxton_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_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("HDMI1", NULL), - SND_SOC_DAPM_SPK("HDMI2", NULL), - SND_SOC_DAPM_SPK("HDMI3", 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), -}; - -static const struct snd_soc_dapm_widget max98357a_widgets[] = { - SND_SOC_DAPM_SPK("Spk", NULL), -}; - -static const struct snd_soc_dapm_widget max98390_widgets[] = { - SND_SOC_DAPM_SPK("Left Spk", NULL), - SND_SOC_DAPM_SPK("Right Spk", NULL), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - /* HP jack connectors - unknown if we have jack detection */ - {"Headphone Jack", NULL, "HPL"}, - {"Headphone Jack", NULL, "HPR"}, - - /* other jacks */ - {"MIC", NULL, "Headset Mic"}, - - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, - - /* CODEC BE connections */ - {"HDMI1", NULL, "hif5-0 Output"}, - {"HDMI2", NULL, "hif6-0 Output"}, - {"HDMI2", NULL, "hif7-0 Output"}, - - {"hifi3", NULL, "iDisp3 Tx"}, - {"iDisp3 Tx", NULL, "iDisp3_out"}, - {"hifi2", NULL, "iDisp2 Tx"}, - {"iDisp2 Tx", NULL, "iDisp2_out"}, - {"hifi1", NULL, "iDisp1 Tx"}, - {"iDisp1 Tx", NULL, "iDisp1_out"}, - - /* DMIC */ - {"dmic01_hifi", NULL, "DMIC01 Rx"}, - {"DMIC01 Rx", NULL, "DMIC AIF"}, - - { "Headphone Jack", NULL, "Platform Clock" }, - { "Headset Mic", NULL, "Platform Clock" }, - { "Line Out", NULL, "Platform Clock" }, -}; - -static const struct snd_soc_dapm_route max98357a_routes[] = { - /* speaker */ - {"Spk", NULL, "Speaker"}, -}; - -static const struct snd_soc_dapm_route max98390_routes[] = { - /* Speaker */ - {"Left Spk", NULL, "Left BE_OUT"}, - {"Right Spk", NULL, "Right BE_OUT"}, -}; - -static const struct snd_soc_dapm_route broxton_map[] = { - {"HiFi Playback", NULL, "ssp5 Tx"}, - {"ssp5 Tx", NULL, "codec0_out"}, - - {"Playback", NULL, "ssp1 Tx"}, - {"ssp1 Tx", NULL, "codec1_out"}, - - {"codec0_in", NULL, "ssp1 Rx"}, - {"ssp1 Rx", NULL, "Capture"}, -}; - -static const struct snd_soc_dapm_route gemini_map[] = { - {"HiFi Playback", NULL, "ssp1 Tx"}, - {"ssp1 Tx", NULL, "codec0_out"}, - - {"Playback", NULL, "ssp2 Tx"}, - {"ssp2 Tx", NULL, "codec1_out"}, - - {"codec0_in", NULL, "ssp2 Rx"}, - {"ssp2 Rx", NULL, "Capture"}, -}; - -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, - { - .pin = "Line Out", - .mask = SND_JACK_LINEOUT, - }, -}; - -static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - - /* The ADSP will convert the FE rate to 48k, stereo */ - rate->min = rate->max = 48000; - chan->min = chan->max = DUAL_CHANNEL; - - /* set SSP to 24 bit */ - snd_mask_none(fmt); - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); - - return 0; -} - -static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret; - 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 */ - if (soc_intel_is_cml()) - clk_freq = 24000000; - else - clk_freq = 19200000; - - ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq, - SND_SOC_CLOCK_IN); - - if (ret) { - dev_err(rtd->dev, "can't set codec sysclk configuration\n"); - return ret; - } - - /* - * Headset buttons map to the google Reference headset. - * These can be configured by userspace. - */ - ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, - &broxton_headset, - jack_pins, - ARRAY_SIZE(jack_pins)); - if (ret) { - dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); - return ret; - } - - snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); - snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); - snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); - snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_3, - KEY_VOICECOMMAND); - - snd_soc_component_set_jack(component, &broxton_headset, NULL); - - snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); - - return ret; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct bxt_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = BXT_DPCM_AUDIO_HDMI1_PB + dai->id; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -static int broxton_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dapm_context *dapm; - 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"); - - return 0; -} - -static const unsigned int rates[] = { - 48000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static const unsigned int channels[] = { - DUAL_CHANNEL, -}; - -static const struct snd_pcm_hw_constraint_list constraints_channels = { - .count = ARRAY_SIZE(channels), - .list = channels, - .mask = 0, -}; - -static const unsigned int channels_quad[] = { - QUAD_CHANNEL, -}; - -static const struct snd_pcm_hw_constraint_list constraints_channels_quad = { - .count = ARRAY_SIZE(channels_quad), - .list = channels_quad, - .mask = 0, -}; - -static int bxt_fe_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - /* - * On this platform for PCM device we support, - * 48Khz - * stereo - * 16 bit audio - */ - - runtime->hw.channels_max = DUAL_CHANNEL; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels); - - runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; - snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); - - snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); - - return 0; -} - -static const struct snd_soc_ops broxton_da7219_fe_ops = { - .startup = bxt_fe_startup, -}; - -static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - if (params_channels(params) == 2) - chan->min = chan->max = 2; - else - chan->min = chan->max = 4; - - return 0; -} - -static int broxton_dmic_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels_quad); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); -} - -static const struct snd_soc_ops broxton_dmic_ops = { - .startup = broxton_dmic_startup, -}; - -static const unsigned int rates_16000[] = { - 16000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_16000 = { - .count = ARRAY_SIZE(rates_16000), - .list = rates_16000, -}; - -static const unsigned int ch_mono[] = { - 1, -}; - -static const struct snd_pcm_hw_constraint_list constraints_refcap = { - .count = ARRAY_SIZE(ch_mono), - .list = ch_mono, -}; - -static int broxton_refcap_startup(struct snd_pcm_substream *substream) -{ - substream->runtime->hw.channels_max = 1; - snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_refcap); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &constraints_16000); -}; - -static const struct snd_soc_ops broxton_refcap_ops = { - .startup = broxton_refcap_startup, -}; - -/* broxton digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); - -SND_SOC_DAILINK_DEF(system2, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin2"))); - -SND_SOC_DAILINK_DEF(reference, - DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); - -SND_SOC_DAILINK_DEF(dmic, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); - -SND_SOC_DAILINK_DEF(hdmi1, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi2, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi3, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); - - /* Back End DAI */ -SND_SOC_DAILINK_DEF(ssp5_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP5 Pin"))); -SND_SOC_DAILINK_DEF(ssp5_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", - BXT_MAXIM_CODEC_DAI))); -SND_SOC_DAILINK_DEF(max98390_codec, - DAILINK_COMP_ARRAY( - /* Left */ COMP_CODEC(MAX98390_DEV0_NAME, "max98390-aif1"), - /* Right */ COMP_CODEC(MAX98390_DEV1_NAME, "max98390-aif1"))); - -SND_SOC_DAILINK_DEF(ssp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); -SND_SOC_DAILINK_DEF(ssp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00", - BXT_DIALOG_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(dmic_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); - -SND_SOC_DAILINK_DEF(dmic16k_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin"))); - -SND_SOC_DAILINK_DEF(dmic_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", - "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", - "intel-hdmi-hifi3"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:0e.0"))); - -static struct snd_soc_dai_link broxton_dais[] = { - /* Front End DAI links */ - [BXT_DPCM_AUDIO_PB] = - { - .name = "Bxt Audio Port", - .stream_name = "Audio", - .dynamic = 1, - .nonatomic = 1, - .init = broxton_da7219_fe_init, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .ops = &broxton_da7219_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [BXT_DPCM_AUDIO_CP] = - { - .name = "Bxt Audio Capture Port", - .stream_name = "Audio Record", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, - .ops = &broxton_da7219_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [BXT_DPCM_AUDIO_HS_PB] = { - .name = "Bxt Audio Headset Playback", - .stream_name = "Headset Playback", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .ops = &broxton_da7219_fe_ops, - SND_SOC_DAILINK_REG(system2, dummy, platform), - }, - [BXT_DPCM_AUDIO_REF_CP] = - { - .name = "Bxt Audio Reference cap", - .stream_name = "Refcap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &broxton_refcap_ops, - SND_SOC_DAILINK_REG(reference, dummy, platform), - }, - [BXT_DPCM_AUDIO_DMIC_CP] = - { - .name = "Bxt Audio DMIC cap", - .stream_name = "dmiccap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &broxton_dmic_ops, - SND_SOC_DAILINK_REG(dmic, dummy, platform), - }, - [BXT_DPCM_AUDIO_HDMI1_PB] = - { - .name = "Bxt HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [BXT_DPCM_AUDIO_HDMI2_PB] = - { - .name = "Bxt HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - [BXT_DPCM_AUDIO_HDMI3_PB] = - { - .name = "Bxt HDMI Port3", - .stream_name = "Hdmi3", - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi3, dummy, platform), - }, - /* Back End DAI links */ - { - /* SSP5 - Codec */ - .name = "SSP5-Codec", - .id = 0, - .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = broxton_ssp_fixup, - .dpcm_playback = 1, - SND_SOC_DAILINK_REG(ssp5_pin, ssp5_codec, platform), - }, - { - /* SSP1 - Codec */ - .name = "SSP1-Codec", - .id = 1, - .no_pcm = 1, - .init = broxton_da7219_codec_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = broxton_ssp_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), - }, - { - .name = "dmic01", - .id = 2, - .ignore_suspend = 1, - .be_hw_params_fixup = broxton_dmic_fixup, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), - }, - { - .name = "iDisp1", - .id = 3, - .init = broxton_hdmi_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 4, - .init = broxton_hdmi_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, - { - .name = "iDisp3", - .id = 5, - .init = broxton_hdmi_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), - }, - { - .name = "dmic16k", - .id = 6, - .be_hw_params_fixup = broxton_dmic_fixup, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic16k_pin, dmic_codec, platform), - }, -}; - -static struct snd_soc_codec_conf max98390_codec_confs[] = { - { - .dlc = COMP_CODEC_CONF(MAX98390_DEV0_NAME), - .name_prefix = "Left", - }, - { - .dlc = COMP_CODEC_CONF(MAX98390_DEV1_NAME), - .name_prefix = "Right", - }, -}; - -#define NAME_SIZE 32 -static int bxt_card_late_probe(struct snd_soc_card *card) -{ - struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card); - struct bxt_hdmi_pcm *pcm; - struct snd_soc_component *component = NULL; - const struct snd_kcontrol_new *controls; - const struct snd_soc_dapm_widget *widgets; - const struct snd_soc_dapm_route *routes; - int num_controls, num_widgets, num_routes, err, i = 0; - char jack_name[NAME_SIZE]; - - switch (ctx->spkamp) { - case SPKAMP_MAX98357A: - controls = max98357a_controls; - num_controls = ARRAY_SIZE(max98357a_controls); - widgets = max98357a_widgets; - num_widgets = ARRAY_SIZE(max98357a_widgets); - routes = max98357a_routes; - num_routes = ARRAY_SIZE(max98357a_routes); - break; - case SPKAMP_MAX98390: - controls = max98390_controls; - num_controls = ARRAY_SIZE(max98390_controls); - widgets = max98390_widgets; - num_widgets = ARRAY_SIZE(max98390_widgets); - routes = max98390_routes; - num_routes = ARRAY_SIZE(max98390_routes); - break; - default: - dev_err(card->dev, "Invalid speaker amplifier %d\n", ctx->spkamp); - return -EINVAL; - } - - err = snd_soc_dapm_new_controls(&card->dapm, widgets, num_widgets); - if (err) { - dev_err(card->dev, "Fail to new widgets\n"); - return err; - } - - err = snd_soc_add_card_controls(card, controls, num_controls); - if (err) { - dev_err(card->dev, "Fail to add controls\n"); - return err; - } - - err = snd_soc_dapm_add_routes(&card->dapm, routes, num_routes); - if (err) { - dev_err(card->dev, "Fail to add routes\n"); - return err; - } - - if (soc_intel_is_glk()) - snd_soc_dapm_add_routes(&card->dapm, gemini_map, - ARRAY_SIZE(gemini_map)); - else - snd_soc_dapm_add_routes(&card->dapm, broxton_map, - ARRAY_SIZE(broxton_map)); - - if (list_empty(&ctx->hdmi_pcm_list)) - return -EINVAL; - - if (ctx->common_hdmi_codec_drv) { - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_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, &broxton_hdmi[i]); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &broxton_hdmi[i]); - if (err < 0) - return err; - - i++; - } - - return hdac_hdmi_jack_port_init(component, &card->dapm); -} - -/* broxton audio machine driver for SPT + da7219 */ -static struct snd_soc_card broxton_audio_card = { - .name = "bxtda7219max", - .owner = THIS_MODULE, - .dai_link = broxton_dais, - .num_links = ARRAY_SIZE(broxton_dais), - .controls = broxton_controls, - .num_controls = ARRAY_SIZE(broxton_controls), - .dapm_widgets = broxton_widgets, - .num_dapm_widgets = ARRAY_SIZE(broxton_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), - .fully_routed = true, - .late_probe = bxt_card_late_probe, -}; - -static int broxton_audio_probe(struct platform_device *pdev) -{ - struct bxt_card_private *ctx; - struct snd_soc_acpi_mach *mach; - const char *platform_name; - int ret; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - - if (acpi_dev_present("MX98390", NULL, -1)) - ctx->spkamp = SPKAMP_MAX98390; - else - ctx->spkamp = SPKAMP_MAX98357A; - - broxton_audio_card.dev = &pdev->dev; - snd_soc_card_set_drvdata(&broxton_audio_card, ctx); - if (soc_intel_is_glk()) { - unsigned int i; - - broxton_audio_card.name = "glkda7219max"; - /* Fixup the SSP entries for geminilake */ - for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) { - if (!broxton_dais[i].codecs->dai_name) - continue; - - /* MAXIM_CODEC is connected to SSP1. */ - if (!strcmp(broxton_dais[i].codecs->dai_name, - BXT_MAXIM_CODEC_DAI)) { - broxton_dais[i].name = "SSP1-Codec"; - broxton_dais[i].cpus->dai_name = "SSP1 Pin"; - } - /* DIALOG_CODE is connected to SSP2 */ - else if (!strcmp(broxton_dais[i].codecs->dai_name, - BXT_DIALOG_CODEC_DAI)) { - broxton_dais[i].name = "SSP2-Codec"; - broxton_dais[i].cpus->dai_name = "SSP2 Pin"; - } - } - } else if (soc_intel_is_cml()) { - unsigned int i; - - if (ctx->spkamp == SPKAMP_MAX98390) { - broxton_audio_card.name = "cml_max98390_da7219"; - - broxton_audio_card.codec_conf = max98390_codec_confs; - broxton_audio_card.num_configs = ARRAY_SIZE(max98390_codec_confs); - } else - broxton_audio_card.name = "cmlda7219max"; - - for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) { - if (!broxton_dais[i].codecs->dai_name) - continue; - - /* MAXIM_CODEC is connected to SSP1. */ - if (!strcmp(broxton_dais[i].codecs->dai_name, - BXT_MAXIM_CODEC_DAI)) { - broxton_dais[i].name = "SSP1-Codec"; - broxton_dais[i].cpus->dai_name = "SSP1 Pin"; - - if (ctx->spkamp == SPKAMP_MAX98390) { - broxton_dais[i].codecs = max98390_codec; - broxton_dais[i].num_codecs = ARRAY_SIZE(max98390_codec); - broxton_dais[i].dpcm_capture = 1; - } - } - /* DIALOG_CODEC is connected to SSP0 */ - else if (!strcmp(broxton_dais[i].codecs->dai_name, - BXT_DIALOG_CODEC_DAI)) { - broxton_dais[i].name = "SSP0-Codec"; - broxton_dais[i].cpus->dai_name = "SSP0 Pin"; - } - } - } - - /* override platform name, if required */ - mach = pdev->dev.platform_data; - platform_name = mach->mach_params.platform; - - ret = snd_soc_fixup_dai_links_platform_name(&broxton_audio_card, - platform_name); - if (ret) - return ret; - - ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; - - return devm_snd_soc_register_card(&pdev->dev, &broxton_audio_card); -} - -static const struct platform_device_id bxt_board_ids[] = { - { .name = "bxt_da7219_mx98357a" }, - { .name = "glk_da7219_mx98357a" }, - { .name = "cml_da7219_mx98357a" }, - { } -}; -MODULE_DEVICE_TABLE(platform, bxt_board_ids); - -static struct platform_driver broxton_audio = { - .probe = broxton_audio_probe, - .driver = { - .name = "bxt_da7219_max98357a", - .pm = &snd_soc_pm_ops, - }, - .id_table = bxt_board_ids, -}; -module_platform_driver(broxton_audio) - -/* Module information */ -MODULE_DESCRIPTION("Audio Machine driver-DA7219 & MAX98357A in I2S mode"); -MODULE_AUTHOR("Sathyanarayana Nujella <sathyanarayana.nujella@intel.com>"); -MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com>"); -MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); -MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>"); -MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>"); -MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); -MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); -MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c deleted file mode 100644 index c0eb65c14aa9..000000000000 --- a/sound/soc/intel/boards/bxt_rt298.c +++ /dev/null @@ -1,669 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel Broxton-P I2S Machine Driver - * - * Copyright (C) 2014-2016, Intel Corporation. All rights reserved. - * - * Modified from: - * Intel Skylake I2S Machine driver - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/jack.h> -#include <sound/pcm_params.h> -#include "../../codecs/hdac_hdmi.h" -#include "../../codecs/rt298.h" -#include "hda_dsp_common.h" - -/* Headset jack detection DAPM pins */ -static struct snd_soc_jack broxton_headset; -static struct snd_soc_jack broxton_hdmi[3]; - -struct bxt_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct bxt_rt286_private { - struct list_head hdmi_pcm_list; - bool common_hdmi_codec_drv; -}; - -enum { - BXT_DPCM_AUDIO_PB = 0, - BXT_DPCM_AUDIO_CP, - BXT_DPCM_AUDIO_REF_CP, - BXT_DPCM_AUDIO_DMIC_CP, - BXT_DPCM_AUDIO_HDMI1_PB, - BXT_DPCM_AUDIO_HDMI2_PB, - BXT_DPCM_AUDIO_HDMI3_PB, -}; - -static struct snd_soc_jack_pin broxton_headset_pins[] = { - { - .pin = "Mic Jack", - .mask = SND_JACK_MICROPHONE, - }, - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, -}; - -static const struct snd_kcontrol_new broxton_controls[] = { - SOC_DAPM_PIN_SWITCH("Speaker"), - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Mic Jack"), -}; - -static const struct snd_soc_dapm_widget broxton_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_SPK("Speaker", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), - SND_SOC_DAPM_MIC("DMIC2", NULL), - SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("HDMI1", NULL), - SND_SOC_DAPM_SPK("HDMI2", NULL), - SND_SOC_DAPM_SPK("HDMI3", NULL), -}; - -static const struct snd_soc_dapm_route broxton_rt298_map[] = { - /* speaker */ - {"Speaker", NULL, "SPOR"}, - {"Speaker", NULL, "SPOL"}, - - /* HP jack connectors - unknown if we have jack detect */ - {"Headphone Jack", NULL, "HPO Pin"}, - - /* other jacks */ - {"MIC1", NULL, "Mic Jack"}, - - /* digital mics */ - {"DMIC1 Pin", NULL, "DMIC2"}, - {"DMic", NULL, "SoC DMIC"}, - - {"HDMI1", NULL, "hif5-0 Output"}, - {"HDMI2", NULL, "hif6-0 Output"}, - {"HDMI2", NULL, "hif7-0 Output"}, - - /* CODEC BE connections */ - { "AIF1 Playback", NULL, "ssp5 Tx"}, - { "ssp5 Tx", NULL, "codec0_out"}, - { "ssp5 Tx", NULL, "codec1_out"}, - - { "codec0_in", NULL, "ssp5 Rx" }, - { "ssp5 Rx", NULL, "AIF1 Capture" }, - - { "dmic01_hifi", NULL, "DMIC01 Rx" }, - { "DMIC01 Rx", NULL, "Capture" }, - - { "hifi3", NULL, "iDisp3 Tx"}, - { "iDisp3 Tx", NULL, "iDisp3_out"}, - { "hifi2", NULL, "iDisp2 Tx"}, - { "iDisp2 Tx", NULL, "iDisp2_out"}, - { "hifi1", NULL, "iDisp1 Tx"}, - { "iDisp1 Tx", NULL, "iDisp1_out"}, -}; - -static const struct snd_soc_dapm_route geminilake_rt298_map[] = { - /* speaker */ - {"Speaker", NULL, "SPOR"}, - {"Speaker", NULL, "SPOL"}, - - /* HP jack connectors - unknown if we have jack detect */ - {"Headphone Jack", NULL, "HPO Pin"}, - - /* other jacks */ - {"MIC1", NULL, "Mic Jack"}, - - /* digital mics */ - {"DMIC1 Pin", NULL, "DMIC2"}, - {"DMic", NULL, "SoC DMIC"}, - - {"HDMI1", NULL, "hif5-0 Output"}, - {"HDMI2", NULL, "hif6-0 Output"}, - {"HDMI2", NULL, "hif7-0 Output"}, - - /* CODEC BE connections */ - { "AIF1 Playback", NULL, "ssp2 Tx"}, - { "ssp2 Tx", NULL, "codec0_out"}, - { "ssp2 Tx", NULL, "codec1_out"}, - - { "codec0_in", NULL, "ssp2 Rx" }, - { "ssp2 Rx", NULL, "AIF1 Capture" }, - - { "dmic01_hifi", NULL, "DMIC01 Rx" }, - { "DMIC01 Rx", NULL, "Capture" }, - - { "dmic_voice", NULL, "DMIC16k Rx" }, - { "DMIC16k Rx", NULL, "Capture" }, - - { "hifi3", NULL, "iDisp3 Tx"}, - { "iDisp3 Tx", NULL, "iDisp3_out"}, - { "hifi2", NULL, "iDisp2 Tx"}, - { "iDisp2 Tx", NULL, "iDisp2_out"}, - { "hifi1", NULL, "iDisp1 Tx"}, - { "iDisp1 Tx", NULL, "iDisp1_out"}, -}; - -static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dapm_context *dapm; - 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"); - - return 0; -} - -static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd) -{ - 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", - SND_JACK_HEADSET | SND_JACK_BTN_0, - &broxton_headset, - broxton_headset_pins, ARRAY_SIZE(broxton_headset_pins)); - - if (ret) - return ret; - - snd_soc_component_set_jack(component, &broxton_headset, NULL); - - snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); - - return 0; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct bxt_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = BXT_DPCM_AUDIO_HDMI1_PB + dai->id; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -static int broxton_ssp5_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - - /* The ADSP will convert the FE rate to 48k, stereo */ - rate->min = rate->max = 48000; - chan->min = chan->max = 2; - - /* set SSP5 to 24 bit */ - snd_mask_none(fmt); - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); - - return 0; -} - -static int broxton_rt298_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - 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, - 19200000, SND_SOC_CLOCK_IN); - if (ret < 0) { - dev_err(rtd->dev, "can't set codec sysclk configuration\n"); - return ret; - } - - return ret; -} - -static const struct snd_soc_ops broxton_rt298_ops = { - .hw_params = broxton_rt298_hw_params, -}; - -static const unsigned int rates[] = { - 48000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - chan->min = chan->max = 4; - - return 0; -} - -static const unsigned int channels_dmic[] = { - 1, 2, 3, 4, -}; - -static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = { - .count = ARRAY_SIZE(channels_dmic), - .list = channels_dmic, - .mask = 0, -}; - -static int broxton_dmic_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw.channels_max = 4; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_dmic_channels); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); -} - -static const struct snd_soc_ops broxton_dmic_ops = { - .startup = broxton_dmic_startup, -}; - -static const unsigned int channels[] = { - 2, -}; - -static const struct snd_pcm_hw_constraint_list constraints_channels = { - .count = ARRAY_SIZE(channels), - .list = channels, - .mask = 0, -}; - -static int bxt_fe_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - /* - * on this platform for PCM device we support: - * 48Khz - * stereo - * 16-bit audio - */ - - runtime->hw.channels_max = 2; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels); - - runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; - snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); - snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); - - return 0; -} - -static const struct snd_soc_ops broxton_rt286_fe_ops = { - .startup = bxt_fe_startup, -}; - -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); - -SND_SOC_DAILINK_DEF(reference, - DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); - -SND_SOC_DAILINK_DEF(dmic, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); - -SND_SOC_DAILINK_DEF(hdmi1, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi2, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi3, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); - -SND_SOC_DAILINK_DEF(ssp5_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP5 Pin"))); -SND_SOC_DAILINK_DEF(ssp5_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT343A:00", - "rt298-aif1"))); - -SND_SOC_DAILINK_DEF(dmic_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); - -SND_SOC_DAILINK_DEF(dmic_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", - "dmic-hifi"))); - -SND_SOC_DAILINK_DEF(dmic16k, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin"))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", - "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", - "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", - "intel-hdmi-hifi3"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:0e.0"))); - -/* broxton digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link broxton_rt298_dais[] = { - /* Front End DAI links */ - [BXT_DPCM_AUDIO_PB] = - { - .name = "Bxt Audio Port", - .stream_name = "Audio", - .nonatomic = 1, - .dynamic = 1, - .init = broxton_rt298_fe_init, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .ops = &broxton_rt286_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [BXT_DPCM_AUDIO_CP] = - { - .name = "Bxt Audio Capture Port", - .stream_name = "Audio Record", - .nonatomic = 1, - .dynamic = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, - .ops = &broxton_rt286_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [BXT_DPCM_AUDIO_REF_CP] = - { - .name = "Bxt Audio Reference cap", - .stream_name = "refcap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(reference, dummy, platform), - }, - [BXT_DPCM_AUDIO_DMIC_CP] = - { - .name = "Bxt Audio DMIC cap", - .stream_name = "dmiccap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &broxton_dmic_ops, - SND_SOC_DAILINK_REG(dmic, dummy, platform), - }, - [BXT_DPCM_AUDIO_HDMI1_PB] = - { - .name = "Bxt HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [BXT_DPCM_AUDIO_HDMI2_PB] = - { - .name = "Bxt HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - [BXT_DPCM_AUDIO_HDMI3_PB] = - { - .name = "Bxt HDMI Port3", - .stream_name = "Hdmi3", - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi3, dummy, platform), - }, - /* Back End DAI links */ - { - /* SSP5 - Codec */ - .name = "SSP5-Codec", - .id = 0, - .no_pcm = 1, - .init = broxton_rt298_codec_init, - .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = broxton_ssp5_fixup, - .ops = &broxton_rt298_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp5_pin, ssp5_codec, platform), - }, - { - .name = "dmic01", - .id = 1, - .be_hw_params_fixup = broxton_dmic_fixup, - .ignore_suspend = 1, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), - }, - { - .name = "dmic16k", - .id = 2, - .be_hw_params_fixup = broxton_dmic_fixup, - .ignore_suspend = 1, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic16k, dmic_codec, platform), - }, - { - .name = "iDisp1", - .id = 3, - .init = broxton_hdmi_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 4, - .init = broxton_hdmi_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, - { - .name = "iDisp3", - .id = 5, - .init = broxton_hdmi_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), - }, -}; - -#define NAME_SIZE 32 -static int bxt_card_late_probe(struct snd_soc_card *card) -{ - struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(card); - struct bxt_hdmi_pcm *pcm; - struct snd_soc_component *component = NULL; - int err, i = 0; - char jack_name[NAME_SIZE]; - - if (list_empty(&ctx->hdmi_pcm_list)) - return -EINVAL; - - if (ctx->common_hdmi_codec_drv) { - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_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, &broxton_hdmi[i]); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &broxton_hdmi[i]); - if (err < 0) - return err; - - i++; - } - - return hdac_hdmi_jack_port_init(component, &card->dapm); -} - - -/* broxton audio machine driver for SPT + RT298S */ -static struct snd_soc_card broxton_rt298 = { - .name = "broxton-rt298", - .owner = THIS_MODULE, - .dai_link = broxton_rt298_dais, - .num_links = ARRAY_SIZE(broxton_rt298_dais), - .controls = broxton_controls, - .num_controls = ARRAY_SIZE(broxton_controls), - .dapm_widgets = broxton_widgets, - .num_dapm_widgets = ARRAY_SIZE(broxton_widgets), - .dapm_routes = broxton_rt298_map, - .num_dapm_routes = ARRAY_SIZE(broxton_rt298_map), - .fully_routed = true, - .late_probe = bxt_card_late_probe, - -}; - -static struct snd_soc_card geminilake_rt298 = { - .name = "geminilake-rt298", - .owner = THIS_MODULE, - .dai_link = broxton_rt298_dais, - .num_links = ARRAY_SIZE(broxton_rt298_dais), - .controls = broxton_controls, - .num_controls = ARRAY_SIZE(broxton_controls), - .dapm_widgets = broxton_widgets, - .num_dapm_widgets = ARRAY_SIZE(broxton_widgets), - .dapm_routes = geminilake_rt298_map, - .num_dapm_routes = ARRAY_SIZE(geminilake_rt298_map), - .fully_routed = true, - .late_probe = bxt_card_late_probe, -}; - -static int broxton_audio_probe(struct platform_device *pdev) -{ - struct bxt_rt286_private *ctx; - struct snd_soc_card *card = - (struct snd_soc_card *)pdev->id_entry->driver_data; - struct snd_soc_acpi_mach *mach; - const char *platform_name; - int ret; - int i; - - for (i = 0; i < ARRAY_SIZE(broxton_rt298_dais); i++) { - if (card->dai_link[i].codecs->name && - !strncmp(card->dai_link[i].codecs->name, "i2c-INT343A:00", - I2C_NAME_SIZE)) { - if (!strncmp(card->name, "broxton-rt298", - PLATFORM_NAME_SIZE)) { - card->dai_link[i].name = "SSP5-Codec"; - card->dai_link[i].cpus->dai_name = "SSP5 Pin"; - } else if (!strncmp(card->name, "geminilake-rt298", - PLATFORM_NAME_SIZE)) { - card->dai_link[i].name = "SSP2-Codec"; - card->dai_link[i].cpus->dai_name = "SSP2 Pin"; - } - } - } - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - - card->dev = &pdev->dev; - snd_soc_card_set_drvdata(card, ctx); - - /* override platform name, if required */ - mach = pdev->dev.platform_data; - platform_name = mach->mach_params.platform; - - ret = snd_soc_fixup_dai_links_platform_name(card, - platform_name); - if (ret) - return ret; - - ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; - - return devm_snd_soc_register_card(&pdev->dev, card); -} - -static const struct platform_device_id bxt_board_ids[] = { - { .name = "bxt_alc298s_i2s", .driver_data = - (unsigned long)&broxton_rt298 }, - { .name = "glk_alc298s_i2s", .driver_data = - (unsigned long)&geminilake_rt298 }, - {} -}; -MODULE_DEVICE_TABLE(platform, bxt_board_ids); - -static struct platform_driver broxton_audio = { - .probe = broxton_audio_probe, - .driver = { - .name = "bxt_alc298s_i2s", - .pm = &snd_soc_pm_ops, - }, - .id_table = bxt_board_ids, -}; -module_platform_driver(broxton_audio) - -/* Module information */ -MODULE_AUTHOR("Ramesh Babu <Ramesh.Babu@intel.com>"); -MODULE_AUTHOR("Senthilnathan Veppur <senthilnathanx.veppur@intel.com>"); -MODULE_DESCRIPTION("Intel SST Audio for Broxton"); -MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); diff --git a/sound/soc/intel/boards/bytcht_cx2072x.c b/sound/soc/intel/boards/bytcht_cx2072x.c index c014d85a08b2..68a3d345dc25 100644 --- a/sound/soc/intel/boards/bytcht_cx2072x.c +++ b/sound/soc/intel/boards/bytcht_cx2072x.c @@ -175,8 +175,6 @@ static struct snd_soc_dai_link byt_cht_cx2072x_dais[] = { .stream_name = "Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &byt_cht_cx2072x_aif1_ops, SND_SOC_DAILINK_REG(media, dummy, platform), }, @@ -185,7 +183,7 @@ static struct snd_soc_dai_link byt_cht_cx2072x_dais[] = { .stream_name = "Deep-Buffer Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, + .playback_only = 1, .ops = &byt_cht_cx2072x_aif1_ops, SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), }, @@ -198,8 +196,6 @@ static struct snd_soc_dai_link byt_cht_cx2072x_dais[] = { | SND_SOC_DAIFMT_CBC_CFC, .init = byt_cht_cx2072x_init, .be_hw_params_fixup = byt_cht_cx2072x_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, SND_SOC_DAILINK_REG(ssp2, cx2072x, platform), }, }; @@ -241,7 +237,7 @@ static int snd_byt_cht_cx2072x_probe(struct platform_device *pdev) /* fix index of codec dai */ for (i = 0; i < ARRAY_SIZE(byt_cht_cx2072x_dais); i++) { - if (byt_cht_cx2072x_dais[i].codecs->name && + if (byt_cht_cx2072x_dais[i].num_codecs && !strcmp(byt_cht_cx2072x_dais[i].codecs->name, "i2c-14F10720:00")) { dai_index = i; @@ -255,7 +251,11 @@ static int snd_byt_cht_cx2072x_probe(struct platform_device *pdev) snprintf(codec_name, sizeof(codec_name), "i2c-%s", acpi_dev_name(adev)); byt_cht_cx2072x_dais[dai_index].codecs->name = codec_name; + } else { + dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id); + return -ENOENT; } + acpi_dev_put(adev); /* override platform name, if required */ diff --git a/sound/soc/intel/boards/bytcht_da7213.c b/sound/soc/intel/boards/bytcht_da7213.c index f4ac3ddd148b..31141d4b6b25 100644 --- a/sound/soc/intel/boards/bytcht_da7213.c +++ b/sound/soc/intel/boards/bytcht_da7213.c @@ -174,8 +174,6 @@ static struct snd_soc_dai_link dailink[] = { .stream_name = "Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &aif1_ops, SND_SOC_DAILINK_REG(media, dummy, platform), }, @@ -184,7 +182,7 @@ static struct snd_soc_dai_link dailink[] = { .stream_name = "Deep-Buffer Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, + .playback_only = 1, .ops = &aif1_ops, SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), }, @@ -197,8 +195,6 @@ static struct snd_soc_dai_link dailink[] = { .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .be_hw_params_fixup = codec_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &ssp2_ops, SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform), }, @@ -245,7 +241,7 @@ static int bytcht_da7213_probe(struct platform_device *pdev) /* fix index of codec dai */ for (i = 0; i < ARRAY_SIZE(dailink); i++) { - if (dailink[i].codecs->name && + if (dailink[i].num_codecs && !strcmp(dailink[i].codecs->name, "i2c-DLGS7213:00")) { dai_index = i; break; @@ -258,7 +254,11 @@ static int bytcht_da7213_probe(struct platform_device *pdev) snprintf(codec_name, sizeof(codec_name), "i2c-%s", acpi_dev_name(adev)); dailink[dai_index].codecs->name = codec_name; + } else { + dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id); + return -ENOENT; } + acpi_dev_put(adev); /* override platform name, if required */ diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 2fcec2e02bb5..62594e7966ab 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -315,8 +315,6 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = { .stream_name = "Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &byt_cht_es8316_aif1_ops, SND_SOC_DAILINK_REG(media, dummy, platform), }, @@ -326,7 +324,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = { .stream_name = "Deep-Buffer Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, + .playback_only = 1, .ops = &byt_cht_es8316_aif1_ops, SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), }, @@ -339,8 +337,6 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = { .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .be_hw_params_fixup = byt_cht_es8316_codec_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, .init = byt_cht_es8316_init, SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform), }, @@ -546,7 +542,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) /* fix index of codec dai */ for (i = 0; i < ARRAY_SIZE(byt_cht_es8316_dais); i++) { - if (byt_cht_es8316_dais[i].codecs->name && + if (byt_cht_es8316_dais[i].num_codecs && !strcmp(byt_cht_es8316_dais[i].codecs->name, "i2c-ESSX8316:00")) { dai_index = i; @@ -562,7 +558,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) byt_cht_es8316_dais[dai_index].codecs->name = codec_name; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); - return -ENXIO; + return -ENOENT; } codec_dev = acpi_get_first_physical_node(adev); @@ -709,7 +705,7 @@ static struct platform_driver snd_byt_cht_es8316_mc_driver = { .name = "bytcht_es8316", }, .probe = snd_byt_cht_es8316_mc_probe, - .remove_new = snd_byt_cht_es8316_mc_remove, + .remove = snd_byt_cht_es8316_mc_remove, }; module_platform_driver(snd_byt_cht_es8316_mc_driver); diff --git a/sound/soc/intel/boards/bytcht_nocodec.c b/sound/soc/intel/boards/bytcht_nocodec.c index 4a957d1cece3..fec23bda9e64 100644 --- a/sound/soc/intel/boards/bytcht_nocodec.c +++ b/sound/soc/intel/boards/bytcht_nocodec.c @@ -119,8 +119,6 @@ static struct snd_soc_dai_link dais[] = { .ignore_suspend = 1, .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &aif1_ops, SND_SOC_DAILINK_REG(media, dummy, platform), }, @@ -130,7 +128,7 @@ static struct snd_soc_dai_link dais[] = { .ignore_suspend = 1, .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, + .playback_only = 1, .ops = &aif1_ops, SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), }, @@ -144,8 +142,6 @@ static struct snd_soc_dai_link dais[] = { | SND_SOC_DAIFMT_CBC_CFC, .be_hw_params_fixup = codec_fixup, .ignore_suspend = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, SND_SOC_DAILINK_REG(ssp2_port, dummy, platform), }, }; diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 05f38d1f7d82..0f3b8f44e701 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -17,6 +17,7 @@ #include <linux/acpi.h> #include <linux/clk.h> #include <linux/device.h> +#include <linux/device/bus.h> #include <linux/dmi.h> #include <linux/gpio/consumer.h> #include <linux/gpio/machine.h> @@ -32,6 +33,8 @@ #include "../atom/sst-atom-controls.h" #include "../common/soc-intel-quirks.h" +#define BYT_RT5640_FALLBACK_CODEC_DEV_NAME "i2c-rt5640" + enum { BYT_RT5640_DMIC1_MAP, BYT_RT5640_DMIC2_MAP, @@ -573,6 +576,19 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF2 | BYT_RT5640_MCLK_EN), }, + { /* Acer Aspire SW3-013 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-013"), + }, + .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | + BYT_RT5640_JD_SRC_JD2_IN4N | + BYT_RT5640_OVCD_TH_2000UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_DIFF_MIC | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), @@ -613,6 +629,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { { .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 101 CESIUM"), + }, + .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | + BYT_RT5640_JD_NOT_INV | + BYT_RT5640_DIFF_MIC | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, + { + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 140 CESIUM"), }, .driver_data = (void *)(BYT_RT5640_IN1_MAP | @@ -636,28 +663,30 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_USE_AMCR0F28), }, { + /* Asus T100TAF, unlike other T100TA* models this one has a mono speaker */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"), }, .driver_data = (void *)(BYT_RT5640_IN1_MAP | BYT_RT5640_JD_SRC_JD2_IN4N | BYT_RT5640_OVCD_TH_2000UA | BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_MONO_SPEAKER | + BYT_RT5640_DIFF_MIC | + BYT_RT5640_SSP0_AIF2 | BYT_RT5640_MCLK_EN), }, { + /* Asus T100TA and T100TAM, must come after T100TAF (mono spk) match */ .matches = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"), + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"), }, .driver_data = (void *)(BYT_RT5640_IN1_MAP | BYT_RT5640_JD_SRC_JD2_IN4N | BYT_RT5640_OVCD_TH_2000UA | BYT_RT5640_OVCD_SF_0P75 | - BYT_RT5640_MONO_SPEAKER | - BYT_RT5640_DIFF_MIC | - BYT_RT5640_SSP0_AIF2 | BYT_RT5640_MCLK_EN), }, { @@ -1116,6 +1145,36 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF2 | BYT_RT5640_MCLK_EN), }, + { + /* Vexia Edu Atla 10 tablet 5V version */ + .matches = { + /* Having all 3 of these not set is somewhat unique */ + DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), + DMI_MATCH(DMI_PRODUCT_NAME, "To be filled by O.E.M."), + DMI_MATCH(DMI_BOARD_NAME, "To be filled by O.E.M."), + /* Above strings are too generic, also match on BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "05/14/2015"), + }, + .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | + BYT_RT5640_JD_NOT_INV | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, + { /* Vexia Edu Atla 10 tablet 9V version */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), + /* Above strings are too generic, also match on BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"), + }, + .driver_data = (void *)(BYT_RT5640_IN1_MAP | + BYT_RT5640_JD_SRC_JD2_IN4N | + BYT_RT5640_OVCD_TH_2000UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_DIFF_MIC | + BYT_RT5640_SSP0_AIF2 | + BYT_RT5640_MCLK_EN), + }, { /* Voyo Winpad A15 */ .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), @@ -1533,8 +1592,6 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { .stream_name = "Baytrail Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &byt_rt5640_aif1_ops, SND_SOC_DAILINK_REG(media, dummy, platform), }, @@ -1543,7 +1600,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { .stream_name = "Deep-Buffer Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, + .playback_only = 1, .ops = &byt_rt5640_aif1_ops, SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), }, @@ -1555,8 +1612,6 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .be_hw_params_fixup = byt_rt5640_codec_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, .init = byt_rt5640_init, .exit = byt_rt5640_exit, .ops = &byt_rt5640_be_ssp2_ops, @@ -1664,7 +1719,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) /* fix index of codec dai */ for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) { - if (byt_rt5640_dais[i].codecs->name && + if (byt_rt5640_dais[i].num_codecs && !strcmp(byt_rt5640_dais[i].codecs->name, "i2c-10EC5640:00")) { dai_index = i; @@ -1680,14 +1735,38 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); - return -ENXIO; + return -ENOENT; } codec_dev = acpi_get_first_physical_node(adev); acpi_dev_put(adev); - if (!codec_dev) - return -EPROBE_DEFER; - priv->codec_dev = get_device(codec_dev); + + if (codec_dev) { + priv->codec_dev = get_device(codec_dev); + } else { + /* + * Special case for Android tablets where the codec i2c_client + * has been manually instantiated by x86_android_tablets.ko due + * to a broken DSDT. + */ + codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL, + BYT_RT5640_FALLBACK_CODEC_DEV_NAME); + if (!codec_dev) + return -EPROBE_DEFER; + + if (!i2c_verify_client(codec_dev)) { + dev_err(dev, "Error '%s' is not an i2c_client\n", + BYT_RT5640_FALLBACK_CODEC_DEV_NAME); + put_device(codec_dev); + } + + /* fixup codec name */ + strscpy(byt_rt5640_codec_name, BYT_RT5640_FALLBACK_CODEC_DEV_NAME, + sizeof(byt_rt5640_codec_name)); + + /* bus_find_device() returns a reference no need to get() */ + priv->codec_dev = codec_dev; + } /* * swap SSP0 if bytcr is detected @@ -1905,7 +1984,7 @@ static struct platform_driver snd_byt_rt5640_mc_driver = { .name = "bytcr_rt5640", }, .probe = snd_byt_rt5640_mc_probe, - .remove_new = snd_byt_rt5640_mc_remove, + .remove = snd_byt_rt5640_mc_remove, }; module_platform_driver(snd_byt_rt5640_mc_driver); diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 80c841b000a3..67c62844ca2a 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -770,8 +770,6 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = { .stream_name = "Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &byt_rt5651_aif1_ops, SND_SOC_DAILINK_REG(media, dummy, platform), }, @@ -780,7 +778,7 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = { .stream_name = "Deep-Buffer Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, + .playback_only = 1, .ops = &byt_rt5651_aif1_ops, SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), }, @@ -793,8 +791,6 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = { .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .be_hw_params_fixup = byt_rt5651_codec_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, .init = byt_rt5651_init, .ops = &byt_rt5651_be_ssp2_ops, SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform), @@ -910,7 +906,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) /* fix index of codec dai */ for (i = 0; i < ARRAY_SIZE(byt_rt5651_dais); i++) { - if (byt_rt5651_dais[i].codecs->name && + if (byt_rt5651_dais[i].num_codecs && !strcmp(byt_rt5651_dais[i].codecs->name, "i2c-10EC5651:00")) { dai_index = i; @@ -926,7 +922,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); - return -ENXIO; + return -ENOENT; } codec_dev = acpi_get_first_physical_node(adev); @@ -1142,7 +1138,7 @@ static struct platform_driver snd_byt_rt5651_mc_driver = { .name = "bytcr_rt5651", }, .probe = snd_byt_rt5651_mc_probe, - .remove_new = snd_byt_rt5651_mc_remove, + .remove = snd_byt_rt5651_mc_remove, }; module_platform_driver(snd_byt_rt5651_mc_driver); diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index cccb5e90c0fe..a6dfbcfdf74e 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -462,8 +462,6 @@ static struct snd_soc_dai_link byt_wm5102_dais[] = { .stream_name = "Baytrail Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &byt_wm5102_aif1_ops, SND_SOC_DAILINK_REG(media, dummy, platform), @@ -473,7 +471,7 @@ static struct snd_soc_dai_link byt_wm5102_dais[] = { .stream_name = "Deep-Buffer Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, + .playback_only = 1, .ops = &byt_wm5102_aif1_ops, SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), }, @@ -490,8 +488,6 @@ static struct snd_soc_dai_link byt_wm5102_dais[] = { .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .be_hw_params_fixup = byt_wm5102_codec_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, .init = byt_wm5102_init, SND_SOC_DAILINK_REG(ssp0_port, ssp0_codec, platform), }, @@ -605,7 +601,7 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) /* find index of codec dai */ for (i = 0; i < ARRAY_SIZE(byt_wm5102_dais); i++) { - if (byt_wm5102_dais[i].codecs->name && + if (byt_wm5102_dais[i].num_codecs && !strcmp(byt_wm5102_dais[i].codecs->name, "wm5102-codec")) { dai_index = i; @@ -663,7 +659,7 @@ static struct platform_driver snd_byt_wm5102_mc_driver = { .name = "bytcr_wm5102", }, .probe = snd_byt_wm5102_mc_probe, - .remove_new = snd_byt_wm5102_mc_remove, + .remove = snd_byt_wm5102_mc_remove, }; module_platform_driver(snd_byt_wm5102_mc_driver); diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index f43bc20d6aae..36984de8a067 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -351,8 +351,6 @@ static struct snd_soc_dai_link cht_dailink[] = { .stream_name = "Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &cht_aif1_ops, SND_SOC_DAILINK_REG(media, dummy, platform), }, @@ -361,7 +359,7 @@ static struct snd_soc_dai_link cht_dailink[] = { .stream_name = "Deep-Buffer Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, + .playback_only = 1, .ops = &cht_aif1_ops, SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), }, @@ -374,8 +372,6 @@ static struct snd_soc_dai_link cht_dailink[] = { | SND_SOC_DAIFMT_CBC_CFC, .init = cht_codec_init, .be_hw_params_fixup = cht_codec_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &cht_be_ssp2_ops, SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform), }, @@ -637,7 +633,7 @@ static struct platform_driver snd_cht_mc_driver = { .name = "cht-bsw-max98090", }, .probe = snd_cht_mc_probe, - .remove_new = snd_cht_mc_remove, + .remove = snd_cht_mc_remove, }; module_platform_driver(snd_cht_mc_driver) diff --git a/sound/soc/intel/boards/cht_bsw_nau8824.c b/sound/soc/intel/boards/cht_bsw_nau8824.c index 7651b83632fa..4afb292d4f13 100644 --- a/sound/soc/intel/boards/cht_bsw_nau8824.c +++ b/sound/soc/intel/boards/cht_bsw_nau8824.c @@ -193,8 +193,6 @@ static struct snd_soc_dai_link cht_dailink[] = { .stream_name = "Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &cht_aif1_ops, SND_SOC_DAILINK_REG(media, dummy, platform), }, @@ -203,7 +201,7 @@ static struct snd_soc_dai_link cht_dailink[] = { .stream_name = "Deep-Buffer Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, + .playback_only = 1, .ops = &cht_aif1_ops, SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), }, @@ -217,8 +215,6 @@ static struct snd_soc_dai_link cht_dailink[] = { | SND_SOC_DAIFMT_CBC_CFC, .init = cht_codec_init, .be_hw_params_fixup = cht_codec_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &cht_be_ssp2_ops, SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform), }, diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index eb41b7115d01..b977a2db73a3 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -448,8 +448,6 @@ static struct snd_soc_dai_link cht_dailink[] = { .stream_name = "Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &cht_aif1_ops, SND_SOC_DAILINK_REG(media, dummy, platform), }, @@ -458,7 +456,7 @@ static struct snd_soc_dai_link cht_dailink[] = { .stream_name = "Deep-Buffer Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, + .playback_only = 1, .ops = &cht_aif1_ops, SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), }, @@ -470,8 +468,6 @@ static struct snd_soc_dai_link cht_dailink[] = { .no_pcm = 1, .init = cht_codec_init, .be_hw_params_fixup = cht_codec_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &cht_be_ssp2_ops, SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform), }, @@ -569,7 +565,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) /* set correct codec name */ for (i = 0; i < ARRAY_SIZE(cht_dailink); i++) - if (cht_dailink[i].codecs->name && + if (cht_dailink[i].num_codecs && !strcmp(cht_dailink[i].codecs->name, "i2c-10EC5645:00")) { dai_index = i; @@ -582,7 +578,11 @@ static int snd_cht_mc_probe(struct platform_device *pdev) snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name), "i2c-%s", acpi_dev_name(adev)); cht_dailink[dai_index].codecs->name = cht_rt5645_codec_name; + } else { + dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id); + return -ENOENT; } + /* acpi_get_first_physical_node() returns a borrowed ref, no need to deref */ codec_dev = acpi_get_first_physical_node(adev); acpi_dev_put(adev); diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index be2d1a8dbca8..aaef212cf44e 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -358,8 +358,6 @@ static struct snd_soc_dai_link cht_dailink[] = { .stream_name = "Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &cht_aif1_ops, SND_SOC_DAILINK_REG(media, dummy, platform), }, @@ -368,7 +366,7 @@ static struct snd_soc_dai_link cht_dailink[] = { .stream_name = "Deep-Buffer Audio", .nonatomic = true, .dynamic = 1, - .dpcm_playback = 1, + .playback_only = 1, .ops = &cht_aif1_ops, SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), }, @@ -381,8 +379,6 @@ static struct snd_soc_dai_link cht_dailink[] = { .no_pcm = 1, .init = cht_codec_init, .be_hw_params_fixup = cht_codec_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &cht_be_ssp2_ops, SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform), }, @@ -466,7 +462,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) /* find index of codec dai */ for (i = 0; i < ARRAY_SIZE(cht_dailink); i++) { - if (cht_dailink[i].codecs->name && + if (cht_dailink[i].num_codecs && !strcmp(cht_dailink[i].codecs->name, RT5672_I2C_DEFAULT)) { dai_index = i; break; @@ -479,7 +475,11 @@ static int snd_cht_mc_probe(struct platform_device *pdev) snprintf(drv->codec_name, sizeof(drv->codec_name), "i2c-%s", acpi_dev_name(adev)); cht_dailink[dai_index].codecs->name = drv->codec_name; + } else { + dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id); + return -ENOENT; } + acpi_dev_put(adev); /* Use SSP0 on Bay Trail CR devices */ diff --git a/sound/soc/intel/boards/cml_rt1011_rt5682.c b/sound/soc/intel/boards/cml_rt1011_rt5682.c deleted file mode 100644 index 679a09b63ea5..000000000000 --- a/sound/soc/intel/boards/cml_rt1011_rt5682.c +++ /dev/null @@ -1,609 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright(c) 2019 Intel Corporation. - -/* - * Intel Cometlake I2S Machine driver for RT1011 + RT5682 codec - */ - -#include <linux/input.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/dmi.h> -#include <linux/slab.h> -#include <linux/acpi.h> -#include <sound/core.h> -#include <sound/jack.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> -#include <sound/rt5682.h> -#include <sound/soc-acpi.h> -#include "../../codecs/rt1011.h" -#include "../../codecs/rt5682.h" -#include "../../codecs/hdac_hdmi.h" -#include "hda_dsp_common.h" - -/* The platform clock outputs 24Mhz clock to codec as I2S MCLK */ -#define CML_PLAT_CLK 24000000 -#define CML_RT1011_CODEC_DAI "rt1011-aif" -#define CML_RT5682_CODEC_DAI "rt5682-aif1" -#define NAME_SIZE 32 - -#define SOF_RT1011_SPEAKER_WL BIT(0) -#define SOF_RT1011_SPEAKER_WR BIT(1) -#define SOF_RT1011_SPEAKER_TL BIT(2) -#define SOF_RT1011_SPEAKER_TR BIT(3) - -/* Default: Woofer speakers */ -static unsigned long sof_rt1011_quirk = SOF_RT1011_SPEAKER_WL | - SOF_RT1011_SPEAKER_WR; - -static int sof_rt1011_quirk_cb(const struct dmi_system_id *id) -{ - sof_rt1011_quirk = (unsigned long)id->driver_data; - return 1; -} - -static const struct dmi_system_id sof_rt1011_quirk_table[] = { - { - .callback = sof_rt1011_quirk_cb, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Google"), - DMI_MATCH(DMI_PRODUCT_NAME, "Helios"), - }, - .driver_data = (void *)(SOF_RT1011_SPEAKER_WL | SOF_RT1011_SPEAKER_WR | - SOF_RT1011_SPEAKER_TL | SOF_RT1011_SPEAKER_TR), - }, - { - } -}; - -static struct snd_soc_jack hdmi_jack[3]; - -struct hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct card_private { - char codec_name[SND_ACPI_I2C_ID_LEN]; - struct snd_soc_jack headset; - struct list_head hdmi_pcm_list; - bool common_hdmi_codec_drv; -}; - -static const struct snd_kcontrol_new cml_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("WL Ext Spk"), - SOC_DAPM_PIN_SWITCH("WR Ext Spk"), -}; - -static const struct snd_kcontrol_new cml_rt1011_tt_controls[] = { - SOC_DAPM_PIN_SWITCH("TL Ext Spk"), - SOC_DAPM_PIN_SWITCH("TR Ext Spk"), -}; - -static const struct snd_soc_dapm_widget cml_rt1011_rt5682_widgets[] = { - SND_SOC_DAPM_SPK("WL Ext Spk", NULL), - SND_SOC_DAPM_SPK("WR Ext Spk", NULL), - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - -static const struct snd_soc_dapm_widget cml_rt1011_tt_widgets[] = { - SND_SOC_DAPM_SPK("TL Ext Spk", NULL), - SND_SOC_DAPM_SPK("TR Ext Spk", NULL), -}; - -static const struct snd_soc_dapm_route cml_rt1011_rt5682_map[] = { - /*WL/WR speaker*/ - {"WL Ext Spk", NULL, "WL SPO"}, - {"WR Ext Spk", NULL, "WR SPO"}, - - /* HP jack connectors - unknown if we have jack detection */ - { "Headphone Jack", NULL, "HPOL" }, - { "Headphone Jack", NULL, "HPOR" }, - - /* other jacks */ - { "IN1P", NULL, "Headset Mic" }, - - /* DMIC */ - {"DMic", NULL, "SoC DMIC"}, -}; - -static const struct snd_soc_dapm_route cml_rt1011_tt_map[] = { - /*TL/TR speaker*/ - {"TL Ext Spk", NULL, "TL SPO" }, - {"TR Ext Spk", NULL, "TR SPO" }, -}; - -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, -}; - -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 = snd_soc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_jack *jack; - int ret; - - /* need to enable ASRC function for 24MHz mclk rate */ - rt5682_sel_asrc_clk_src(component, RT5682_DA_STEREO1_FILTER | - RT5682_AD_STEREO1_FILTER, - RT5682_CLK_SEL_I2S1_ASRC); - - /* - * Headset buttons map to the google Reference headset. - * These can be configured by userspace. - */ - ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | - SND_JACK_BTN_1 | SND_JACK_BTN_2 | - SND_JACK_BTN_3, - &ctx->headset, - jack_pins, - ARRAY_SIZE(jack_pins)); - if (ret) { - dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); - return ret; - } - - jack = &ctx->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); - if (ret) - dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); - - return ret; -}; - -static void cml_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; - - snd_soc_component_set_jack(component, NULL, NULL); -} - -static int cml_rt1011_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret = 0; - struct snd_soc_card *card = rtd->card; - - if (sof_rt1011_quirk & (SOF_RT1011_SPEAKER_TL | - SOF_RT1011_SPEAKER_TR)) { - - ret = snd_soc_add_card_controls(card, cml_rt1011_tt_controls, - ARRAY_SIZE(cml_rt1011_tt_controls)); - if (ret) - return ret; - - ret = snd_soc_dapm_new_controls(&card->dapm, - cml_rt1011_tt_widgets, - ARRAY_SIZE(cml_rt1011_tt_widgets)); - if (ret) - return ret; - - ret = snd_soc_dapm_add_routes(&card->dapm, cml_rt1011_tt_map, - ARRAY_SIZE(cml_rt1011_tt_map)); - - if (ret) - return ret; - } - - return ret; -} - -static int cml_rt5682_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - 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; - clk_freq = CML_PLAT_CLK; - - pll_out = params_rate(params) * 512; - - ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out); - if (ret < 0) - dev_warn(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret); - - /* Configure sysclk for codec */ - ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1, - pll_out, SND_SOC_CLOCK_IN); - if (ret < 0) - dev_warn(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); - - /* - * slot_width should be equal or large than data length, set them - * be the same - */ - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2, - params_width(params)); - if (ret < 0) - dev_warn(rtd->dev, "set TDM slot err:%d\n", ret); - return ret; -} - -static int cml_rt1011_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - 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; - - srate = params_rate(params); - - for_each_rtd_codec_dais(rtd, i, codec_dai) { - - /* 100 Fs to drive 24 bit data */ - ret = snd_soc_dai_set_pll(codec_dai, 0, RT1011_PLL1_S_BCLK, - 100 * srate, 256 * srate); - if (ret < 0) { - dev_err(card->dev, "codec_dai clock not set\n"); - return ret; - } - - ret = snd_soc_dai_set_sysclk(codec_dai, - RT1011_FS_SYS_PRE_S_PLL1, - 256 * srate, SND_SOC_CLOCK_IN); - if (ret < 0) { - dev_err(card->dev, "codec_dai clock not set\n"); - return ret; - } - - /* - * Codec TDM is configured as 24 bit capture/ playback. - * 2 CH PB is done over 4 codecs - 2 Woofers and 2 Tweeters. - * The Left woofer and tweeter plays the Left playback data - * and similar by the Right. - * Hence 2 codecs (1 T and 1 W pair) share same Rx slot. - * The feedback is captured for each codec individually. - * Hence all 4 codecs use 1 Tx slot each for feedback. - */ - if (sof_rt1011_quirk & (SOF_RT1011_SPEAKER_WL | - SOF_RT1011_SPEAKER_WR)) { - if (!strcmp(codec_dai->component->name, "i2c-10EC1011:00")) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, - 0x4, 0x1, 4, 24); - if (ret < 0) - break; - } - - if (!strcmp(codec_dai->component->name, "i2c-10EC1011:01")) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, - 0x8, 0x2, 4, 24); - if (ret < 0) - break; - } - } - - if (sof_rt1011_quirk & (SOF_RT1011_SPEAKER_TL | - SOF_RT1011_SPEAKER_TR)) { - if (!strcmp(codec_dai->component->name, "i2c-10EC1011:02")) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, - 0x1, 0x1, 4, 24); - if (ret < 0) - break; - } - - if (!strcmp(codec_dai->component->name, "i2c-10EC1011:03")) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, - 0x2, 0x2, 4, 24); - if (ret < 0) - break; - } - } - } - if (ret < 0) - dev_err(rtd->dev, - "set codec TDM slot for %s failed with error %d\n", - codec_dai->component->name, ret); - return ret; -} - -static struct snd_soc_ops cml_rt5682_ops = { - .hw_params = cml_rt5682_hw_params, -}; - -static const struct snd_soc_ops cml_rt1011_ops = { - .hw_params = cml_rt1011_hw_params, -}; - -static int sof_card_late_probe(struct snd_soc_card *card) -{ - struct card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component = NULL; - char jack_name[NAME_SIZE]; - struct hdmi_pcm *pcm; - int ret, i = 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 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); - ret = snd_soc_card_jack_new(card, jack_name, - SND_JACK_AVOUT, &hdmi_jack[i]); - if (ret) - return ret; - - ret = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &hdmi_jack[i]); - if (ret < 0) - return ret; - - i++; - } - - return hdac_hdmi_jack_port_init(component, &card->dapm); -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = dai->id; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -/* Cometlake digital audio interface glue - connects codec <--> CPU */ - -SND_SOC_DAILINK_DEF(ssp0_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); -SND_SOC_DAILINK_DEF(ssp0_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", - CML_RT5682_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(ssp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); -SND_SOC_DAILINK_DEF(ssp1_codec_2spk, - DAILINK_COMP_ARRAY( - /* WL */ COMP_CODEC("i2c-10EC1011:00", CML_RT1011_CODEC_DAI), - /* WR */ COMP_CODEC("i2c-10EC1011:01", CML_RT1011_CODEC_DAI))); -SND_SOC_DAILINK_DEF(ssp1_codec_4spk, - DAILINK_COMP_ARRAY( - /* WL */ COMP_CODEC("i2c-10EC1011:00", CML_RT1011_CODEC_DAI), - /* WR */ COMP_CODEC("i2c-10EC1011:01", CML_RT1011_CODEC_DAI), - /* TL */ COMP_CODEC("i2c-10EC1011:02", CML_RT1011_CODEC_DAI), - /* TR */ COMP_CODEC("i2c-10EC1011:03", CML_RT1011_CODEC_DAI))); - - -SND_SOC_DAILINK_DEF(dmic_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); - -SND_SOC_DAILINK_DEF(dmic16k_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin"))); - -SND_SOC_DAILINK_DEF(dmic_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); - -static struct snd_soc_dai_link cml_rt1011_rt5682_dailink[] = { - /* Back End DAI links */ - { - /* SSP0 - Codec */ - .name = "SSP0-Codec", - .id = 0, - .init = cml_rt5682_codec_init, - .exit = cml_rt5682_codec_exit, - .ignore_pmdown_time = 1, - .ops = &cml_rt5682_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, - .no_pcm = 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), - }, - { - /* - * SSP1 - Codec : added to end of list ensuring - * reuse of common topologies for other end points - * and changing only SSP1's codec - */ - .name = "SSP1-Codec", - .id = 6, - .dpcm_playback = 1, - .dpcm_capture = 1, /* Capture stream provides Feedback */ - .no_pcm = 1, - .init = cml_rt1011_spk_init, - .ops = &cml_rt1011_ops, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec_2spk, platform), - }, -}; - -static struct snd_soc_codec_conf rt1011_conf[] = { - { - .dlc = COMP_CODEC_CONF("i2c-10EC1011:00"), - .name_prefix = "WL", - }, - { - .dlc = COMP_CODEC_CONF("i2c-10EC1011:01"), - .name_prefix = "WR", - }, - /* single configuration structure for 2 and 4 channels */ - { - .dlc = COMP_CODEC_CONF("i2c-10EC1011:02"), - .name_prefix = "TL", - }, - { - .dlc = COMP_CODEC_CONF("i2c-10EC1011:03"), - .name_prefix = "TR", - }, -}; - -/* Cometlake audio machine driver for RT1011 and RT5682 */ -static struct snd_soc_card snd_soc_card_cml = { - .name = "cml_rt1011_rt5682", - .owner = THIS_MODULE, - .dai_link = cml_rt1011_rt5682_dailink, - .num_links = ARRAY_SIZE(cml_rt1011_rt5682_dailink), - .codec_conf = rt1011_conf, - .num_configs = ARRAY_SIZE(rt1011_conf), - .dapm_widgets = cml_rt1011_rt5682_widgets, - .num_dapm_widgets = ARRAY_SIZE(cml_rt1011_rt5682_widgets), - .dapm_routes = cml_rt1011_rt5682_map, - .num_dapm_routes = ARRAY_SIZE(cml_rt1011_rt5682_map), - .controls = cml_controls, - .num_controls = ARRAY_SIZE(cml_controls), - .fully_routed = true, - .late_probe = sof_card_late_probe, -}; - -static int snd_cml_rt1011_probe(struct platform_device *pdev) -{ - struct snd_soc_dai_link *dai_link; - struct card_private *ctx; - struct snd_soc_acpi_mach *mach; - const char *platform_name; - int ret, i; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - mach = pdev->dev.platform_data; - snd_soc_card_cml.dev = &pdev->dev; - platform_name = mach->mach_params.platform; - - dmi_check_system(sof_rt1011_quirk_table); - - dev_dbg(&pdev->dev, "sof_rt1011_quirk = %lx\n", sof_rt1011_quirk); - - /* when 4 speaker is available, update codec config */ - if (sof_rt1011_quirk & (SOF_RT1011_SPEAKER_TL | - SOF_RT1011_SPEAKER_TR)) { - for_each_card_prelinks(&snd_soc_card_cml, i, dai_link) { - if (!strcmp(dai_link->codecs[0].dai_name, - CML_RT1011_CODEC_DAI)) { - dai_link->codecs = ssp1_codec_4spk; - dai_link->num_codecs = ARRAY_SIZE(ssp1_codec_4spk); - } - } - } - - /* set platform name for each dailink */ - ret = snd_soc_fixup_dai_links_platform_name(&snd_soc_card_cml, - platform_name); - if (ret) - return ret; - - ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; - - snd_soc_card_set_drvdata(&snd_soc_card_cml, ctx); - - return devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cml); -} - -static struct platform_driver snd_cml_rt1011_rt5682_driver = { - .probe = snd_cml_rt1011_probe, - .driver = { - .name = "cml_rt1011_rt5682", - .pm = &snd_soc_pm_ops, - }, -}; -module_platform_driver(snd_cml_rt1011_rt5682_driver); - -/* Module information */ -MODULE_DESCRIPTION("Cometlake Audio Machine driver - RT1011 and RT5682 in I2S mode"); -MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>"); -MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>"); -MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>"); -MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:cml_rt1011_rt5682"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); diff --git a/sound/soc/intel/boards/ehl_rt5660.c b/sound/soc/intel/boards/ehl_rt5660.c index 686e60321224..5c7b218f22b7 100644 --- a/sound/soc/intel/boards/ehl_rt5660.c +++ b/sound/soc/intel/boards/ehl_rt5660.c @@ -132,7 +132,7 @@ static int rt5660_hw_params(struct snd_pcm_substream *substream, return ret; } -static struct snd_soc_ops rt5660_ops = { +static const struct snd_soc_ops rt5660_ops = { .hw_params = rt5660_hw_params, }; @@ -178,8 +178,6 @@ static struct snd_soc_dai_link ehl_rt5660_dailink[] = { .name = "SSP0-Codec", .id = 0, .no_pcm = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &rt5660_ops, SND_SOC_DAILINK_REG(ssp0_pin, rt5660_codec, platform), }, @@ -187,7 +185,7 @@ static struct snd_soc_dai_link ehl_rt5660_dailink[] = { .name = "dmic48k", .id = 1, .ignore_suspend = 1, - .dpcm_capture = 1, + .capture_only = 1, .no_pcm = 1, SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), }, @@ -195,7 +193,7 @@ static struct snd_soc_dai_link ehl_rt5660_dailink[] = { .name = "dmic16k", .id = 2, .ignore_suspend = 1, - .dpcm_capture = 1, + .capture_only = 1, .no_pcm = 1, SND_SOC_DAILINK_REG(dmic16k, dmic_codec, platform), }, @@ -203,7 +201,7 @@ static struct snd_soc_dai_link ehl_rt5660_dailink[] = { .name = "iDisp1", .id = 5, .init = hdmi_init, - .dpcm_playback = 1, + .playback_only = 1, .no_pcm = 1, SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), }, @@ -211,7 +209,7 @@ static struct snd_soc_dai_link ehl_rt5660_dailink[] = { .name = "iDisp2", .id = 6, .init = hdmi_init, - .dpcm_playback = 1, + .playback_only = 1, .no_pcm = 1, SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), }, @@ -219,7 +217,7 @@ static struct snd_soc_dai_link ehl_rt5660_dailink[] = { .name = "iDisp3", .id = 7, .init = hdmi_init, - .dpcm_playback = 1, + .playback_only = 1, .no_pcm = 1, SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), }, @@ -227,7 +225,7 @@ static struct snd_soc_dai_link ehl_rt5660_dailink[] = { .name = "iDisp4", .id = 8, .init = hdmi_init, - .dpcm_playback = 1, + .playback_only = 1, .no_pcm = 1, SND_SOC_DAILINK_REG(idisp4_pin, idisp4_codec, platform), }, @@ -256,8 +254,7 @@ static void hdmi_link_init(struct snd_soc_card *card, { int i; - if (mach->mach_params.common_hdmi_codec_drv && - (mach->mach_params.codec_mask & IDISP_CODEC_MASK)) { + if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) { ctx->idisp_codec = true; return; } @@ -316,4 +313,4 @@ module_platform_driver(snd_ehl_rt5660_driver); MODULE_DESCRIPTION("ASoC Intel(R) Elkhartlake + rt5660 Machine driver"); MODULE_AUTHOR("libin.yang@intel.com"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON"); diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c b/sound/soc/intel/boards/glk_rt5682_max98357a.c deleted file mode 100644 index 657e4658234c..000000000000 --- a/sound/soc/intel/boards/glk_rt5682_max98357a.c +++ /dev/null @@ -1,691 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright(c) 2018 Intel Corporation. - -/* - * Intel Geminilake I2S Machine Driver with MAX98357A & RT5682 Codecs - * - * Modified from: - * Intel Apollolake I2S Machine driver - */ - -#include <linux/input.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/jack.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include "../../codecs/rt5682.h" -#include "../../codecs/rt5682s.h" -#include "../../codecs/hdac_hdmi.h" -#include "hda_dsp_common.h" - -/* The platform clock outputs 19.2Mhz clock to codec as I2S MCLK */ -#define GLK_PLAT_CLK_FREQ 19200000 -#define RT5682_PLL_FREQ (48000 * 512) -#define RT5682_DAI_NAME "rt5682-aif1" -#define RT5682S_DAI_NAME "rt5682s-aif1" -#define GLK_MAXIM_CODEC_DAI "HiFi" -#define RT5682_DEV0_NAME "i2c-10EC5682:00" -#define RT5682S_DEV0_NAME "i2c-RTL5682:00" -#define MAXIM_DEV0_NAME "MX98357A:00" -#define DUAL_CHANNEL 2 -#define QUAD_CHANNEL 4 -#define NAME_SIZE 32 - -static struct snd_soc_jack geminilake_hdmi[3]; - -struct glk_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct glk_card_private { - struct snd_soc_jack geminilake_headset; - struct list_head hdmi_pcm_list; - bool common_hdmi_codec_drv; - int is_rt5682s; -}; - -enum { - GLK_DPCM_AUDIO_PB = 0, - GLK_DPCM_AUDIO_CP, - GLK_DPCM_AUDIO_HS_PB, - GLK_DPCM_AUDIO_ECHO_REF_CP, - GLK_DPCM_AUDIO_REF_CP, - GLK_DPCM_AUDIO_DMIC_CP, - GLK_DPCM_AUDIO_HDMI1_PB, - GLK_DPCM_AUDIO_HDMI2_PB, - GLK_DPCM_AUDIO_HDMI3_PB, -}; - -static const struct snd_kcontrol_new geminilake_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Spk"), -}; - -static const struct snd_soc_dapm_widget geminilake_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("Spk", NULL), - SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("HDMI1", NULL), - SND_SOC_DAPM_SPK("HDMI2", NULL), - SND_SOC_DAPM_SPK("HDMI3", NULL), -}; - -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, -}; - -static const struct snd_soc_dapm_route geminilake_map[] = { - /* HP jack connectors - unknown if we have jack detection */ - { "Headphone Jack", NULL, "HPOL" }, - { "Headphone Jack", NULL, "HPOR" }, - - /* speaker */ - { "Spk", NULL, "Speaker" }, - - /* other jacks */ - { "IN1P", NULL, "Headset Mic" }, - - /* digital mics */ - { "DMic", NULL, "SoC DMIC" }, - - /* CODEC BE connections */ - { "HiFi Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec0_out" }, - - { "AIF1 Playback", NULL, "ssp2 Tx" }, - { "ssp2 Tx", NULL, "codec1_out" }, - - { "codec0_in", NULL, "ssp2 Rx" }, - { "ssp2 Rx", NULL, "AIF1 Capture" }, - - { "HDMI1", NULL, "hif5-0 Output" }, - { "HDMI2", NULL, "hif6-0 Output" }, - { "HDMI2", NULL, "hif7-0 Output" }, - - { "hifi3", NULL, "iDisp3 Tx" }, - { "iDisp3 Tx", NULL, "iDisp3_out" }, - { "hifi2", NULL, "iDisp2 Tx" }, - { "iDisp2 Tx", NULL, "iDisp2_out" }, - { "hifi1", NULL, "iDisp1 Tx" }, - { "iDisp1 Tx", NULL, "iDisp1_out" }, - - /* DMIC */ - { "dmic01_hifi", NULL, "DMIC01 Rx" }, - { "DMIC01 Rx", NULL, "DMIC AIF" }, -}; - -static int geminilake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - - /* The ADSP will convert the FE rate to 48k, stereo */ - rate->min = rate->max = 48000; - chan->min = chan->max = DUAL_CHANNEL; - - /* set SSP to 24 bit */ - snd_mask_none(fmt); - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); - - return 0; -} - -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 = 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; - - if (ctx->is_rt5682s) { - pll_id = RT5682S_PLL2; - pll_source = RT5682S_PLL_S_MCLK; - clk_id = RT5682S_SCLK_S_PLL2; - } else { - pll_id = RT5682_PLL1; - pll_source = RT5682_PLL1_S_MCLK; - clk_id = RT5682_SCLK_S_PLL1; - } - - ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, - GLK_PLAT_CLK_FREQ, RT5682_PLL_FREQ); - if (ret < 0) { - dev_err(rtd->dev, "can't set codec pll: %d\n", ret); - return ret; - } - - /* Configure sysclk for codec */ - ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, - RT5682_PLL_FREQ, SND_SOC_CLOCK_IN); - if (ret < 0) - dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); - - /* - * Headset buttons map to the google Reference headset. - * These can be configured by userspace. - */ - ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, - &ctx->geminilake_headset, - jack_pins, - ARRAY_SIZE(jack_pins)); - if (ret) { - dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); - return ret; - } - - jack = &ctx->geminilake_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); - - if (ret) { - dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); - return ret; - } - - return ret; -}; - -static int geminilake_rt5682_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - 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 */ - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2, 24); - if (ret < 0) { - dev_err(rtd->dev, "set TDM slot err:%d\n", ret); - return ret; - } - - return ret; -} - -static struct snd_soc_ops geminilake_rt5682_ops = { - .hw_params = geminilake_rt5682_hw_params, -}; - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct glk_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = GLK_DPCM_AUDIO_HDMI1_PB + dai->id; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -static int geminilake_rt5682_fe_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; - struct snd_soc_dapm_context *dapm; - int ret; - - dapm = snd_soc_component_get_dapm(component); - ret = snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); - if (ret) { - dev_err(rtd->dev, "Ref Cap ignore suspend failed %d\n", ret); - return ret; - } - - return ret; -} - -static const unsigned int rates[] = { - 48000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static unsigned int channels_quad[] = { - QUAD_CHANNEL, -}; - -static struct snd_pcm_hw_constraint_list constraints_channels_quad = { - .count = ARRAY_SIZE(channels_quad), - .list = channels_quad, - .mask = 0, -}; - -static int geminilake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - /* - * set BE channel constraint as user FE channels - */ - chan->min = chan->max = 4; - - return 0; -} - -static int geminilake_dmic_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels_quad); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); -} - -static const struct snd_soc_ops geminilake_dmic_ops = { - .startup = geminilake_dmic_startup, -}; - -static const unsigned int rates_16000[] = { - 16000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_16000 = { - .count = ARRAY_SIZE(rates_16000), - .list = rates_16000, -}; - -static int geminilake_refcap_startup(struct snd_pcm_substream *substream) -{ - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &constraints_16000); -}; - -static const struct snd_soc_ops geminilake_refcap_ops = { - .startup = geminilake_refcap_startup, -}; - -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); - -SND_SOC_DAILINK_DEF(system2, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin2"))); - -SND_SOC_DAILINK_DEF(echoref, - DAILINK_COMP_ARRAY(COMP_CPU("Echoref Pin"))); - -SND_SOC_DAILINK_DEF(reference, - DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); - -SND_SOC_DAILINK_DEF(dmic, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); - -SND_SOC_DAILINK_DEF(hdmi1, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi2, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi3, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); - -SND_SOC_DAILINK_DEF(ssp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); -SND_SOC_DAILINK_DEF(ssp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC(MAXIM_DEV0_NAME, - GLK_MAXIM_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(ssp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP2 Pin"))); -SND_SOC_DAILINK_DEF(ssp2_codec_5682, - DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME, - RT5682_DAI_NAME))); -SND_SOC_DAILINK_DEF(ssp2_codec_5682s, - DAILINK_COMP_ARRAY(COMP_CODEC(RT5682S_DEV0_NAME, - RT5682S_DAI_NAME))); - -SND_SOC_DAILINK_DEF(dmic_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); -SND_SOC_DAILINK_DEF(dmic_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:0e.0"))); - -/* geminilake digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link geminilake_dais[] = { - /* Front End DAI links */ - [GLK_DPCM_AUDIO_PB] = { - .name = "Glk Audio Port", - .stream_name = "Audio", - .dynamic = 1, - .nonatomic = 1, - .init = geminilake_rt5682_fe_init, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [GLK_DPCM_AUDIO_CP] = { - .name = "Glk Audio Capture Port", - .stream_name = "Audio Record", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [GLK_DPCM_AUDIO_HS_PB] = { - .name = "Glk Audio Headset Playback", - .stream_name = "Headset Audio", - .dpcm_playback = 1, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(system2, dummy, platform), - }, - [GLK_DPCM_AUDIO_ECHO_REF_CP] = { - .name = "Glk Audio Echo Reference cap", - .stream_name = "Echoreference Capture", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(echoref, dummy, platform), - }, - [GLK_DPCM_AUDIO_REF_CP] = { - .name = "Glk Audio Reference cap", - .stream_name = "Refcap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &geminilake_refcap_ops, - SND_SOC_DAILINK_REG(reference, dummy, platform), - }, - [GLK_DPCM_AUDIO_DMIC_CP] = { - .name = "Glk Audio DMIC cap", - .stream_name = "dmiccap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &geminilake_dmic_ops, - SND_SOC_DAILINK_REG(dmic, dummy, platform), - }, - [GLK_DPCM_AUDIO_HDMI1_PB] = { - .name = "Glk HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [GLK_DPCM_AUDIO_HDMI2_PB] = { - .name = "Glk HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - [GLK_DPCM_AUDIO_HDMI3_PB] = { - .name = "Glk HDMI Port3", - .stream_name = "Hdmi3", - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi3, dummy, platform), - }, - /* Back End DAI links */ - { - /* SSP1 - Codec */ - .name = "SSP1-Codec", - .id = 0, - .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = geminilake_ssp_fixup, - .dpcm_playback = 1, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), - }, - { - /* SSP2 - Codec */ - .name = "SSP2-Codec", - .id = 1, - .no_pcm = 1, - .init = geminilake_rt5682_codec_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = geminilake_ssp_fixup, - .ops = &geminilake_rt5682_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp2_pin, ssp2_codec_5682, platform), - }, - { - .name = "dmic01", - .id = 2, - .ignore_suspend = 1, - .be_hw_params_fixup = geminilake_dmic_fixup, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), - }, - { - .name = "iDisp1", - .id = 3, - .init = geminilake_hdmi_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 4, - .init = geminilake_hdmi_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, - { - .name = "iDisp3", - .id = 5, - .init = geminilake_hdmi_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), - }, -}; - -static int glk_card_late_probe(struct snd_soc_card *card) -{ - struct glk_card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component = NULL; - char jack_name[NAME_SIZE]; - struct glk_hdmi_pcm *pcm; - int err; - int i = 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 glk_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, &geminilake_hdmi[i]); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &geminilake_hdmi[i]); - if (err < 0) - return err; - - i++; - } - - return hdac_hdmi_jack_port_init(component, &card->dapm); -} - -/* geminilake audio machine driver for SPT + RT5682 */ -static struct snd_soc_card glk_audio_card_rt5682_m98357a = { - .name = "glkrt5682max", - .owner = THIS_MODULE, - .dai_link = geminilake_dais, - .num_links = ARRAY_SIZE(geminilake_dais), - .controls = geminilake_controls, - .num_controls = ARRAY_SIZE(geminilake_controls), - .dapm_widgets = geminilake_widgets, - .num_dapm_widgets = ARRAY_SIZE(geminilake_widgets), - .dapm_routes = geminilake_map, - .num_dapm_routes = ARRAY_SIZE(geminilake_map), - .fully_routed = true, - .late_probe = glk_card_late_probe, -}; - -static int geminilake_audio_probe(struct platform_device *pdev) -{ - struct glk_card_private *ctx; - struct snd_soc_acpi_mach *mach; - const char *platform_name; - struct snd_soc_card *card; - int ret, i; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - /* Detect the headset codec variant */ - if (acpi_dev_present("RTL5682", NULL, -1)) { - /* ALC5682I-VS is detected */ - ctx->is_rt5682s = 1; - - for (i = 0; i < glk_audio_card_rt5682_m98357a.num_links; i++) { - if (strcmp(geminilake_dais[i].name, "SSP2-Codec")) - continue; - - /* update the dai link to use rt5682s codec */ - geminilake_dais[i].codecs = ssp2_codec_5682s; - geminilake_dais[i].num_codecs = ARRAY_SIZE(ssp2_codec_5682s); - break; - } - } - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - - card = &glk_audio_card_rt5682_m98357a; - card->dev = &pdev->dev; - snd_soc_card_set_drvdata(card, ctx); - - /* override platform name, if required */ - mach = pdev->dev.platform_data; - platform_name = mach->mach_params.platform; - - ret = snd_soc_fixup_dai_links_platform_name(card, platform_name); - if (ret) - return ret; - - ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; - - return devm_snd_soc_register_card(&pdev->dev, card); -} - -static const struct platform_device_id glk_board_ids[] = { - { - .name = "glk_rt5682_mx98357a", - .driver_data = - (kernel_ulong_t)&glk_audio_card_rt5682_m98357a, - }, - { } -}; -MODULE_DEVICE_TABLE(platform, glk_board_ids); - -static struct platform_driver geminilake_audio = { - .probe = geminilake_audio_probe, - .driver = { - .name = "glk_rt5682_max98357a", - .pm = &snd_soc_pm_ops, - }, - .id_table = glk_board_ids, -}; -module_platform_driver(geminilake_audio) - -/* Module information */ -MODULE_DESCRIPTION("Geminilake Audio Machine driver-RT5682 & MAX98357A in I2S mode"); -MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>"); -MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); -MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); diff --git a/sound/soc/intel/boards/hda_dsp_common.c b/sound/soc/intel/boards/hda_dsp_common.c index 04b7d4f7f9e2..86e541a2c204 100644 --- a/sound/soc/intel/boards/hda_dsp_common.c +++ b/sound/soc/intel/boards/hda_dsp_common.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only // -// Copyright(c) 2019 Intel Corporation. All rights reserved. +// Copyright(c) 2019 Intel Corporation #include <linux/module.h> #include <sound/pcm.h> @@ -83,7 +83,7 @@ int hda_dsp_hdmi_build_controls(struct snd_soc_card *card, return err; } -EXPORT_SYMBOL_NS(hda_dsp_hdmi_build_controls, SND_SOC_INTEL_HDA_DSP_COMMON); +EXPORT_SYMBOL_NS(hda_dsp_hdmi_build_controls, "SND_SOC_INTEL_HDA_DSP_COMMON"); #endif diff --git a/sound/soc/intel/boards/hsw_rt5640.c b/sound/soc/intel/boards/hsw_rt5640.c index 2a2fe27dff0e..9bb2822ba63e 100644 --- a/sound/soc/intel/boards/hsw_rt5640.c +++ b/sound/soc/intel/boards/hsw_rt5640.c @@ -2,7 +2,7 @@ /* * Sound card driver for Intel Haswell Lynx Point with Realtek 5640 * - * Copyright (C) 2013, Intel Corporation. All rights reserved. + * Copyright (C) 2013, Intel Corporation */ #include <linux/module.h> @@ -85,8 +85,6 @@ static struct snd_soc_dai_link card_dai_links[] = { .nonatomic = 1, .dynamic = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .dpcm_capture = 1, SND_SOC_DAILINK_REG(system, dummy, platform), }, { @@ -95,7 +93,7 @@ static struct snd_soc_dai_link card_dai_links[] = { .nonatomic = 1, .dynamic = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, + .playback_only = 1, SND_SOC_DAILINK_REG(offload0, dummy, platform), }, { @@ -104,7 +102,7 @@ static struct snd_soc_dai_link card_dai_links[] = { .nonatomic = 1, .dynamic = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, + .playback_only = 1, SND_SOC_DAILINK_REG(offload1, dummy, platform), }, { @@ -113,7 +111,7 @@ static struct snd_soc_dai_link card_dai_links[] = { .nonatomic = 1, .dynamic = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, + .capture_only = 1, SND_SOC_DAILINK_REG(loopback, dummy, platform), }, /* Back End DAI links */ @@ -127,8 +125,6 @@ static struct snd_soc_dai_link card_dai_links[] = { .ignore_pmdown_time = 1, .be_hw_params_fixup = codec_link_hw_params_fixup, .ops = &codec_link_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, SND_SOC_DAILINK_REG(ssp0_port, codec, platform), }, }; diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c deleted file mode 100644 index a5d8965303a8..000000000000 --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c +++ /dev/null @@ -1,687 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright(c) 2017-18 Intel Corporation. - -/* - * Intel Kabylake I2S Machine Driver with MAX98357A & DA7219 Codecs - * - * Modified from: - * Intel Kabylake I2S Machine driver supporting MAXIM98927 and - * RT5663 codecs - */ - -#include <linux/input.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/jack.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> -#include "../../codecs/da7219.h" -#include "../../codecs/hdac_hdmi.h" - -#define KBL_DIALOG_CODEC_DAI "da7219-hifi" -#define KBL_MAXIM_CODEC_DAI "HiFi" -#define MAXIM_DEV0_NAME "MX98357A:00" -#define DUAL_CHANNEL 2 -#define QUAD_CHANNEL 4 - -static struct snd_soc_card *kabylake_audio_card; -static struct snd_soc_jack skylake_hdmi[3]; - -struct kbl_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct kbl_codec_private { - struct snd_soc_jack kabylake_headset; - struct list_head hdmi_pcm_list; -}; - -enum { - KBL_DPCM_AUDIO_PB = 0, - KBL_DPCM_AUDIO_CP, - KBL_DPCM_AUDIO_REF_CP, - KBL_DPCM_AUDIO_DMIC_CP, - KBL_DPCM_AUDIO_HDMI1_PB, - KBL_DPCM_AUDIO_HDMI2_PB, - KBL_DPCM_AUDIO_HDMI3_PB, -}; - -static int platform_clock_control(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; - struct snd_soc_dai *codec_dai; - int ret = 0; - - codec_dai = snd_soc_card_get_codec_dai(card, KBL_DIALOG_CODEC_DAI); - if (!codec_dai) { - dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n"); - return -EIO; - } - - if (SND_SOC_DAPM_EVENT_OFF(event)) { - ret = snd_soc_dai_set_pll(codec_dai, 0, - DA7219_SYSCLK_MCLK, 0, 0); - if (ret) - dev_err(card->dev, "failed to stop PLL: %d\n", ret); - } else if (SND_SOC_DAPM_EVENT_ON(event)) { - ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL_SRM, - 0, DA7219_PLL_FREQ_OUT_98304); - if (ret) - dev_err(card->dev, "failed to start PLL: %d\n", ret); - } - - return ret; -} - -static const struct snd_kcontrol_new kabylake_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Spk"), - SOC_DAPM_PIN_SWITCH("Line Out"), -}; - -static const struct snd_soc_dapm_widget kabylake_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("Spk", NULL), - SND_SOC_DAPM_LINE("Line Out", NULL), - SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("HDMI1", NULL), - SND_SOC_DAPM_SPK("HDMI2", NULL), - SND_SOC_DAPM_SPK("HDMI3", NULL), - SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, - platform_clock_control, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), -}; - -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, - { - .pin = "Line Out", - .mask = SND_JACK_LINEOUT, - }, -}; - -static const struct snd_soc_dapm_route kabylake_map[] = { - { "Headphone Jack", NULL, "HPL" }, - { "Headphone Jack", NULL, "HPR" }, - - /* speaker */ - { "Spk", NULL, "Speaker" }, - - /* other jacks */ - { "MIC", NULL, "Headset Mic" }, - { "DMic", NULL, "SoC DMIC" }, - - {"HDMI1", NULL, "hif5-0 Output"}, - {"HDMI2", NULL, "hif6-0 Output"}, - {"HDMI3", NULL, "hif7-0 Output"}, - - /* CODEC BE connections */ - { "HiFi Playback", NULL, "ssp0 Tx" }, - { "ssp0 Tx", NULL, "codec0_out" }, - - { "Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec1_out" }, - - { "codec0_in", NULL, "ssp1 Rx" }, - { "ssp1 Rx", NULL, "Capture" }, - - /* DMIC */ - { "dmic01_hifi", NULL, "DMIC01 Rx" }, - { "DMIC01 Rx", NULL, "DMIC AIF" }, - - { "hifi1", NULL, "iDisp1 Tx" }, - { "iDisp1 Tx", NULL, "iDisp1_out" }, - { "hifi2", NULL, "iDisp2 Tx" }, - { "iDisp2 Tx", NULL, "iDisp2_out" }, - { "hifi3", NULL, "iDisp3 Tx"}, - { "iDisp3 Tx", NULL, "iDisp3_out"}, - - { "Headphone Jack", NULL, "Platform Clock" }, - { "Headset Mic", NULL, "Platform Clock" }, - { "Line Out", NULL, "Platform Clock" }, -}; - -static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - - /* The ADSP will convert the FE rate to 48k, stereo */ - rate->min = rate->max = 48000; - chan->min = chan->max = DUAL_CHANNEL; - - /* set SSP to 24 bit */ - snd_mask_none(fmt); - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); - - return 0; -} - -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 = 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; - - /* Configure sysclk for codec */ - ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 24576000, - SND_SOC_CLOCK_IN); - if (ret) { - dev_err(rtd->dev, "can't set codec sysclk configuration\n"); - return ret; - } - - /* - * Headset buttons map to the google Reference headset. - * These can be configured by userspace. - */ - ret = snd_soc_card_jack_new_pins(kabylake_audio_card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, - &ctx->kabylake_headset, - jack_pins, - ARRAY_SIZE(jack_pins)); - if (ret) { - dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); - return ret; - } - - jack = &ctx->kabylake_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, &ctx->kabylake_headset, NULL); - - ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); - if (ret) - dev_err(rtd->dev, "SoC DMIC - Ignore suspend failed %d\n", ret); - - return ret; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct kbl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = device; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB); -} - -static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB); -} - -static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB); -} - -static int kabylake_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dapm_context *dapm; - 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"); - - return 0; -} - -static const unsigned int rates[] = { - 48000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static const unsigned int channels[] = { - DUAL_CHANNEL, -}; - -static const struct snd_pcm_hw_constraint_list constraints_channels = { - .count = ARRAY_SIZE(channels), - .list = channels, - .mask = 0, -}; - -static unsigned int channels_quad[] = { - QUAD_CHANNEL, -}; - -static struct snd_pcm_hw_constraint_list constraints_channels_quad = { - .count = ARRAY_SIZE(channels_quad), - .list = channels_quad, - .mask = 0, -}; - -static int kbl_fe_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - /* - * On this platform for PCM device we support, - * 48Khz - * stereo - * 16 bit audio - */ - - runtime->hw.channels_max = DUAL_CHANNEL; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels); - - runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; - snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); - - snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); - - return 0; -} - -static const struct snd_soc_ops kabylake_da7219_fe_ops = { - .startup = kbl_fe_startup, -}; - -static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - /* - * set BE channel constraint as user FE channels - */ - - if (params_channels(params) == 2) - chan->min = chan->max = 2; - else - chan->min = chan->max = 4; - - return 0; -} - -static int kabylake_dmic_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels_quad); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); -} - -static struct snd_soc_ops kabylake_dmic_ops = { - .startup = kabylake_dmic_startup, -}; - -static unsigned int rates_16000[] = { - 16000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_16000 = { - .count = ARRAY_SIZE(rates_16000), - .list = rates_16000, -}; - -static const unsigned int ch_mono[] = { - 1, -}; - -static const struct snd_pcm_hw_constraint_list constraints_refcap = { - .count = ARRAY_SIZE(ch_mono), - .list = ch_mono, -}; - -static int kabylake_refcap_startup(struct snd_pcm_substream *substream) -{ - substream->runtime->hw.channels_max = 1; - snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_refcap); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &constraints_16000); -} - -static struct snd_soc_ops skylake_refcap_ops = { - .startup = kabylake_refcap_startup, -}; - -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); - -SND_SOC_DAILINK_DEF(reference, - DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); - -SND_SOC_DAILINK_DEF(dmic, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); - -SND_SOC_DAILINK_DEF(hdmi1, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi2, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi3, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); - -SND_SOC_DAILINK_DEF(ssp0_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); -SND_SOC_DAILINK_DEF(ssp0_codec, - DAILINK_COMP_ARRAY(COMP_CODEC(MAXIM_DEV0_NAME, - KBL_MAXIM_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(ssp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); -SND_SOC_DAILINK_DEF(ssp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00", - KBL_DIALOG_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(dmic_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); -SND_SOC_DAILINK_DEF(dmic_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", - "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); - -/* kabylake digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link kabylake_dais[] = { - /* Front End DAI links */ - [KBL_DPCM_AUDIO_PB] = { - .name = "Kbl Audio Port", - .stream_name = "Audio", - .dynamic = 1, - .nonatomic = 1, - .init = kabylake_da7219_fe_init, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .ops = &kabylake_da7219_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [KBL_DPCM_AUDIO_CP] = { - .name = "Kbl Audio Capture Port", - .stream_name = "Audio Record", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, - .ops = &kabylake_da7219_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [KBL_DPCM_AUDIO_REF_CP] = { - .name = "Kbl Audio Reference cap", - .stream_name = "Wake on Voice", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &skylake_refcap_ops, - SND_SOC_DAILINK_REG(reference, dummy, platform), - }, - [KBL_DPCM_AUDIO_DMIC_CP] = { - .name = "Kbl Audio DMIC cap", - .stream_name = "dmiccap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &kabylake_dmic_ops, - SND_SOC_DAILINK_REG(dmic, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI1_PB] = { - .name = "Kbl HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI2_PB] = { - .name = "Kbl HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI3_PB] = { - .name = "Kbl HDMI Port3", - .stream_name = "Hdmi3", - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi3, dummy, platform), - }, - - /* Back End DAI links */ - { - /* SSP0 - Codec */ - .name = "SSP0-Codec", - .id = 0, - .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = kabylake_ssp_fixup, - .dpcm_playback = 1, - SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform), - }, - { - /* SSP1 - Codec */ - .name = "SSP1-Codec", - .id = 1, - .no_pcm = 1, - .init = kabylake_da7219_codec_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = kabylake_ssp_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), - }, - { - .name = "dmic01", - .id = 2, - .be_hw_params_fixup = kabylake_dmic_fixup, - .ignore_suspend = 1, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), - }, - { - .name = "iDisp1", - .id = 3, - .dpcm_playback = 1, - .init = kabylake_hdmi1_init, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 4, - .init = kabylake_hdmi2_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, - { - .name = "iDisp3", - .id = 5, - .init = kabylake_hdmi3_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), - }, -}; - -#define NAME_SIZE 32 -static int kabylake_card_late_probe(struct snd_soc_card *card) -{ - struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card); - struct kbl_hdmi_pcm *pcm; - struct snd_soc_component *component = NULL; - int err, i = 0; - char jack_name[NAME_SIZE]; - - 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, &skylake_hdmi[i]); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &skylake_hdmi[i]); - if (err < 0) - return err; - - i++; - - } - - if (!component) - return -EINVAL; - - return hdac_hdmi_jack_port_init(component, &card->dapm); -} - -/* kabylake audio machine driver for SPT + DA7219 */ -static struct snd_soc_card kabylake_audio_card_da7219_m98357a = { - .name = "kblda7219max", - .owner = THIS_MODULE, - .dai_link = kabylake_dais, - .num_links = ARRAY_SIZE(kabylake_dais), - .controls = kabylake_controls, - .num_controls = ARRAY_SIZE(kabylake_controls), - .dapm_widgets = kabylake_widgets, - .num_dapm_widgets = ARRAY_SIZE(kabylake_widgets), - .dapm_routes = kabylake_map, - .num_dapm_routes = ARRAY_SIZE(kabylake_map), - .fully_routed = true, - .late_probe = kabylake_card_late_probe, -}; - -static int kabylake_audio_probe(struct platform_device *pdev) -{ - struct kbl_codec_private *ctx; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - - kabylake_audio_card = - (struct snd_soc_card *)pdev->id_entry->driver_data; - - kabylake_audio_card->dev = &pdev->dev; - snd_soc_card_set_drvdata(kabylake_audio_card, ctx); - return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card); -} - -static const struct platform_device_id kbl_board_ids[] = { - { - .name = "kbl_da7219_mx98357a", - .driver_data = - (kernel_ulong_t)&kabylake_audio_card_da7219_m98357a, - }, - { } -}; -MODULE_DEVICE_TABLE(platform, kbl_board_ids); - -static struct platform_driver kabylake_audio = { - .probe = kabylake_audio_probe, - .driver = { - .name = "kbl_da7219_max98357a", - .pm = &snd_soc_pm_ops, - }, - .id_table = kbl_board_ids, -}; - -module_platform_driver(kabylake_audio) - -/* Module information */ -MODULE_DESCRIPTION("Audio Machine driver-DA7219 & MAX98357A in I2S mode"); -MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c deleted file mode 100644 index 98c11ec0adc0..000000000000 --- a/sound/soc/intel/boards/kbl_da7219_max98927.c +++ /dev/null @@ -1,1171 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright(c) 2018 Intel Corporation. - -/* - * Intel Kabylake I2S Machine Driver with MAX98927, MAX98373 & DA7219 Codecs - * - * Modified from: - * Intel Kabylake I2S Machine driver supporting MAX98927 and - * RT5663 codecs - */ - -#include <linux/input.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/jack.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> -#include "../../codecs/da7219.h" -#include "../../codecs/hdac_hdmi.h" - -#define KBL_DIALOG_CODEC_DAI "da7219-hifi" -#define MAX98927_CODEC_DAI "max98927-aif1" -#define MAX98927_DEV0_NAME "i2c-MX98927:00" -#define MAX98927_DEV1_NAME "i2c-MX98927:01" - -#define MAX98373_CODEC_DAI "max98373-aif1" -#define MAX98373_DEV0_NAME "i2c-MX98373:00" -#define MAX98373_DEV1_NAME "i2c-MX98373:01" - - -#define DUAL_CHANNEL 2 -#define QUAD_CHANNEL 4 -#define NAME_SIZE 32 - -static struct snd_soc_card *kabylake_audio_card; -static struct snd_soc_jack kabylake_hdmi[3]; - -struct kbl_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct kbl_codec_private { - struct snd_soc_jack kabylake_headset; - struct list_head hdmi_pcm_list; -}; - -enum { - KBL_DPCM_AUDIO_PB = 0, - KBL_DPCM_AUDIO_ECHO_REF_CP, - KBL_DPCM_AUDIO_REF_CP, - KBL_DPCM_AUDIO_DMIC_CP, - KBL_DPCM_AUDIO_HDMI1_PB, - KBL_DPCM_AUDIO_HDMI2_PB, - KBL_DPCM_AUDIO_HDMI3_PB, - KBL_DPCM_AUDIO_HS_PB, - KBL_DPCM_AUDIO_CP, -}; - -static int platform_clock_control(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; - struct snd_soc_dai *codec_dai; - int ret = 0; - - codec_dai = snd_soc_card_get_codec_dai(card, KBL_DIALOG_CODEC_DAI); - if (!codec_dai) { - dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n"); - return -EIO; - } - - /* Configure sysclk for codec */ - ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 24576000, - SND_SOC_CLOCK_IN); - if (ret) { - dev_err(card->dev, "can't set codec sysclk configuration\n"); - return ret; - } - - if (SND_SOC_DAPM_EVENT_OFF(event)) { - ret = snd_soc_dai_set_pll(codec_dai, 0, - DA7219_SYSCLK_MCLK, 0, 0); - if (ret) - dev_err(card->dev, "failed to stop PLL: %d\n", ret); - } else if (SND_SOC_DAPM_EVENT_ON(event)) { - ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL_SRM, - 0, DA7219_PLL_FREQ_OUT_98304); - if (ret) - dev_err(card->dev, "failed to start PLL: %d\n", ret); - } - - return ret; -} - -static const struct snd_kcontrol_new kabylake_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Left Spk"), - SOC_DAPM_PIN_SWITCH("Right Spk"), - SOC_DAPM_PIN_SWITCH("Line Out"), -}; - -static const struct snd_soc_dapm_widget kabylake_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("Left Spk", NULL), - SND_SOC_DAPM_SPK("Right Spk", NULL), - SND_SOC_DAPM_LINE("Line Out", NULL), - SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("HDMI1", NULL), - SND_SOC_DAPM_SPK("HDMI2", NULL), - SND_SOC_DAPM_SPK("HDMI3", NULL), - SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, - platform_clock_control, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), -}; - -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, - { - .pin = "Line Out", - .mask = SND_JACK_MICROPHONE, - }, -}; - -static const struct snd_soc_dapm_route kabylake_map[] = { - /* speaker */ - { "Left Spk", NULL, "Left BE_OUT" }, - { "Right Spk", NULL, "Right BE_OUT" }, - - /* other jacks */ - { "DMic", NULL, "SoC DMIC" }, - - {"HDMI1", NULL, "hif5-0 Output"}, - {"HDMI2", NULL, "hif6-0 Output"}, - {"HDMI3", NULL, "hif7-0 Output"}, - - /* CODEC BE connections */ - { "Left HiFi Playback", NULL, "ssp0 Tx" }, - { "Right HiFi Playback", NULL, "ssp0 Tx" }, - { "ssp0 Tx", NULL, "spk_out" }, - - /* IV feedback path */ - { "codec0_fb_in", NULL, "ssp0 Rx"}, - { "ssp0 Rx", NULL, "Left HiFi Capture" }, - { "ssp0 Rx", NULL, "Right HiFi Capture" }, - - /* AEC capture path */ - { "echo_ref_out", NULL, "ssp0 Rx" }, - - /* DMIC */ - { "dmic01_hifi", NULL, "DMIC01 Rx" }, - { "DMIC01 Rx", NULL, "DMIC AIF" }, - - { "hifi1", NULL, "iDisp1 Tx" }, - { "iDisp1 Tx", NULL, "iDisp1_out" }, - { "hifi2", NULL, "iDisp2 Tx" }, - { "iDisp2 Tx", NULL, "iDisp2_out" }, - { "hifi3", NULL, "iDisp3 Tx"}, - { "iDisp3 Tx", NULL, "iDisp3_out"}, -}; - -static const struct snd_soc_dapm_route kabylake_ssp1_map[] = { - { "Headphone Jack", NULL, "HPL" }, - { "Headphone Jack", NULL, "HPR" }, - - /* other jacks */ - { "MIC", NULL, "Headset Mic" }, - - /* CODEC BE connections */ - { "Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec1_out" }, - - { "hs_in", NULL, "ssp1 Rx" }, - { "ssp1 Rx", NULL, "Capture" }, - - { "Headphone Jack", NULL, "Platform Clock" }, - { "Headset Mic", NULL, "Platform Clock" }, - { "Line Out", NULL, "Platform Clock" }, -}; - -static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *runtime = snd_soc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai; - int ret, j; - - for_each_rtd_codec_dais(runtime, j, codec_dai) { - - if (!strcmp(codec_dai->component->name, MAX98927_DEV0_NAME)) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); - if (ret < 0) { - dev_err(runtime->dev, "DEV0 TDM slot err:%d\n", ret); - return ret; - } - } - if (!strcmp(codec_dai->component->name, MAX98927_DEV1_NAME)) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16); - if (ret < 0) { - dev_err(runtime->dev, "DEV1 TDM slot err:%d\n", ret); - return ret; - } - } - if (!strcmp(codec_dai->component->name, MAX98373_DEV0_NAME)) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, - 0x30, 3, 8, 16); - if (ret < 0) { - dev_err(runtime->dev, - "DEV0 TDM slot err:%d\n", ret); - return ret; - } - } - if (!strcmp(codec_dai->component->name, MAX98373_DEV1_NAME)) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, - 0xC0, 3, 8, 16); - if (ret < 0) { - dev_err(runtime->dev, - "DEV1 TDM slot err:%d\n", ret); - return ret; - } - } - } - - return 0; -} - -static int kabylake_ssp0_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai; - int j, ret; - - for_each_rtd_codec_dais(rtd, j, codec_dai) { - const char *name = codec_dai->component->name; - struct snd_soc_component *component = codec_dai->component; - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); - char pin_name[20]; - - if (strcmp(name, MAX98927_DEV0_NAME) && - strcmp(name, MAX98927_DEV1_NAME) && - strcmp(name, MAX98373_DEV0_NAME) && - strcmp(name, MAX98373_DEV1_NAME)) - continue; - - snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk", - codec_dai->component->name_prefix); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - ret = snd_soc_dapm_enable_pin(dapm, pin_name); - if (ret) { - dev_err(rtd->dev, "failed to enable %s: %d\n", - pin_name, ret); - return ret; - } - snd_soc_dapm_sync(dapm); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - ret = snd_soc_dapm_disable_pin(dapm, pin_name); - if (ret) { - dev_err(rtd->dev, "failed to disable %s: %d\n", - pin_name, ret); - return ret; - } - snd_soc_dapm_sync(dapm); - break; - } - } - - return 0; -} - -static struct snd_soc_ops kabylake_ssp0_ops = { - .hw_params = kabylake_ssp0_hw_params, - .trigger = kabylake_ssp0_trigger, -}; - -static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - struct snd_soc_dpcm *dpcm, *rtd_dpcm = NULL; - - /* - * The following loop will be called only for playback stream - * In this platform, there is only one playback device on every SSP - */ - for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_PLAYBACK, dpcm) { - rtd_dpcm = dpcm; - break; - } - - /* - * This following loop will be called only for capture stream - * In this platform, there is only one capture device on every SSP - */ - for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_CAPTURE, dpcm) { - rtd_dpcm = dpcm; - break; - } - - if (!rtd_dpcm) - return -EINVAL; - - /* - * The above 2 loops are mutually exclusive based on the stream direction, - * thus rtd_dpcm variable will never be overwritten - */ - - /* - * The ADSP will convert the FE rate to 48k, stereo, 24 bit - */ - if (!strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Port") || - !strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Headset Playback") || - !strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Capture Port")) { - rate->min = rate->max = 48000; - chan->min = chan->max = 2; - snd_mask_none(fmt); - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); - } - - /* - * The speaker on the SSP0 supports S16_LE and not S24_LE. - * thus changing the mask here - */ - if (!strcmp(rtd_dpcm->be->dai_link->name, "SSP0-Codec")) - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); - - return 0; -} - -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 = snd_soc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_jack *jack; - struct snd_soc_card *card = rtd->card; - int ret; - - - ret = snd_soc_dapm_add_routes(&card->dapm, - kabylake_ssp1_map, - ARRAY_SIZE(kabylake_ssp1_map)); - - if (ret) - return ret; - - /* - * Headset buttons map to the google Reference headset. - * These can be configured by userspace. - */ - ret = snd_soc_card_jack_new_pins(kabylake_audio_card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, - &ctx->kabylake_headset, - jack_pins, - ARRAY_SIZE(jack_pins)); - if (ret) { - dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); - return ret; - } - - jack = &ctx->kabylake_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, &ctx->kabylake_headset, NULL); - - return 0; -} - -static int kabylake_dmic_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret; - ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); - if (ret) - dev_err(rtd->dev, "SoC DMIC - Ignore suspend failed %d\n", ret); - - return ret; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct kbl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = device; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB); -} - -static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB); -} - -static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB); -} - -static int kabylake_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dapm_context *dapm; - 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"); - - return 0; -} - -static const unsigned int rates[] = { - 48000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static const unsigned int channels[] = { - DUAL_CHANNEL, -}; - -static const struct snd_pcm_hw_constraint_list constraints_channels = { - .count = ARRAY_SIZE(channels), - .list = channels, - .mask = 0, -}; - -static unsigned int channels_quad[] = { - QUAD_CHANNEL, -}; - -static struct snd_pcm_hw_constraint_list constraints_channels_quad = { - .count = ARRAY_SIZE(channels_quad), - .list = channels_quad, - .mask = 0, -}; - -static int kbl_fe_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - /* - * On this platform for PCM device we support, - * 48Khz - * stereo - * 16 bit audio - */ - - runtime->hw.channels_max = DUAL_CHANNEL; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels); - - runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; - snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); - - snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); - - return 0; -} - -static const struct snd_soc_ops kabylake_da7219_fe_ops = { - .startup = kbl_fe_startup, -}; - -static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - /* - * set BE channel constraint as user FE channels - */ - - if (params_channels(params) == 2) - chan->min = chan->max = 2; - else - chan->min = chan->max = 4; - - return 0; -} - -static int kabylake_dmic_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels_quad); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); -} - -static struct snd_soc_ops kabylake_dmic_ops = { - .startup = kabylake_dmic_startup, -}; - -static const unsigned int rates_16000[] = { - 16000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_16000 = { - .count = ARRAY_SIZE(rates_16000), - .list = rates_16000, -}; - -static const unsigned int ch_mono[] = { - 1, -}; -static const struct snd_pcm_hw_constraint_list constraints_refcap = { - .count = ARRAY_SIZE(ch_mono), - .list = ch_mono, -}; - -static int kabylake_refcap_startup(struct snd_pcm_substream *substream) -{ - substream->runtime->hw.channels_max = 1; - snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_refcap); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &constraints_16000); -} - - -static struct snd_soc_ops skylake_refcap_ops = { - .startup = kabylake_refcap_startup, -}; - -static struct snd_soc_codec_conf max98927_codec_conf[] = { - - { - .dlc = COMP_CODEC_CONF(MAX98927_DEV0_NAME), - .name_prefix = "Right", - }, - - { - .dlc = COMP_CODEC_CONF(MAX98927_DEV1_NAME), - .name_prefix = "Left", - }, -}; - -static struct snd_soc_codec_conf max98373_codec_conf[] = { - - { - .dlc = COMP_CODEC_CONF(MAX98373_DEV0_NAME), - .name_prefix = "Right", - }, - - { - .dlc = COMP_CODEC_CONF(MAX98373_DEV1_NAME), - .name_prefix = "Left", - }, -}; - -static struct snd_soc_dai_link_component max98373_ssp0_codec_components[] = { - { /* Left */ - .name = MAX98373_DEV0_NAME, - .dai_name = MAX98373_CODEC_DAI, - }, - - { /* For Right */ - .name = MAX98373_DEV1_NAME, - .dai_name = MAX98373_CODEC_DAI, - }, - -}; - -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); - -SND_SOC_DAILINK_DEF(echoref, - DAILINK_COMP_ARRAY(COMP_CPU("Echoref Pin"))); - -SND_SOC_DAILINK_DEF(reference, - DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); - -SND_SOC_DAILINK_DEF(dmic, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); - -SND_SOC_DAILINK_DEF(hdmi1, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi2, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi3, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); - -SND_SOC_DAILINK_DEF(system2, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin2"))); - -SND_SOC_DAILINK_DEF(ssp0_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); -SND_SOC_DAILINK_DEF(ssp0_codec, - DAILINK_COMP_ARRAY( - /* Left */ COMP_CODEC(MAX98927_DEV0_NAME, MAX98927_CODEC_DAI), - /* For Right */ COMP_CODEC(MAX98927_DEV1_NAME, MAX98927_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(ssp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); -SND_SOC_DAILINK_DEF(ssp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00", - KBL_DIALOG_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(dmic_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); -SND_SOC_DAILINK_DEF(dmic_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); - -/* kabylake digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link kabylake_dais[] = { - /* Front End DAI links */ - [KBL_DPCM_AUDIO_PB] = { - .name = "Kbl Audio Port", - .stream_name = "Audio", - .dynamic = 1, - .nonatomic = 1, - .init = kabylake_da7219_fe_init, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .ops = &kabylake_da7219_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [KBL_DPCM_AUDIO_ECHO_REF_CP] = { - .name = "Kbl Audio Echo Reference cap", - .stream_name = "Echoreference Capture", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - SND_SOC_DAILINK_REG(echoref, dummy, platform), - }, - [KBL_DPCM_AUDIO_REF_CP] = { - .name = "Kbl Audio Reference cap", - .stream_name = "Wake on Voice", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &skylake_refcap_ops, - SND_SOC_DAILINK_REG(reference, dummy, platform), - }, - [KBL_DPCM_AUDIO_DMIC_CP] = { - .name = "Kbl Audio DMIC cap", - .stream_name = "dmiccap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &kabylake_dmic_ops, - SND_SOC_DAILINK_REG(dmic, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI1_PB] = { - .name = "Kbl HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI2_PB] = { - .name = "Kbl HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI3_PB] = { - .name = "Kbl HDMI Port3", - .stream_name = "Hdmi3", - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi3, dummy, platform), - }, - [KBL_DPCM_AUDIO_HS_PB] = { - .name = "Kbl Audio Headset Playback", - .stream_name = "Headset Audio", - .dpcm_playback = 1, - .nonatomic = 1, - .dynamic = 1, - .init = kabylake_da7219_fe_init, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .ops = &kabylake_da7219_fe_ops, - SND_SOC_DAILINK_REG(system2, dummy, platform), - }, - [KBL_DPCM_AUDIO_CP] = { - .name = "Kbl Audio Capture Port", - .stream_name = "Audio Record", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, - .ops = &kabylake_da7219_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - - /* Back End DAI links */ - { - /* SSP0 - Codec */ - .name = "SSP0-Codec", - .id = 0, - .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_DSP_B | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .dpcm_playback = 1, - .dpcm_capture = 1, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = kabylake_ssp_fixup, - .ops = &kabylake_ssp0_ops, - SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform), - }, - { - /* SSP1 - Codec */ - .name = "SSP1-Codec", - .id = 1, - .no_pcm = 1, - .init = kabylake_da7219_codec_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = kabylake_ssp_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), - }, - { - .name = "dmic01", - .id = 2, - .init = kabylake_dmic_init, - .be_hw_params_fixup = kabylake_dmic_fixup, - .ignore_suspend = 1, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), - }, - { - .name = "iDisp1", - .id = 3, - .dpcm_playback = 1, - .init = kabylake_hdmi1_init, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 4, - .init = kabylake_hdmi2_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, - { - .name = "iDisp3", - .id = 5, - .init = kabylake_hdmi3_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), - }, -}; - -/* kabylake digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link kabylake_max98_927_373_dais[] = { - /* Front End DAI links */ - [KBL_DPCM_AUDIO_PB] = { - .name = "Kbl Audio Port", - .stream_name = "Audio", - .dynamic = 1, - .nonatomic = 1, - .init = kabylake_da7219_fe_init, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .ops = &kabylake_da7219_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [KBL_DPCM_AUDIO_ECHO_REF_CP] = { - .name = "Kbl Audio Echo Reference cap", - .stream_name = "Echoreference Capture", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - SND_SOC_DAILINK_REG(echoref, dummy, platform), - }, - [KBL_DPCM_AUDIO_REF_CP] = { - .name = "Kbl Audio Reference cap", - .stream_name = "Wake on Voice", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &skylake_refcap_ops, - SND_SOC_DAILINK_REG(reference, dummy, platform), - }, - [KBL_DPCM_AUDIO_DMIC_CP] = { - .name = "Kbl Audio DMIC cap", - .stream_name = "dmiccap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &kabylake_dmic_ops, - SND_SOC_DAILINK_REG(dmic, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI1_PB] = { - .name = "Kbl HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI2_PB] = { - .name = "Kbl HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI3_PB] = { - .name = "Kbl HDMI Port3", - .stream_name = "Hdmi3", - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi3, dummy, platform), - }, - - /* Back End DAI links */ - { - /* SSP0 - Codec */ - .name = "SSP0-Codec", - .id = 0, - .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_DSP_B | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .dpcm_playback = 1, - .dpcm_capture = 1, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = kabylake_ssp_fixup, - .ops = &kabylake_ssp0_ops, - SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec), - }, - { - .name = "dmic01", - .id = 1, - .init = kabylake_dmic_init, - .be_hw_params_fixup = kabylake_dmic_fixup, - .ignore_suspend = 1, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), - }, - { - .name = "iDisp1", - .id = 2, - .dpcm_playback = 1, - .init = kabylake_hdmi1_init, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 3, - .init = kabylake_hdmi2_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, - { - .name = "iDisp3", - .id = 4, - .init = kabylake_hdmi3_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), - }, -}; - -static int kabylake_card_late_probe(struct snd_soc_card *card) -{ - struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card); - struct kbl_hdmi_pcm *pcm; - struct snd_soc_dapm_context *dapm = &card->dapm; - struct snd_soc_component *component = NULL; - int err, i = 0; - char jack_name[NAME_SIZE]; - - 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, &kabylake_hdmi[i]); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &kabylake_hdmi[i]); - if (err < 0) - return err; - - i++; - } - - if (!component) - return -EINVAL; - - - err = hdac_hdmi_jack_port_init(component, &card->dapm); - - if (err < 0) - return err; - - err = snd_soc_dapm_disable_pin(dapm, "Left Spk"); - if (err) { - dev_err(card->dev, "failed to disable Left Spk: %d\n", err); - return err; - } - - err = snd_soc_dapm_disable_pin(dapm, "Right Spk"); - if (err) { - dev_err(card->dev, "failed to disable Right Spk: %d\n", err); - return err; - } - - return snd_soc_dapm_sync(dapm); -} - -/* kabylake audio machine driver for SPT + DA7219 */ -static struct snd_soc_card kbl_audio_card_da7219_m98927 = { - .name = "kblda7219m98927", - .owner = THIS_MODULE, - .dai_link = kabylake_dais, - .num_links = ARRAY_SIZE(kabylake_dais), - .controls = kabylake_controls, - .num_controls = ARRAY_SIZE(kabylake_controls), - .dapm_widgets = kabylake_widgets, - .num_dapm_widgets = ARRAY_SIZE(kabylake_widgets), - .dapm_routes = kabylake_map, - .num_dapm_routes = ARRAY_SIZE(kabylake_map), - .codec_conf = max98927_codec_conf, - .num_configs = ARRAY_SIZE(max98927_codec_conf), - .fully_routed = true, - .late_probe = kabylake_card_late_probe, -}; - -/* kabylake audio machine driver for Maxim98927 */ -static struct snd_soc_card kbl_audio_card_max98927 = { - .name = "kblmax98927", - .owner = THIS_MODULE, - .dai_link = kabylake_max98_927_373_dais, - .num_links = ARRAY_SIZE(kabylake_max98_927_373_dais), - .controls = kabylake_controls, - .num_controls = ARRAY_SIZE(kabylake_controls), - .dapm_widgets = kabylake_widgets, - .num_dapm_widgets = ARRAY_SIZE(kabylake_widgets), - .dapm_routes = kabylake_map, - .num_dapm_routes = ARRAY_SIZE(kabylake_map), - .codec_conf = max98927_codec_conf, - .num_configs = ARRAY_SIZE(max98927_codec_conf), - .fully_routed = true, - .late_probe = kabylake_card_late_probe, -}; - -static struct snd_soc_card kbl_audio_card_da7219_m98373 = { - .name = "kblda7219m98373", - .owner = THIS_MODULE, - .dai_link = kabylake_dais, - .num_links = ARRAY_SIZE(kabylake_dais), - .controls = kabylake_controls, - .num_controls = ARRAY_SIZE(kabylake_controls), - .dapm_widgets = kabylake_widgets, - .num_dapm_widgets = ARRAY_SIZE(kabylake_widgets), - .dapm_routes = kabylake_map, - .num_dapm_routes = ARRAY_SIZE(kabylake_map), - .codec_conf = max98373_codec_conf, - .num_configs = ARRAY_SIZE(max98373_codec_conf), - .fully_routed = true, - .late_probe = kabylake_card_late_probe, -}; - -static struct snd_soc_card kbl_audio_card_max98373 = { - .name = "kblmax98373", - .owner = THIS_MODULE, - .dai_link = kabylake_max98_927_373_dais, - .num_links = ARRAY_SIZE(kabylake_max98_927_373_dais), - .controls = kabylake_controls, - .num_controls = ARRAY_SIZE(kabylake_controls), - .dapm_widgets = kabylake_widgets, - .num_dapm_widgets = ARRAY_SIZE(kabylake_widgets), - .dapm_routes = kabylake_map, - .num_dapm_routes = ARRAY_SIZE(kabylake_map), - .codec_conf = max98373_codec_conf, - .num_configs = ARRAY_SIZE(max98373_codec_conf), - .fully_routed = true, - .late_probe = kabylake_card_late_probe, -}; - -static int kabylake_audio_probe(struct platform_device *pdev) -{ - struct kbl_codec_private *ctx; - struct snd_soc_dai_link *kbl_dai_link; - struct snd_soc_dai_link_component **codecs; - int i; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - - kabylake_audio_card = - (struct snd_soc_card *)pdev->id_entry->driver_data; - - kbl_dai_link = kabylake_audio_card->dai_link; - - /* Update codecs for SSP0 with max98373 codec info */ - if (!strcmp(pdev->name, "kbl_da7219_max98373") || - (!strcmp(pdev->name, "kbl_max98373"))) { - for (i = 0; i < kabylake_audio_card->num_links; ++i) { - if (strcmp(kbl_dai_link[i].name, "SSP0-Codec")) - continue; - - codecs = &(kbl_dai_link[i].codecs); - *codecs = max98373_ssp0_codec_components; - kbl_dai_link[i].num_codecs = - ARRAY_SIZE(max98373_ssp0_codec_components); - break; - } - } - kabylake_audio_card->dev = &pdev->dev; - snd_soc_card_set_drvdata(kabylake_audio_card, ctx); - - return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card); -} - -static const struct platform_device_id kbl_board_ids[] = { - { - .name = "kbl_da7219_max98927", - .driver_data = - (kernel_ulong_t)&kbl_audio_card_da7219_m98927, - }, - { - .name = "kbl_max98927", - .driver_data = - (kernel_ulong_t)&kbl_audio_card_max98927, - }, - { - .name = "kbl_da7219_max98373", - .driver_data = - (kernel_ulong_t)&kbl_audio_card_da7219_m98373, - }, - { - .name = "kbl_max98373", - .driver_data = - (kernel_ulong_t)&kbl_audio_card_max98373, - }, - { } -}; -MODULE_DEVICE_TABLE(platform, kbl_board_ids); - -static struct platform_driver kabylake_audio = { - .probe = kabylake_audio_probe, - .driver = { - .name = "kbl_da7219_max98_927_373", - .pm = &snd_soc_pm_ops, - }, - .id_table = kbl_board_ids, -}; - -module_platform_driver(kabylake_audio) - -/* Module information */ -MODULE_DESCRIPTION("Audio KabyLake Machine driver for MAX98927/MAX98373 & DA7219"); -MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/boards/kbl_rt5660.c b/sound/soc/intel/boards/kbl_rt5660.c deleted file mode 100644 index 30e0aca161cd..000000000000 --- a/sound/soc/intel/boards/kbl_rt5660.c +++ /dev/null @@ -1,566 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright(c) 2018-19 Canonical Corporation. - -/* - * Intel Kabylake I2S Machine Driver with RT5660 Codec - * - * Modified from: - * Intel Kabylake I2S Machine driver supporting MAXIM98357a and - * DA7219 codecs - * Also referred to: - * Intel Broadwell I2S Machine driver supporting RT5677 codec - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/gpio/consumer.h> -#include <linux/acpi.h> -#include <sound/core.h> -#include <sound/jack.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> - -#include "../../codecs/hdac_hdmi.h" -#include "../../codecs/rt5660.h" - -#define KBL_RT5660_CODEC_DAI "rt5660-aif1" -#define DUAL_CHANNEL 2 - -static struct snd_soc_card *kabylake_audio_card; -static struct snd_soc_jack skylake_hdmi[3]; -static struct snd_soc_jack lineout_jack; -static struct snd_soc_jack mic_jack; - -struct kbl_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct kbl_codec_private { - struct gpio_desc *gpio_lo_mute; - struct list_head hdmi_pcm_list; -}; - -enum { - KBL_DPCM_AUDIO_PB = 0, - KBL_DPCM_AUDIO_CP, - KBL_DPCM_AUDIO_HDMI1_PB, - KBL_DPCM_AUDIO_HDMI2_PB, - KBL_DPCM_AUDIO_HDMI3_PB, -}; - -#define GPIO_LINEOUT_MUTE_INDEX 0 -#define GPIO_LINEOUT_DET_INDEX 3 -#define GPIO_LINEIN_DET_INDEX 4 - -static const struct acpi_gpio_params lineout_mute_gpio = { GPIO_LINEOUT_MUTE_INDEX, 0, true }; -static const struct acpi_gpio_params lineout_det_gpio = { GPIO_LINEOUT_DET_INDEX, 0, false }; -static const struct acpi_gpio_params mic_det_gpio = { GPIO_LINEIN_DET_INDEX, 0, false }; - - -static const struct acpi_gpio_mapping acpi_rt5660_gpios[] = { - { "lineout-mute-gpios", &lineout_mute_gpio, 1 }, - { "lineout-det-gpios", &lineout_det_gpio, 1 }, - { "mic-det-gpios", &mic_det_gpio, 1 }, - { NULL }, -}; - -static struct snd_soc_jack_pin lineout_jack_pin = { - .pin = "Line Out", - .mask = SND_JACK_LINEOUT, -}; - -static struct snd_soc_jack_pin mic_jack_pin = { - .pin = "Line In", - .mask = SND_JACK_MICROPHONE, -}; - -static struct snd_soc_jack_gpio lineout_jack_gpio = { - .name = "lineout-det", - .report = SND_JACK_LINEOUT, - .debounce_time = 200, -}; - -static struct snd_soc_jack_gpio mic_jack_gpio = { - .name = "mic-det", - .report = SND_JACK_MICROPHONE, - .debounce_time = 200, -}; - -static int kabylake_5660_event_lineout(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_dapm_context *dapm = w->dapm; - struct kbl_codec_private *priv = snd_soc_card_get_drvdata(dapm->card); - - gpiod_set_value_cansleep(priv->gpio_lo_mute, - !(SND_SOC_DAPM_EVENT_ON(event))); - - return 0; -} - -static const struct snd_kcontrol_new kabylake_rt5660_controls[] = { - SOC_DAPM_PIN_SWITCH("Line In"), - SOC_DAPM_PIN_SWITCH("Line Out"), -}; - -static const struct snd_soc_dapm_widget kabylake_rt5660_widgets[] = { - SND_SOC_DAPM_MIC("Line In", NULL), - SND_SOC_DAPM_LINE("Line Out", kabylake_5660_event_lineout), -}; - -static const struct snd_soc_dapm_route kabylake_rt5660_map[] = { - /* other jacks */ - {"IN1P", NULL, "Line In"}, - {"IN2P", NULL, "Line In"}, - {"Line Out", NULL, "LOUTR"}, - {"Line Out", NULL, "LOUTL"}, - - /* CODEC BE connections */ - { "AIF1 Playback", NULL, "ssp0 Tx"}, - { "ssp0 Tx", NULL, "codec0_out"}, - - { "codec0_in", NULL, "ssp0 Rx" }, - { "ssp0 Rx", NULL, "AIF1 Capture" }, - - { "hifi1", NULL, "iDisp1 Tx"}, - { "iDisp1 Tx", NULL, "iDisp1_out"}, - { "hifi2", NULL, "iDisp2 Tx"}, - { "iDisp2 Tx", NULL, "iDisp2_out"}, - { "hifi3", NULL, "iDisp3 Tx"}, - { "iDisp3 Tx", NULL, "iDisp3_out"}, -}; - -static int kabylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - - /* The ADSP will convert the FE rate to 48k, stereo */ - rate->min = rate->max = 48000; - chan->min = chan->max = DUAL_CHANNEL; - - /* set SSP0 to 24 bit */ - snd_mask_none(fmt); - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); - - return 0; -} - -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 = 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); - if (ret) - dev_warn(component->dev, "Failed to add driver gpios\n"); - - /* Request rt5660 GPIO for lineout mute control, return if fails */ - ctx->gpio_lo_mute = gpiod_get(component->dev, "lineout-mute", - GPIOD_OUT_HIGH); - if (IS_ERR(ctx->gpio_lo_mute)) { - dev_err(component->dev, "Can't find GPIO_MUTE# gpio\n"); - return PTR_ERR(ctx->gpio_lo_mute); - } - - /* Create and initialize headphone jack, this jack is not mandatory, don't return if fails */ - ret = snd_soc_card_jack_new_pins(rtd->card, "Lineout Jack", - SND_JACK_LINEOUT, &lineout_jack, - &lineout_jack_pin, 1); - if (ret) - dev_warn(component->dev, "Can't create Lineout jack\n"); - else { - lineout_jack_gpio.gpiod_dev = component->dev; - ret = snd_soc_jack_add_gpios(&lineout_jack, 1, - &lineout_jack_gpio); - if (ret) - dev_warn(component->dev, "Can't add Lineout jack gpio\n"); - } - - /* Create and initialize mic jack, this jack is not mandatory, don't return if fails */ - ret = snd_soc_card_jack_new_pins(rtd->card, "Mic Jack", - SND_JACK_MICROPHONE, &mic_jack, - &mic_jack_pin, 1); - if (ret) - dev_warn(component->dev, "Can't create mic jack\n"); - else { - mic_jack_gpio.gpiod_dev = component->dev; - ret = snd_soc_jack_add_gpios(&mic_jack, 1, &mic_jack_gpio); - if (ret) - dev_warn(component->dev, "Can't add mic jack gpio\n"); - } - - /* Here we enable some dapms in advance to reduce the pop noise for recording via line-in */ - snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); - snd_soc_dapm_force_enable_pin(dapm, "BST1"); - snd_soc_dapm_force_enable_pin(dapm, "BST2"); - - return 0; -} - -static void kabylake_rt5660_codec_exit(struct snd_soc_pcm_runtime *rtd) -{ - struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - - /* - * The .exit() can be reached without going through the .init() - * so explicitly test if the gpiod is valid - */ - if (!IS_ERR_OR_NULL(ctx->gpio_lo_mute)) - gpiod_put(ctx->gpio_lo_mute); -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct kbl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = device; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB); -} - -static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB); -} - -static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB); -} - -static int kabylake_rt5660_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - 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, - RT5660_SCLK_S_PLL1, params_rate(params) * 512, - SND_SOC_CLOCK_IN); - if (ret < 0) { - dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); - return ret; - } - - ret = snd_soc_dai_set_pll(codec_dai, 0, - RT5660_PLL1_S_BCLK, - params_rate(params) * 50, - params_rate(params) * 512); - if (ret < 0) - dev_err(codec_dai->dev, "can't set codec pll: %d\n", ret); - - return ret; -} - -static struct snd_soc_ops kabylake_rt5660_ops = { - .hw_params = kabylake_rt5660_hw_params, -}; - -static const unsigned int rates[] = { - 48000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static const unsigned int channels[] = { - DUAL_CHANNEL, -}; - -static const struct snd_pcm_hw_constraint_list constraints_channels = { - .count = ARRAY_SIZE(channels), - .list = channels, - .mask = 0, -}; - -static int kbl_fe_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - /* - * On this platform for PCM device we support, - * 48Khz - * stereo - * 16 bit audio - */ - - runtime->hw.channels_max = DUAL_CHANNEL; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels); - - runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; - snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); - - snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); - - return 0; -} - -static const struct snd_soc_ops kabylake_rt5660_fe_ops = { - .startup = kbl_fe_startup, -}; - -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); - -SND_SOC_DAILINK_DEF(hdmi1, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi2, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi3, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); - -SND_SOC_DAILINK_DEF(ssp0_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); -SND_SOC_DAILINK_DEF(ssp0_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC3277:00", KBL_RT5660_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); - -/* kabylake digital audio interface glue - connects rt5660 codec <--> CPU */ -static struct snd_soc_dai_link kabylake_rt5660_dais[] = { - /* Front End DAI links */ - [KBL_DPCM_AUDIO_PB] = { - .name = "Kbl Audio Port", - .stream_name = "Audio", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .ops = &kabylake_rt5660_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [KBL_DPCM_AUDIO_CP] = { - .name = "Kbl Audio Capture Port", - .stream_name = "Audio Record", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, - .ops = &kabylake_rt5660_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI1_PB] = { - .name = "Kbl HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI2_PB] = { - .name = "Kbl HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI3_PB] = { - .name = "Kbl HDMI Port3", - .stream_name = "Hdmi3", - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi3, dummy, platform), - }, - - /* Back End DAI links */ - { - /* SSP0 - Codec */ - .name = "SSP0-Codec", - .id = 0, - .no_pcm = 1, - .init = kabylake_rt5660_codec_init, - .exit = kabylake_rt5660_codec_exit, - .dai_fmt = SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = kabylake_ssp0_fixup, - .ops = &kabylake_rt5660_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform), - }, - { - .name = "iDisp1", - .id = 1, - .dpcm_playback = 1, - .init = kabylake_hdmi1_init, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 2, - .init = kabylake_hdmi2_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, - { - .name = "iDisp3", - .id = 3, - .init = kabylake_hdmi3_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), - }, -}; - - -#define NAME_SIZE 32 -static int kabylake_card_late_probe(struct snd_soc_card *card) -{ - struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card); - struct kbl_hdmi_pcm *pcm; - struct snd_soc_component *component = NULL; - int err, i = 0; - char jack_name[NAME_SIZE]; - - 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, &skylake_hdmi[i]); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &skylake_hdmi[i]); - if (err < 0) - return err; - - i++; - - } - - if (!component) - return -EINVAL; - - return hdac_hdmi_jack_port_init(component, &card->dapm); -} - -/* kabylake audio machine driver for rt5660 */ -static struct snd_soc_card kabylake_audio_card_rt5660 = { - .name = "kblrt5660", - .owner = THIS_MODULE, - .dai_link = kabylake_rt5660_dais, - .num_links = ARRAY_SIZE(kabylake_rt5660_dais), - .controls = kabylake_rt5660_controls, - .num_controls = ARRAY_SIZE(kabylake_rt5660_controls), - .dapm_widgets = kabylake_rt5660_widgets, - .num_dapm_widgets = ARRAY_SIZE(kabylake_rt5660_widgets), - .dapm_routes = kabylake_rt5660_map, - .num_dapm_routes = ARRAY_SIZE(kabylake_rt5660_map), - .fully_routed = true, - .late_probe = kabylake_card_late_probe, -}; - -static int kabylake_audio_probe(struct platform_device *pdev) -{ - struct kbl_codec_private *ctx; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - - kabylake_audio_card = - (struct snd_soc_card *)pdev->id_entry->driver_data; - - kabylake_audio_card->dev = &pdev->dev; - snd_soc_card_set_drvdata(kabylake_audio_card, ctx); - return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card); -} - -static const struct platform_device_id kbl_board_ids[] = { - { - .name = "kbl_rt5660", - .driver_data = - (kernel_ulong_t)&kabylake_audio_card_rt5660, - }, - { } -}; -MODULE_DEVICE_TABLE(platform, kbl_board_ids); - -static struct platform_driver kabylake_audio = { - .probe = kabylake_audio_probe, - .driver = { - .name = "kbl_rt5660", - .pm = &snd_soc_pm_ops, - }, - .id_table = kbl_board_ids, -}; - -module_platform_driver(kabylake_audio) - -/* Module information */ -MODULE_DESCRIPTION("Audio Machine driver-RT5660 in I2S mode"); -MODULE_AUTHOR("Hui Wang <hui.wang@canonical.com>"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c deleted file mode 100644 index 9071b1f1cbd0..000000000000 --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c +++ /dev/null @@ -1,1071 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel Kabylake I2S Machine Driver with MAXIM98927 - * and RT5663 Codecs - * - * Copyright (C) 2017, Intel Corporation. All rights reserved. - * - * Modified from: - * Intel Skylake I2S Machine driver - */ - -#include <linux/input.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/jack.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include "../../codecs/rt5663.h" -#include "../../codecs/hdac_hdmi.h" -#include <linux/clk.h> -#include <linux/clk-provider.h> -#include <linux/clkdev.h> - -#define KBL_REALTEK_CODEC_DAI "rt5663-aif" -#define KBL_MAXIM_CODEC_DAI "max98927-aif1" -#define DMIC_CH(p) p->list[p->count-1] -#define MAXIM_DEV0_NAME "i2c-MX98927:00" -#define MAXIM_DEV1_NAME "i2c-MX98927:01" - -static struct snd_soc_card *kabylake_audio_card; -static const struct snd_pcm_hw_constraint_list *dmic_constraints; -static struct snd_soc_jack skylake_hdmi[3]; - -struct kbl_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct kbl_rt5663_private { - struct snd_soc_jack kabylake_headset; - struct list_head hdmi_pcm_list; - struct clk *mclk; - struct clk *sclk; -}; - -enum { - KBL_DPCM_AUDIO_PB = 0, - KBL_DPCM_AUDIO_CP, - KBL_DPCM_AUDIO_HS_PB, - KBL_DPCM_AUDIO_ECHO_REF_CP, - KBL_DPCM_AUDIO_REF_CP, - KBL_DPCM_AUDIO_DMIC_CP, - KBL_DPCM_AUDIO_HDMI1_PB, - KBL_DPCM_AUDIO_HDMI2_PB, - KBL_DPCM_AUDIO_HDMI3_PB, -}; - -static const struct snd_kcontrol_new kabylake_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Left Spk"), - SOC_DAPM_PIN_SWITCH("Right Spk"), -}; - -static int platform_clock_control(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; - struct kbl_rt5663_private *priv = snd_soc_card_get_drvdata(card); - int ret = 0; - - /* - * MCLK/SCLK need to be ON early for a successful synchronization of - * codec internal clock. And the clocks are turned off during - * POST_PMD after the stream is stopped. - */ - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - /* Enable MCLK */ - ret = clk_set_rate(priv->mclk, 24000000); - if (ret < 0) { - dev_err(card->dev, "Can't set rate for mclk, err: %d\n", - ret); - return ret; - } - - ret = clk_prepare_enable(priv->mclk); - if (ret < 0) { - dev_err(card->dev, "Can't enable mclk, err: %d\n", ret); - return ret; - } - - /* Enable SCLK */ - ret = clk_set_rate(priv->sclk, 3072000); - if (ret < 0) { - dev_err(card->dev, "Can't set rate for sclk, err: %d\n", - ret); - clk_disable_unprepare(priv->mclk); - return ret; - } - - ret = clk_prepare_enable(priv->sclk); - if (ret < 0) { - dev_err(card->dev, "Can't enable sclk, err: %d\n", ret); - clk_disable_unprepare(priv->mclk); - } - break; - case SND_SOC_DAPM_POST_PMD: - clk_disable_unprepare(priv->mclk); - clk_disable_unprepare(priv->sclk); - break; - default: - return 0; - } - - return 0; -} - -static const struct snd_soc_dapm_widget kabylake_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("Left Spk", NULL), - SND_SOC_DAPM_SPK("Right Spk", NULL), - SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("HDMI1", NULL), - SND_SOC_DAPM_SPK("HDMI2", NULL), - SND_SOC_DAPM_SPK("HDMI3", NULL), - SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, - platform_clock_control, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), -}; - -static const struct snd_soc_dapm_route kabylake_map[] = { - /* HP jack connectors - unknown if we have jack detection */ - { "Headphone Jack", NULL, "Platform Clock" }, - { "Headphone Jack", NULL, "HPOL" }, - { "Headphone Jack", NULL, "HPOR" }, - - /* speaker */ - { "Left Spk", NULL, "Left BE_OUT" }, - { "Right Spk", NULL, "Right BE_OUT" }, - - /* other jacks */ - { "Headset Mic", NULL, "Platform Clock" }, - { "IN1P", NULL, "Headset Mic" }, - { "IN1N", NULL, "Headset Mic" }, - { "DMic", NULL, "SoC DMIC" }, - - {"HDMI1", NULL, "hif5-0 Output"}, - {"HDMI2", NULL, "hif6-0 Output"}, - {"HDMI3", NULL, "hif7-0 Output"}, - - /* CODEC BE connections */ - { "Left HiFi Playback", NULL, "ssp0 Tx" }, - { "Right HiFi Playback", NULL, "ssp0 Tx" }, - { "ssp0 Tx", NULL, "spk_out" }, - - { "AIF Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec1_out" }, - - { "hs_in", NULL, "ssp1 Rx" }, - { "ssp1 Rx", NULL, "AIF Capture" }, - - /* IV feedback path */ - { "codec0_fb_in", NULL, "ssp0 Rx"}, - { "ssp0 Rx", NULL, "Left HiFi Capture" }, - { "ssp0 Rx", NULL, "Right HiFi Capture" }, - - /* DMIC */ - { "dmic01_hifi", NULL, "DMIC01 Rx" }, - { "DMIC01 Rx", NULL, "DMIC AIF" }, - - { "hifi3", NULL, "iDisp3 Tx"}, - { "iDisp3 Tx", NULL, "iDisp3_out"}, - { "hifi2", NULL, "iDisp2 Tx"}, - { "iDisp2 Tx", NULL, "iDisp2_out"}, - { "hifi1", NULL, "iDisp1 Tx"}, - { "iDisp1 Tx", NULL, "iDisp1_out"}, -}; - -enum { - KBL_DPCM_AUDIO_5663_PB = 0, - KBL_DPCM_AUDIO_5663_CP, - KBL_DPCM_AUDIO_5663_HDMI1_PB, - KBL_DPCM_AUDIO_5663_HDMI2_PB, -}; - -static const struct snd_kcontrol_new kabylake_5663_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), -}; - -static const struct snd_soc_dapm_widget kabylake_5663_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("HDMI1", NULL), - SND_SOC_DAPM_SPK("HDMI2", NULL), - SND_SOC_DAPM_SPK("HDMI3", NULL), - SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, - platform_clock_control, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), -}; - -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, -}; - -static const struct snd_soc_dapm_route kabylake_5663_map[] = { - { "Headphone Jack", NULL, "Platform Clock" }, - { "Headphone Jack", NULL, "HPOL" }, - { "Headphone Jack", NULL, "HPOR" }, - - /* other jacks */ - { "Headset Mic", NULL, "Platform Clock" }, - { "IN1P", NULL, "Headset Mic" }, - { "IN1N", NULL, "Headset Mic" }, - - {"HDMI1", NULL, "hif5-0 Output"}, - {"HDMI2", NULL, "hif6-0 Output"}, - {"HDMI3", NULL, "hif7-0 Output"}, - - /* CODEC BE connections */ - { "AIF Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec1_out" }, - - { "codec0_in", NULL, "ssp1 Rx" }, - { "ssp1 Rx", NULL, "AIF Capture" }, - - { "hifi2", NULL, "iDisp2 Tx"}, - { "iDisp2 Tx", NULL, "iDisp2_out"}, - { "hifi1", NULL, "iDisp1 Tx"}, - { "iDisp1 Tx", NULL, "iDisp1_out"}, -}; - -static struct snd_soc_codec_conf max98927_codec_conf[] = { - { - .dlc = COMP_CODEC_CONF(MAXIM_DEV0_NAME), - .name_prefix = "Right", - }, - { - .dlc = COMP_CODEC_CONF(MAXIM_DEV1_NAME), - .name_prefix = "Left", - }, -}; - -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 = snd_soc_rtd_to_cpu(rtd, 0)->component; - - dapm = snd_soc_component_get_dapm(component); - ret = snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); - if (ret) { - dev_err(rtd->dev, "Ref Cap ignore suspend failed %d\n", ret); - return ret; - } - - return ret; -} - -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 = snd_soc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_jack *jack; - - /* - * Headset buttons map to the google Reference headset. - * These can be configured by userspace. - */ - ret = snd_soc_card_jack_new_pins(kabylake_audio_card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3, - &ctx->kabylake_headset, - jack_pins, - ARRAY_SIZE(jack_pins)); - if (ret) { - dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); - return ret; - } - - jack = &ctx->kabylake_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); - - snd_soc_component_set_jack(component, &ctx->kabylake_headset, NULL); - - return ret; -} - -static int kabylake_rt5663_max98927_codec_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret; - - ret = kabylake_rt5663_codec_init(rtd); - if (ret) - return ret; - - ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); - if (ret) { - dev_err(rtd->dev, "SoC DMIC ignore suspend failed %d\n", ret); - return ret; - } - - return ret; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct kbl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = device; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB); -} - -static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB); -} - -static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB); -} - -static int kabylake_5663_hdmi1_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI1_PB); -} - -static int kabylake_5663_hdmi2_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI2_PB); -} - -static unsigned int rates[] = { - 48000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static unsigned int channels[] = { - 2, -}; - -static const struct snd_pcm_hw_constraint_list constraints_channels = { - .count = ARRAY_SIZE(channels), - .list = channels, - .mask = 0, -}; - -static int kbl_fe_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - /* - * On this platform for PCM device we support, - * 48Khz - * stereo - * 16 bit audio - */ - - runtime->hw.channels_max = 2; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels); - - runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; - snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); - - snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); - - return 0; -} - -static const struct snd_soc_ops kabylake_rt5663_fe_ops = { - .startup = kbl_fe_startup, -}; - -static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - struct snd_soc_dpcm *dpcm, *rtd_dpcm = NULL; - - /* - * The following loop will be called only for playback stream - * In this platform, there is only one playback device on every SSP - */ - for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_PLAYBACK, dpcm) { - rtd_dpcm = dpcm; - break; - } - - /* - * This following loop will be called only for capture stream - * In this platform, there is only one capture device on every SSP - */ - for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_CAPTURE, dpcm) { - rtd_dpcm = dpcm; - break; - } - - if (!rtd_dpcm) - return -EINVAL; - - /* - * The above 2 loops are mutually exclusive based on the stream direction, - * thus rtd_dpcm variable will never be overwritten - */ - - /* - * The ADSP will convert the FE rate to 48k, stereo, 24 bit - */ - if (!strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Port") || - !strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Headset Playback") || - !strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Capture Port")) { - rate->min = rate->max = 48000; - chan->min = chan->max = 2; - snd_mask_none(fmt); - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); - } - /* - * The speaker on the SSP0 supports S16_LE and not S24_LE. - * thus changing the mask here - */ - if (!strcmp(rtd_dpcm->be->dai_link->name, "SSP0-Codec")) - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); - - return 0; -} - -static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - 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 */ - rt5663_sel_asrc_clk_src(codec_dai->component, - RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER, - RT5663_CLK_SEL_I2S1_ASRC); - - ret = snd_soc_dai_set_sysclk(codec_dai, - RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); - if (ret < 0) - dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); - - return ret; -} - -static struct snd_soc_ops kabylake_rt5663_ops = { - .hw_params = kabylake_rt5663_hw_params, -}; - -static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2) - chan->min = chan->max = 2; - else - chan->min = chan->max = 4; - - return 0; -} - -static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai; - int ret = 0, j; - - for_each_rtd_codec_dais(rtd, j, codec_dai) { - if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) { - /* - * Use channel 4 and 5 for the first amp - */ - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); - if (ret < 0) { - dev_err(rtd->dev, "set TDM slot err:%d\n", ret); - return ret; - } - } - if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { - /* - * Use channel 6 and 7 for the second amp - */ - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16); - if (ret < 0) { - dev_err(rtd->dev, "set TDM slot err:%d\n", ret); - return ret; - } - } - } - return ret; -} - -static struct snd_soc_ops kabylake_ssp0_ops = { - .hw_params = kabylake_ssp0_hw_params, -}; - -static unsigned int channels_dmic[] = { - 2, 4, -}; - -static struct snd_pcm_hw_constraint_list constraints_dmic_channels = { - .count = ARRAY_SIZE(channels_dmic), - .list = channels_dmic, - .mask = 0, -}; - -static const unsigned int dmic_2ch[] = { - 2, -}; - -static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { - .count = ARRAY_SIZE(dmic_2ch), - .list = dmic_2ch, - .mask = 0, -}; - -static int kabylake_dmic_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw.channels_max = DMIC_CH(dmic_constraints); - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - dmic_constraints); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); -} - -static struct snd_soc_ops kabylake_dmic_ops = { - .startup = kabylake_dmic_startup, -}; - -static unsigned int rates_16000[] = { - 16000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_16000 = { - .count = ARRAY_SIZE(rates_16000), - .list = rates_16000, -}; - -static const unsigned int ch_mono[] = { - 1, -}; - -static const struct snd_pcm_hw_constraint_list constraints_refcap = { - .count = ARRAY_SIZE(ch_mono), - .list = ch_mono, -}; - -static int kabylake_refcap_startup(struct snd_pcm_substream *substream) -{ - substream->runtime->hw.channels_max = 1; - snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_refcap); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &constraints_16000); -} - -static struct snd_soc_ops skylake_refcap_ops = { - .startup = kabylake_refcap_startup, -}; - -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); - -SND_SOC_DAILINK_DEF(system2, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin2"))); - -SND_SOC_DAILINK_DEF(echoref, - DAILINK_COMP_ARRAY(COMP_CPU("Echoref Pin"))); - -SND_SOC_DAILINK_DEF(reference, - DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); - -SND_SOC_DAILINK_DEF(dmic, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); - -SND_SOC_DAILINK_DEF(hdmi1, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi2, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi3, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); - -SND_SOC_DAILINK_DEF(ssp0_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); -SND_SOC_DAILINK_DEF(ssp0_codec, - DAILINK_COMP_ARRAY( - /* Left */ COMP_CODEC(MAXIM_DEV0_NAME, KBL_MAXIM_CODEC_DAI), - /* Right */ COMP_CODEC(MAXIM_DEV1_NAME, KBL_MAXIM_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(ssp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); -SND_SOC_DAILINK_DEF(ssp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5663:00", - KBL_REALTEK_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(dmic01_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); -SND_SOC_DAILINK_DEF(dmic_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); - -/* kabylake digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link kabylake_dais[] = { - /* Front End DAI links */ - [KBL_DPCM_AUDIO_PB] = { - .name = "Kbl Audio Port", - .stream_name = "Audio", - .dynamic = 1, - .nonatomic = 1, - .init = kabylake_rt5663_fe_init, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .ops = &kabylake_rt5663_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [KBL_DPCM_AUDIO_CP] = { - .name = "Kbl Audio Capture Port", - .stream_name = "Audio Record", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, - .ops = &kabylake_rt5663_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [KBL_DPCM_AUDIO_HS_PB] = { - .name = "Kbl Audio Headset Playback", - .stream_name = "Headset Audio", - .dpcm_playback = 1, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(system2, dummy, platform), - }, - [KBL_DPCM_AUDIO_ECHO_REF_CP] = { - .name = "Kbl Audio Echo Reference cap", - .stream_name = "Echoreference Capture", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - SND_SOC_DAILINK_REG(echoref, dummy, platform), - }, - [KBL_DPCM_AUDIO_REF_CP] = { - .name = "Kbl Audio Reference cap", - .stream_name = "Wake on Voice", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &skylake_refcap_ops, - SND_SOC_DAILINK_REG(reference, dummy, platform), - }, - [KBL_DPCM_AUDIO_DMIC_CP] = { - .name = "Kbl Audio DMIC cap", - .stream_name = "dmiccap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &kabylake_dmic_ops, - SND_SOC_DAILINK_REG(dmic, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI1_PB] = { - .name = "Kbl HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI2_PB] = { - .name = "Kbl HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI3_PB] = { - .name = "Kbl HDMI Port3", - .stream_name = "Hdmi3", - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi3, dummy, platform), - }, - - /* Back End DAI links */ - { - /* SSP0 - Codec */ - .name = "SSP0-Codec", - .id = 0, - .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_DSP_B | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = kabylake_ssp_fixup, - .dpcm_playback = 1, - .ops = &kabylake_ssp0_ops, - SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform), - }, - { - /* SSP1 - Codec */ - .name = "SSP1-Codec", - .id = 1, - .no_pcm = 1, - .init = kabylake_rt5663_max98927_codec_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = kabylake_ssp_fixup, - .ops = &kabylake_rt5663_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), - }, - { - .name = "dmic01", - .id = 2, - .be_hw_params_fixup = kabylake_dmic_fixup, - .ignore_suspend = 1, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic01_pin, dmic_codec, platform), - }, - { - .name = "iDisp1", - .id = 3, - .dpcm_playback = 1, - .init = kabylake_hdmi1_init, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 4, - .init = kabylake_hdmi2_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, - { - .name = "iDisp3", - .id = 5, - .init = kabylake_hdmi3_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), - }, -}; - -static struct snd_soc_dai_link kabylake_5663_dais[] = { - /* Front End DAI links */ - [KBL_DPCM_AUDIO_5663_PB] = { - .name = "Kbl Audio Port", - .stream_name = "Audio", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .ops = &kabylake_rt5663_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [KBL_DPCM_AUDIO_5663_CP] = { - .name = "Kbl Audio Capture Port", - .stream_name = "Audio Record", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, - .ops = &kabylake_rt5663_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [KBL_DPCM_AUDIO_5663_HDMI1_PB] = { - .name = "Kbl HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [KBL_DPCM_AUDIO_5663_HDMI2_PB] = { - .name = "Kbl HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - - /* Back End DAI links */ - { - /* SSP1 - Codec */ - .name = "SSP1-Codec", - .id = 0, - .no_pcm = 1, - .init = kabylake_rt5663_codec_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = kabylake_ssp_fixup, - .ops = &kabylake_rt5663_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), - }, - { - .name = "iDisp1", - .id = 1, - .dpcm_playback = 1, - .init = kabylake_5663_hdmi1_init, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 2, - .init = kabylake_5663_hdmi2_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, -}; - -#define NAME_SIZE 32 -static int kabylake_card_late_probe(struct snd_soc_card *card) -{ - struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card); - struct kbl_hdmi_pcm *pcm; - struct snd_soc_component *component = NULL; - int err, i = 0; - char jack_name[NAME_SIZE]; - - 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, &skylake_hdmi[i]); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &skylake_hdmi[i]); - if (err < 0) - return err; - - i++; - } - - if (!component) - return -EINVAL; - - return hdac_hdmi_jack_port_init(component, &card->dapm); -} - -/* kabylake audio machine driver for SPT + RT5663 */ -static struct snd_soc_card kabylake_audio_card_rt5663_m98927 = { - .name = "kblrt5663max", - .owner = THIS_MODULE, - .dai_link = kabylake_dais, - .num_links = ARRAY_SIZE(kabylake_dais), - .controls = kabylake_controls, - .num_controls = ARRAY_SIZE(kabylake_controls), - .dapm_widgets = kabylake_widgets, - .num_dapm_widgets = ARRAY_SIZE(kabylake_widgets), - .dapm_routes = kabylake_map, - .num_dapm_routes = ARRAY_SIZE(kabylake_map), - .codec_conf = max98927_codec_conf, - .num_configs = ARRAY_SIZE(max98927_codec_conf), - .fully_routed = true, - .late_probe = kabylake_card_late_probe, -}; - -/* kabylake audio machine driver for RT5663 */ -static struct snd_soc_card kabylake_audio_card_rt5663 = { - .name = "kblrt5663", - .owner = THIS_MODULE, - .dai_link = kabylake_5663_dais, - .num_links = ARRAY_SIZE(kabylake_5663_dais), - .controls = kabylake_5663_controls, - .num_controls = ARRAY_SIZE(kabylake_5663_controls), - .dapm_widgets = kabylake_5663_widgets, - .num_dapm_widgets = ARRAY_SIZE(kabylake_5663_widgets), - .dapm_routes = kabylake_5663_map, - .num_dapm_routes = ARRAY_SIZE(kabylake_5663_map), - .fully_routed = true, - .late_probe = kabylake_card_late_probe, -}; - -static int kabylake_audio_probe(struct platform_device *pdev) -{ - struct kbl_rt5663_private *ctx; - struct snd_soc_acpi_mach *mach; - int ret; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - - kabylake_audio_card = - (struct snd_soc_card *)pdev->id_entry->driver_data; - - kabylake_audio_card->dev = &pdev->dev; - snd_soc_card_set_drvdata(kabylake_audio_card, ctx); - - mach = pdev->dev.platform_data; - if (mach) - dmic_constraints = mach->mach_params.dmic_num == 2 ? - &constraints_dmic_2ch : &constraints_dmic_channels; - - ctx->mclk = devm_clk_get(&pdev->dev, "ssp1_mclk"); - if (IS_ERR(ctx->mclk)) { - ret = PTR_ERR(ctx->mclk); - if (ret == -ENOENT) { - dev_info(&pdev->dev, - "Failed to get ssp1_sclk, defer probe\n"); - return -EPROBE_DEFER; - } - - dev_err(&pdev->dev, "Failed to get ssp1_mclk with err:%d\n", - ret); - return ret; - } - - ctx->sclk = devm_clk_get(&pdev->dev, "ssp1_sclk"); - if (IS_ERR(ctx->sclk)) { - ret = PTR_ERR(ctx->sclk); - if (ret == -ENOENT) { - dev_info(&pdev->dev, - "Failed to get ssp1_sclk, defer probe\n"); - return -EPROBE_DEFER; - } - - dev_err(&pdev->dev, "Failed to get ssp1_sclk with err:%d\n", - ret); - return ret; - } - - return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card); -} - -static const struct platform_device_id kbl_board_ids[] = { - { - .name = "kbl_rt5663", - .driver_data = (kernel_ulong_t)&kabylake_audio_card_rt5663, - }, - { - .name = "kbl_rt5663_m98927", - .driver_data = - (kernel_ulong_t)&kabylake_audio_card_rt5663_m98927, - }, - { } -}; -MODULE_DEVICE_TABLE(platform, kbl_board_ids); - -static struct platform_driver kabylake_audio = { - .probe = kabylake_audio_probe, - .driver = { - .name = "kbl_rt5663_m98927", - .pm = &snd_soc_pm_ops, - }, - .id_table = kbl_board_ids, -}; - -module_platform_driver(kabylake_audio) - -/* Module information */ -MODULE_DESCRIPTION("Audio Machine driver-RT5663 & MAX98927 in I2S mode"); -MODULE_AUTHOR("Naveen M <naveen.m@intel.com>"); -MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c deleted file mode 100644 index 178fe9c37df6..000000000000 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ /dev/null @@ -1,868 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel Kabylake I2S Machine Driver with MAXIM98927 - * RT5514 and RT5663 Codecs - * - * Copyright (C) 2017, Intel Corporation. All rights reserved. - * - * Modified from: - * Intel Kabylake I2S Machine driver supporting MAXIM98927 and - * RT5663 codecs - */ - -#include <linux/input.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/jack.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include "../../codecs/rt5514.h" -#include "../../codecs/rt5663.h" -#include "../../codecs/hdac_hdmi.h" -#include <linux/clk.h> -#include <linux/clk-provider.h> -#include <linux/clkdev.h> - -#define KBL_REALTEK_CODEC_DAI "rt5663-aif" -#define KBL_REALTEK_DMIC_CODEC_DAI "rt5514-aif1" -#define KBL_MAXIM_CODEC_DAI "max98927-aif1" -#define MAXIM_DEV0_NAME "i2c-MX98927:00" -#define MAXIM_DEV1_NAME "i2c-MX98927:01" -#define RT5514_DEV_NAME "i2c-10EC5514:00" -#define RT5663_DEV_NAME "i2c-10EC5663:00" -#define RT5514_AIF1_BCLK_FREQ (48000 * 8 * 16) -#define RT5514_AIF1_SYSCLK_FREQ 12288000 -#define NAME_SIZE 32 - -#define DMIC_CH(p) p->list[p->count-1] - - -static struct snd_soc_card kabylake_audio_card; -static const struct snd_pcm_hw_constraint_list *dmic_constraints; - -struct kbl_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct kbl_codec_private { - struct snd_soc_jack kabylake_headset; - struct list_head hdmi_pcm_list; - struct snd_soc_jack kabylake_hdmi[2]; - struct clk *mclk; - struct clk *sclk; -}; - -enum { - KBL_DPCM_AUDIO_PB = 0, - KBL_DPCM_AUDIO_CP, - KBL_DPCM_AUDIO_HS_PB, - KBL_DPCM_AUDIO_ECHO_REF_CP, - KBL_DPCM_AUDIO_DMIC_CP, - KBL_DPCM_AUDIO_RT5514_DSP, - KBL_DPCM_AUDIO_HDMI1_PB, - KBL_DPCM_AUDIO_HDMI2_PB, -}; - -static const struct snd_kcontrol_new kabylake_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Left Spk"), - SOC_DAPM_PIN_SWITCH("Right Spk"), - SOC_DAPM_PIN_SWITCH("DMIC"), -}; - -static int platform_clock_control(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; - struct kbl_codec_private *priv = snd_soc_card_get_drvdata(card); - int ret = 0; - - /* - * MCLK/SCLK need to be ON early for a successful synchronization of - * codec internal clock. And the clocks are turned off during - * POST_PMD after the stream is stopped. - */ - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - /* Enable MCLK */ - ret = clk_set_rate(priv->mclk, 24000000); - if (ret < 0) { - dev_err(card->dev, "Can't set rate for mclk, err: %d\n", - ret); - return ret; - } - - ret = clk_prepare_enable(priv->mclk); - if (ret < 0) { - dev_err(card->dev, "Can't enable mclk, err: %d\n", ret); - return ret; - } - - /* Enable SCLK */ - ret = clk_set_rate(priv->sclk, 3072000); - if (ret < 0) { - dev_err(card->dev, "Can't set rate for sclk, err: %d\n", - ret); - clk_disable_unprepare(priv->mclk); - return ret; - } - - ret = clk_prepare_enable(priv->sclk); - if (ret < 0) { - dev_err(card->dev, "Can't enable sclk, err: %d\n", ret); - clk_disable_unprepare(priv->mclk); - } - break; - case SND_SOC_DAPM_POST_PMD: - clk_disable_unprepare(priv->mclk); - clk_disable_unprepare(priv->sclk); - break; - default: - return 0; - } - - return 0; -} - -static const struct snd_soc_dapm_widget kabylake_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("Left Spk", NULL), - SND_SOC_DAPM_SPK("Right Spk", NULL), - SND_SOC_DAPM_MIC("DMIC", NULL), - SND_SOC_DAPM_SPK("HDMI1", NULL), - SND_SOC_DAPM_SPK("HDMI2", NULL), - SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, - platform_clock_control, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - -}; - -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, -}; - -static const struct snd_soc_dapm_route kabylake_map[] = { - /* Headphones */ - { "Headphone Jack", NULL, "Platform Clock" }, - { "Headphone Jack", NULL, "HPOL" }, - { "Headphone Jack", NULL, "HPOR" }, - - /* speaker */ - { "Left Spk", NULL, "Left BE_OUT" }, - { "Right Spk", NULL, "Right BE_OUT" }, - - /* other jacks */ - { "Headset Mic", NULL, "Platform Clock" }, - { "IN1P", NULL, "Headset Mic" }, - { "IN1N", NULL, "Headset Mic" }, - - /* CODEC BE connections */ - { "Left HiFi Playback", NULL, "ssp0 Tx" }, - { "Right HiFi Playback", NULL, "ssp0 Tx" }, - { "ssp0 Tx", NULL, "spk_out" }, - - { "AIF Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec1_out" }, - - { "hs_in", NULL, "ssp1 Rx" }, - { "ssp1 Rx", NULL, "AIF Capture" }, - - { "codec1_in", NULL, "ssp0 Rx" }, - { "ssp0 Rx", NULL, "AIF1 Capture" }, - - /* IV feedback path */ - { "codec0_fb_in", NULL, "ssp0 Rx"}, - { "ssp0 Rx", NULL, "Left HiFi Capture" }, - { "ssp0 Rx", NULL, "Right HiFi Capture" }, - - /* DMIC */ - { "DMIC1L", NULL, "DMIC" }, - { "DMIC1R", NULL, "DMIC" }, - { "DMIC2L", NULL, "DMIC" }, - { "DMIC2R", NULL, "DMIC" }, - - { "hifi2", NULL, "iDisp2 Tx" }, - { "iDisp2 Tx", NULL, "iDisp2_out" }, - { "hifi1", NULL, "iDisp1 Tx" }, - { "iDisp1 Tx", NULL, "iDisp1_out" }, -}; - -static struct snd_soc_codec_conf max98927_codec_conf[] = { - { - .dlc = COMP_CODEC_CONF(MAXIM_DEV0_NAME), - .name_prefix = "Right", - }, - { - .dlc = COMP_CODEC_CONF(MAXIM_DEV1_NAME), - .name_prefix = "Left", - }, -}; - - -static int kabylake_rt5663_fe_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; - int ret; - - dapm = snd_soc_component_get_dapm(component); - ret = snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); - if (ret) - dev_err(rtd->dev, "Ref Cap -Ignore suspend failed = %d\n", ret); - - return ret; -} - -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 = snd_soc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_jack *jack; - - /* - * Headset buttons map to the google Reference headset. - * These can be configured by userspace. - */ - ret = snd_soc_card_jack_new_pins(&kabylake_audio_card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3, - &ctx->kabylake_headset, - jack_pins, - ARRAY_SIZE(jack_pins)); - if (ret) { - dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); - return ret; - } - - jack = &ctx->kabylake_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); - - snd_soc_component_set_jack(component, &ctx->kabylake_headset, NULL); - - ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "DMIC"); - if (ret) - dev_err(rtd->dev, "DMIC - Ignore suspend failed = %d\n", ret); - - return ret; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct kbl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = device; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB); -} - -static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) -{ - return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB); -} - -static const unsigned int rates[] = { - 48000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static const unsigned int channels[] = { - 2, -}; - -static const struct snd_pcm_hw_constraint_list constraints_channels = { - .count = ARRAY_SIZE(channels), - .list = channels, - .mask = 0, -}; - -static int kbl_fe_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - /* - * On this platform for PCM device we support, - * 48Khz - * stereo - * 16 bit audio - */ - - runtime->hw.channels_max = 2; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels); - - runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; - snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); - - snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); - - return 0; -} - -static const struct snd_soc_ops kabylake_rt5663_fe_ops = { - .startup = kbl_fe_startup, -}; - -static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - struct snd_soc_dpcm *dpcm, *rtd_dpcm = NULL; - - /* - * The following loop will be called only for playback stream - * In this platform, there is only one playback device on every SSP - */ - for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_PLAYBACK, dpcm) { - rtd_dpcm = dpcm; - break; - } - - /* - * This following loop will be called only for capture stream - * In this platform, there is only one capture device on every SSP - */ - for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_CAPTURE, dpcm) { - rtd_dpcm = dpcm; - break; - } - - if (!rtd_dpcm) - return -EINVAL; - - /* - * The above 2 loops are mutually exclusive based on the stream direction, - * thus rtd_dpcm variable will never be overwritten - */ - - /* - * The ADSP will convert the FE rate to 48k, stereo, 24 bit - */ - if (!strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Port") || - !strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Headset Playback") || - !strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Capture Port")) { - rate->min = rate->max = 48000; - chan->min = chan->max = 2; - snd_mask_none(fmt); - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); - } else if (!strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio DMIC cap")) { - if (params_channels(params) == 2 || - DMIC_CH(dmic_constraints) == 2) - chan->min = chan->max = 2; - else - chan->min = chan->max = 4; - } - /* - * The speaker on the SSP0 supports S16_LE and not S24_LE. - * thus changing the mask here - */ - if (!strcmp(rtd_dpcm->be->dai_link->name, "SSP0-Codec")) - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); - - return 0; -} - -static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - 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 */ - rt5663_sel_asrc_clk_src(codec_dai->component, - RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER, - RT5663_CLK_SEL_I2S1_ASRC); - - ret = snd_soc_dai_set_sysclk(codec_dai, - RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); - if (ret < 0) - dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); - - return ret; -} - -static struct snd_soc_ops kabylake_rt5663_ops = { - .hw_params = kabylake_rt5663_hw_params, -}; - -static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai; - int ret = 0, j; - - for_each_rtd_codec_dais(rtd, j, codec_dai) { - if (!strcmp(codec_dai->component->name, RT5514_DEV_NAME)) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0, 8, 16); - if (ret < 0) { - dev_err(rtd->dev, "set TDM slot err:%d\n", ret); - return ret; - } - - ret = snd_soc_dai_set_sysclk(codec_dai, - RT5514_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); - if (ret < 0) { - dev_err(rtd->dev, "set sysclk err: %d\n", ret); - return ret; - } - } - if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); - if (ret < 0) { - dev_err(rtd->dev, "DEV0 TDM slot err:%d\n", ret); - return ret; - } - } - - if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16); - if (ret < 0) { - dev_err(rtd->dev, "DEV1 TDM slot err:%d\n", ret); - return ret; - } - } - } - return ret; -} - -static struct snd_soc_ops kabylake_ssp0_ops = { - .hw_params = kabylake_ssp0_hw_params, -}; - -static const unsigned int channels_dmic[] = { - 4, -}; - -static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = { - .count = ARRAY_SIZE(channels_dmic), - .list = channels_dmic, - .mask = 0, -}; - -static const unsigned int dmic_2ch[] = { - 2, -}; - -static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { - .count = ARRAY_SIZE(dmic_2ch), - .list = dmic_2ch, - .mask = 0, -}; - -static int kabylake_dmic_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw.channels_max = DMIC_CH(dmic_constraints); - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - dmic_constraints); - - runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; - snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); -} - -static struct snd_soc_ops kabylake_dmic_ops = { - .startup = kabylake_dmic_startup, -}; - -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); - -SND_SOC_DAILINK_DEF(system2, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin2"))); - -SND_SOC_DAILINK_DEF(echoref, - DAILINK_COMP_ARRAY(COMP_CPU("Echoref Pin"))); - -SND_SOC_DAILINK_DEF(spi_cpu, - DAILINK_COMP_ARRAY(COMP_CPU("spi-PRP0001:00"))); -SND_SOC_DAILINK_DEF(spi_platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("spi-PRP0001:00"))); - -SND_SOC_DAILINK_DEF(dmic, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); - -SND_SOC_DAILINK_DEF(hdmi1, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi2, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); - -SND_SOC_DAILINK_DEF(ssp0_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); -SND_SOC_DAILINK_DEF(ssp0_codec, - DAILINK_COMP_ARRAY( - /* Left */ COMP_CODEC(MAXIM_DEV0_NAME, KBL_MAXIM_CODEC_DAI), - /* Right */COMP_CODEC(MAXIM_DEV1_NAME, KBL_MAXIM_CODEC_DAI), - /* dmic */ COMP_CODEC(RT5514_DEV_NAME, KBL_REALTEK_DMIC_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(ssp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); -SND_SOC_DAILINK_DEF(ssp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC(RT5663_DEV_NAME, KBL_REALTEK_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); - -/* kabylake digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link kabylake_dais[] = { - /* Front End DAI links */ - [KBL_DPCM_AUDIO_PB] = { - .name = "Kbl Audio Port", - .stream_name = "Audio", - .dynamic = 1, - .nonatomic = 1, - .init = kabylake_rt5663_fe_init, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .ops = &kabylake_rt5663_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [KBL_DPCM_AUDIO_CP] = { - .name = "Kbl Audio Capture Port", - .stream_name = "Audio Record", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, - .ops = &kabylake_rt5663_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [KBL_DPCM_AUDIO_HS_PB] = { - .name = "Kbl Audio Headset Playback", - .stream_name = "Headset Audio", - .dpcm_playback = 1, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(system2, dummy, platform), - }, - [KBL_DPCM_AUDIO_ECHO_REF_CP] = { - .name = "Kbl Audio Echo Reference cap", - .stream_name = "Echoreference Capture", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - SND_SOC_DAILINK_REG(echoref, dummy, platform), - }, - [KBL_DPCM_AUDIO_RT5514_DSP] = { - .name = "rt5514 dsp", - .stream_name = "Wake on Voice", - SND_SOC_DAILINK_REG(spi_cpu, dummy, spi_platform), - }, - [KBL_DPCM_AUDIO_DMIC_CP] = { - .name = "Kbl Audio DMIC cap", - .stream_name = "dmiccap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &kabylake_dmic_ops, - SND_SOC_DAILINK_REG(dmic, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI1_PB] = { - .name = "Kbl HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [KBL_DPCM_AUDIO_HDMI2_PB] = { - .name = "Kbl HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - /* Back End DAI links */ - /* single Back end dai for both max speakers and dmic */ - { - /* SSP0 - Codec */ - .name = "SSP0-Codec", - .id = 0, - .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_DSP_B | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = kabylake_ssp_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, - .ops = &kabylake_ssp0_ops, - SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform), - }, - { - .name = "SSP1-Codec", - .id = 1, - .no_pcm = 1, - .init = kabylake_rt5663_codec_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = kabylake_ssp_fixup, - .ops = &kabylake_rt5663_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), - }, - { - .name = "iDisp1", - .id = 3, - .dpcm_playback = 1, - .init = kabylake_hdmi1_init, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 4, - .init = kabylake_hdmi2_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, -}; - -static int kabylake_set_bias_level(struct snd_soc_card *card, - struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) -{ - struct snd_soc_component *component = dapm->component; - struct kbl_codec_private *priv = snd_soc_card_get_drvdata(card); - int ret = 0; - - if (!component || strcmp(component->name, RT5514_DEV_NAME)) - return 0; - - if (IS_ERR(priv->mclk)) - return 0; - - /* - * It's required to control mclk directly in the set_bias_level - * function for rt5514 codec or the recording function could - * break. - */ - switch (level) { - case SND_SOC_BIAS_PREPARE: - if (dapm->bias_level == SND_SOC_BIAS_ON) { - if (!__clk_is_enabled(priv->mclk)) - return 0; - dev_dbg(card->dev, "Disable mclk"); - clk_disable_unprepare(priv->mclk); - } else { - dev_dbg(card->dev, "Enable mclk"); - ret = clk_set_rate(priv->mclk, 24000000); - if (ret) { - dev_err(card->dev, "Can't set rate for mclk, err: %d\n", - ret); - return ret; - } - - ret = clk_prepare_enable(priv->mclk); - if (ret) { - dev_err(card->dev, "Can't enable mclk, err: %d\n", - ret); - - /* mclk is already enabled in FW */ - ret = 0; - } - } - break; - default: - break; - } - - return ret; -} - -static int kabylake_card_late_probe(struct snd_soc_card *card) -{ - struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card); - struct kbl_hdmi_pcm *pcm; - struct snd_soc_component *component = NULL; - int err, i = 0; - char jack_name[NAME_SIZE]; - - 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, &ctx->kabylake_hdmi[i]); - - if (err) - return err; - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &ctx->kabylake_hdmi[i]); - if (err < 0) - return err; - i++; - } - - if (!component) - return -EINVAL; - - return hdac_hdmi_jack_port_init(component, &card->dapm); -} - -/* - * kabylake audio machine driver for MAX98927 + RT5514 + RT5663 - */ -static struct snd_soc_card kabylake_audio_card = { - .name = "kbl-r5514-5663-max", - .owner = THIS_MODULE, - .dai_link = kabylake_dais, - .num_links = ARRAY_SIZE(kabylake_dais), - .set_bias_level = kabylake_set_bias_level, - .controls = kabylake_controls, - .num_controls = ARRAY_SIZE(kabylake_controls), - .dapm_widgets = kabylake_widgets, - .num_dapm_widgets = ARRAY_SIZE(kabylake_widgets), - .dapm_routes = kabylake_map, - .num_dapm_routes = ARRAY_SIZE(kabylake_map), - .codec_conf = max98927_codec_conf, - .num_configs = ARRAY_SIZE(max98927_codec_conf), - .fully_routed = true, - .late_probe = kabylake_card_late_probe, -}; - -static int kabylake_audio_probe(struct platform_device *pdev) -{ - struct kbl_codec_private *ctx; - struct snd_soc_acpi_mach *mach; - int ret; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - - kabylake_audio_card.dev = &pdev->dev; - snd_soc_card_set_drvdata(&kabylake_audio_card, ctx); - - mach = pdev->dev.platform_data; - if (mach) - dmic_constraints = mach->mach_params.dmic_num == 2 ? - &constraints_dmic_2ch : &constraints_dmic_channels; - - ctx->mclk = devm_clk_get(&pdev->dev, "ssp1_mclk"); - if (IS_ERR(ctx->mclk)) { - ret = PTR_ERR(ctx->mclk); - if (ret == -ENOENT) { - dev_info(&pdev->dev, - "Failed to get ssp1_mclk, defer probe\n"); - return -EPROBE_DEFER; - } - - dev_err(&pdev->dev, "Failed to get ssp1_mclk with err:%d\n", - ret); - return ret; - } - - ctx->sclk = devm_clk_get(&pdev->dev, "ssp1_sclk"); - if (IS_ERR(ctx->sclk)) { - ret = PTR_ERR(ctx->sclk); - if (ret == -ENOENT) { - dev_info(&pdev->dev, - "Failed to get ssp1_sclk, defer probe\n"); - return -EPROBE_DEFER; - } - - dev_err(&pdev->dev, "Failed to get ssp1_sclk with err:%d\n", - ret); - return ret; - } - - return devm_snd_soc_register_card(&pdev->dev, &kabylake_audio_card); -} - -static const struct platform_device_id kbl_board_ids[] = { - { .name = "kbl_r5514_5663_max" }, - { } -}; -MODULE_DEVICE_TABLE(platform, kbl_board_ids); - -static struct platform_driver kabylake_audio = { - .probe = kabylake_audio_probe, - .driver = { - .name = "kbl_r5514_5663_max", - .pm = &snd_soc_pm_ops, - }, - .id_table = kbl_board_ids, -}; - -module_platform_driver(kabylake_audio) - -/* Module information */ -MODULE_DESCRIPTION("Audio Machine driver-RT5663 RT5514 & MAX98927"); -MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.c b/sound/soc/intel/boards/skl_hda_dsp_common.c deleted file mode 100644 index e9cefa4ae56d..000000000000 --- a/sound/soc/intel/boards/skl_hda_dsp_common.c +++ /dev/null @@ -1,168 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright(c) 2015-18 Intel Corporation. - -/* - * Common functions used in different Intel machine drivers - */ -#include <linux/module.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/jack.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> -#include "../../codecs/hdac_hdmi.h" -#include "skl_hda_dsp_common.h" - -#include <sound/hda_codec.h> -#include "../../codecs/hdac_hda.h" - -#define NAME_SIZE 32 - -int skl_hda_hdmi_add_pcm(struct snd_soc_card *card, int device) -{ - struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card); - struct skl_hda_hdmi_pcm *pcm; - char dai_name[NAME_SIZE]; - - pcm = devm_kzalloc(card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - snprintf(dai_name, sizeof(dai_name), "intel-hdmi-hifi%d", - ctx->dai_index); - pcm->codec_dai = snd_soc_card_get_codec_dai(card, dai_name); - if (!pcm->codec_dai) - return -EINVAL; - - pcm->device = device; - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -SND_SOC_DAILINK_DEF(idisp1_cpu, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_cpu, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_cpu, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); - -SND_SOC_DAILINK_DEF(analog_cpu, - DAILINK_COMP_ARRAY(COMP_CPU("Analog CPU DAI"))); -SND_SOC_DAILINK_DEF(analog_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D0", "Analog Codec DAI"))); - -SND_SOC_DAILINK_DEF(digital_cpu, - DAILINK_COMP_ARRAY(COMP_CPU("Digital CPU DAI"))); -SND_SOC_DAILINK_DEF(digital_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D0", "Digital Codec DAI"))); - -SND_SOC_DAILINK_DEF(dmic_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); - -SND_SOC_DAILINK_DEF(dmic_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); - -SND_SOC_DAILINK_DEF(dmic16k, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); - -/* skl_hda_digital audio interface glue - connects codec <--> CPU */ -struct snd_soc_dai_link skl_hda_be_dai_links[HDA_DSP_MAX_BE_DAI_LINKS] = { - /* Back End DAI links */ - { - .name = "iDisp1", - .id = 1, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_cpu, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 2, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_cpu, idisp2_codec, platform), - }, - { - .name = "iDisp3", - .id = 3, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp3_cpu, idisp3_codec, platform), - }, - { - .name = "Analog Playback and Capture", - .id = 4, - .dpcm_playback = 1, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(analog_cpu, analog_codec, platform), - }, - { - .name = "Digital Playback and Capture", - .id = 5, - .dpcm_playback = 1, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(digital_cpu, digital_codec, platform), - }, - { - .name = "dmic01", - .id = 6, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), - }, - { - .name = "dmic16k", - .id = 7, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic16k, dmic_codec, platform), - }, -}; - -int skl_hda_hdmi_jack_init(struct snd_soc_card *card) -{ - struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component = NULL; - struct skl_hda_hdmi_pcm *pcm; - char jack_name[NAME_SIZE]; - int err; - - if (ctx->common_hdmi_codec_drv) - return skl_hda_hdmi_build_controls(card); - - 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; - } - - if (!component) - return -EINVAL; - - return hdac_hdmi_jack_port_init(component, &card->dapm); -} diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.h b/sound/soc/intel/boards/skl_hda_dsp_common.h deleted file mode 100644 index 4b0b3959182e..000000000000 --- a/sound/soc/intel/boards/skl_hda_dsp_common.h +++ /dev/null @@ -1,66 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright(c) 2015-18 Intel Corporation. - */ - -/* - * This file defines data structures used in Machine Driver for Intel - * platforms with HDA Codecs. - */ - -#ifndef __SKL_HDA_DSP_COMMON_H -#define __SKL_HDA_DSP_COMMON_H -#include <linux/module.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/jack.h> -#include <sound/hda_codec.h> -#include "../../codecs/hdac_hda.h" -#include "hda_dsp_common.h" - -#define HDA_DSP_MAX_BE_DAI_LINKS 7 - -struct skl_hda_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - struct snd_soc_jack hdmi_jack; - int device; -}; - -struct skl_hda_private { - struct list_head hdmi_pcm_list; - int pcm_count; - int dai_index; - const char *platform_name; - bool common_hdmi_codec_drv; - bool idisp_codec; -}; - -extern struct snd_soc_dai_link skl_hda_be_dai_links[HDA_DSP_MAX_BE_DAI_LINKS]; -int skl_hda_hdmi_jack_init(struct snd_soc_card *card); -int skl_hda_hdmi_add_pcm(struct snd_soc_card *card, int device); - -/* - * Search card topology and register HDMI PCM related controls - * to codec driver. - */ -static inline int skl_hda_hdmi_build_controls(struct snd_soc_card *card) -{ - struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component; - struct skl_hda_hdmi_pcm *pcm; - - /* HDMI disabled, do not create controls */ - if (list_empty(&ctx->hdmi_pcm_list)) - return 0; - - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct skl_hda_hdmi_pcm, - head); - component = pcm->codec_dai->component; - if (!component) - return -EINVAL; - - return hda_dsp_hdmi_build_controls(card, component); -} - -#endif /* __SOUND_SOC_HDA_DSP_COMMON_H */ diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c index 6e172719c979..0554c7e2cb34 100644 --- a/sound/soc/intel/boards/skl_hda_dsp_generic.c +++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c @@ -8,170 +8,23 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <sound/core.h> +#include <sound/hda_codec.h> #include <sound/jack.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/soc-acpi.h> -#include "../../codecs/hdac_hdmi.h" -#include "skl_hda_dsp_common.h" - -static const struct snd_soc_dapm_widget skl_hda_widgets[] = { - SND_SOC_DAPM_HP("Analog Out", NULL), - SND_SOC_DAPM_MIC("Analog In", NULL), - SND_SOC_DAPM_HP("Alt Analog Out", NULL), - SND_SOC_DAPM_MIC("Alt Analog In", NULL), - SND_SOC_DAPM_SPK("Digital Out", NULL), - SND_SOC_DAPM_MIC("Digital In", NULL), - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - -static const struct snd_soc_dapm_route skl_hda_map[] = { - { "hifi3", NULL, "iDisp3 Tx"}, - { "iDisp3 Tx", NULL, "iDisp3_out"}, - { "hifi2", NULL, "iDisp2 Tx"}, - { "iDisp2 Tx", NULL, "iDisp2_out"}, - { "hifi1", NULL, "iDisp1 Tx"}, - { "iDisp1 Tx", NULL, "iDisp1_out"}, - - { "Analog Out", NULL, "Codec Output Pin1" }, - { "Digital Out", NULL, "Codec Output Pin2" }, - { "Alt Analog Out", NULL, "Codec Output Pin3" }, - - { "Codec Input Pin1", NULL, "Analog In" }, - { "Codec Input Pin2", NULL, "Digital In" }, - { "Codec Input Pin3", NULL, "Alt Analog In" }, - - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, - - /* CODEC BE connections */ - { "Analog Codec Playback", NULL, "Analog CPU Playback" }, - { "Analog CPU Playback", NULL, "codec0_out" }, - { "Digital Codec Playback", NULL, "Digital CPU Playback" }, - { "Digital CPU Playback", NULL, "codec1_out" }, - { "Alt Analog Codec Playback", NULL, "Alt Analog CPU Playback" }, - { "Alt Analog CPU Playback", NULL, "codec2_out" }, - - { "codec0_in", NULL, "Analog CPU Capture" }, - { "Analog CPU Capture", NULL, "Analog Codec Capture" }, - { "codec1_in", NULL, "Digital CPU Capture" }, - { "Digital CPU Capture", NULL, "Digital Codec Capture" }, - { "codec2_in", NULL, "Alt Analog CPU Capture" }, - { "Alt Analog CPU Capture", NULL, "Alt Analog Codec Capture" }, -}; +#include "../../codecs/hdac_hda.h" +#include "../../sof/intel/hda.h" +#include "sof_board_helpers.h" static int skl_hda_card_late_probe(struct snd_soc_card *card) { - return skl_hda_hdmi_jack_init(card); -} - -static int -skl_hda_add_dai_link(struct snd_soc_card *card, struct snd_soc_dai_link *link) -{ - struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card); - int ret = 0; - - dev_dbg(card->dev, "dai link name - %s\n", link->name); - link->platforms->name = ctx->platform_name; - link->nonatomic = 1; - - if (!ctx->idisp_codec) - return 0; - - if (strstr(link->name, "HDMI")) { - ret = skl_hda_hdmi_add_pcm(card, ctx->pcm_count); - - if (ret < 0) - return ret; - - ctx->dai_index++; - } - - ctx->pcm_count++; - return ret; + return sof_intel_board_card_late_probe(card); } -static struct snd_soc_card hda_soc_card = { - .name = "hda-dsp", - .owner = THIS_MODULE, - .dai_link = skl_hda_be_dai_links, - .dapm_widgets = skl_hda_widgets, - .dapm_routes = skl_hda_map, - .add_dai_link = skl_hda_add_dai_link, - .fully_routed = true, - .late_probe = skl_hda_card_late_probe, -}; - -static char hda_soc_components[30]; - -#define IDISP_DAI_COUNT 3 -#define HDAC_DAI_COUNT 2 -#define DMIC_DAI_COUNT 2 - -/* there are two routes per iDisp output */ -#define IDISP_ROUTE_COUNT (IDISP_DAI_COUNT * 2) -#define IDISP_CODEC_MASK 0x4 - #define HDA_CODEC_AUTOSUSPEND_DELAY_MS 1000 -static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params) -{ - struct snd_soc_card *card = &hda_soc_card; - struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai_link *dai_link; - u32 codec_count, codec_mask; - int i, num_links, num_route; - - codec_mask = mach_params->codec_mask; - codec_count = hweight_long(codec_mask); - ctx->idisp_codec = !!(codec_mask & IDISP_CODEC_MASK); - - if (!codec_count || codec_count > 2 || - (codec_count == 2 && !ctx->idisp_codec)) - return -EINVAL; - - if (codec_mask == IDISP_CODEC_MASK) { - /* topology with iDisp as the only HDA codec */ - num_links = IDISP_DAI_COUNT + DMIC_DAI_COUNT; - num_route = IDISP_ROUTE_COUNT; - - /* - * rearrange the dai link array and make the - * dmic dai links follow idsp dai links for only - * num_links of dai links need to be registered - * to ASoC. - */ - for (i = 0; i < DMIC_DAI_COUNT; i++) { - skl_hda_be_dai_links[IDISP_DAI_COUNT + i] = - skl_hda_be_dai_links[IDISP_DAI_COUNT + - HDAC_DAI_COUNT + i]; - } - } else { - /* topology with external and iDisp HDA codecs */ - num_links = ARRAY_SIZE(skl_hda_be_dai_links); - num_route = ARRAY_SIZE(skl_hda_map); - card->dapm_widgets = skl_hda_widgets; - card->num_dapm_widgets = ARRAY_SIZE(skl_hda_widgets); - if (!ctx->idisp_codec) { - 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 = &snd_soc_dummy_dlc; - skl_hda_be_dai_links[i].num_codecs = 1; - } - } - } - - card->num_links = num_links; - card->num_dapm_routes = num_route; - - for_each_card_prelinks(card, i, dai_link) - dai_link->platforms->name = mach_params->platform; - - return 0; -} - static void skl_set_hda_codec_autosuspend_delay(struct snd_soc_card *card) { struct snd_soc_pcm_runtime *rtd; @@ -195,48 +48,101 @@ static void skl_set_hda_codec_autosuspend_delay(struct snd_soc_card *card) } } +#define IDISP_HDMI_BE_ID 1 +#define HDA_BE_ID 4 +#define DMIC01_BE_ID 6 +#define DMIC16K_BE_ID 7 +#define BT_OFFLOAD_BE_ID 8 + +#define HDA_LINK_ORDER SOF_LINK_ORDER(SOF_LINK_IDISP_HDMI, \ + SOF_LINK_HDA, \ + SOF_LINK_DMIC01, \ + SOF_LINK_DMIC16K, \ + SOF_LINK_BT_OFFLOAD, \ + SOF_LINK_NONE, \ + SOF_LINK_NONE) + +#define HDA_LINK_IDS SOF_LINK_ORDER(IDISP_HDMI_BE_ID, \ + HDA_BE_ID, \ + DMIC01_BE_ID, \ + DMIC16K_BE_ID, \ + BT_OFFLOAD_BE_ID, \ + 0, \ + 0) + +static unsigned long +skl_hda_get_board_quirk(struct snd_soc_acpi_mach_params *mach_params) +{ + unsigned long board_quirk = 0; + int ssp_bt; + + if (hweight_long(mach_params->bt_link_mask) == 1) { + ssp_bt = fls(mach_params->bt_link_mask) - 1; + board_quirk |= SOF_SSP_PORT_BT_OFFLOAD(ssp_bt) | + SOF_BT_OFFLOAD_PRESENT; + } + + return board_quirk; +} + static int skl_hda_audio_probe(struct platform_device *pdev) { - struct snd_soc_acpi_mach *mach; - struct skl_hda_private *ctx; + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; + struct sof_card_private *ctx; + struct snd_soc_card *card; + unsigned long board_quirk = skl_hda_get_board_quirk(&mach->mach_params); int ret; - dev_dbg(&pdev->dev, "entry\n"); + card = devm_kzalloc(&pdev->dev, sizeof(struct snd_soc_card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + card->name = "hda-dsp"; + card->owner = THIS_MODULE; + card->fully_routed = true; + card->late_probe = skl_hda_card_late_probe; - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); + dev_dbg(&pdev->dev, "board_quirk = %lx\n", board_quirk); + + /* initialize ctx with board quirk */ + ctx = sof_intel_board_get_ctx(&pdev->dev, board_quirk); if (!ctx) return -ENOMEM; - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); + if (HDA_EXT_CODEC(mach->mach_params.codec_mask)) + ctx->hda_codec_present = true; - mach = pdev->dev.platform_data; - if (!mach) - return -EINVAL; + if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) + ctx->hdmi.idisp_codec = true; - snd_soc_card_set_drvdata(&hda_soc_card, ctx); + ctx->link_order_overwrite = HDA_LINK_ORDER; + ctx->link_id_overwrite = HDA_LINK_IDS; - ret = skl_hda_fill_card_info(&mach->mach_params); - if (ret < 0) { - dev_err(&pdev->dev, "Unsupported HDAudio/iDisp configuration found\n"); + /* update dai_link */ + ret = sof_intel_board_set_dai_link(&pdev->dev, card, ctx); + if (ret) return ret; - } - - ctx->pcm_count = hda_soc_card.num_links; - ctx->dai_index = 1; /* hdmi codec dai name starts from index 1 */ - ctx->platform_name = mach->mach_params.platform; - ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; - hda_soc_card.dev = &pdev->dev; + card->dev = &pdev->dev; if (mach->mach_params.dmic_num > 0) { - snprintf(hda_soc_components, sizeof(hda_soc_components), - "cfg-dmics:%d", mach->mach_params.dmic_num); - hda_soc_card.components = hda_soc_components; + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "cfg-dmics:%d", + mach->mach_params.dmic_num); + if (!card->components) + return -ENOMEM; } - ret = devm_snd_soc_register_card(&pdev->dev, &hda_soc_card); + ret = snd_soc_fixup_dai_links_platform_name(card, + mach->mach_params.platform); + if (ret) + return ret; + + snd_soc_card_set_drvdata(card, ctx); + + ret = devm_snd_soc_register_card(&pdev->dev, card); if (!ret) - skl_set_hda_codec_autosuspend_delay(&hda_soc_card); + skl_set_hda_codec_autosuspend_delay(card); return ret; } @@ -256,4 +162,4 @@ MODULE_DESCRIPTION("SKL/KBL/BXT/APL HDA Generic Machine driver"); MODULE_AUTHOR("Rakesh Ughreja <rakesh.a.ughreja@intel.com>"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:skl_hda_dsp_generic"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_BOARD_HELPERS"); diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c deleted file mode 100644 index 0e7025834594..000000000000 --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c +++ /dev/null @@ -1,703 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel Skylake I2S Machine Driver with MAXIM98357A - * and NAU88L25 - * - * Copyright (C) 2015, Intel Corporation. All rights reserved. - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/jack.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include "../../codecs/nau8825.h" -#include "../../codecs/hdac_hdmi.h" - -#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi" -#define SKL_MAXIM_CODEC_DAI "HiFi" -#define DMIC_CH(p) p->list[p->count-1] - -static struct snd_soc_jack skylake_headset; -static struct snd_soc_card skylake_audio_card; -static const struct snd_pcm_hw_constraint_list *dmic_constraints; -static struct snd_soc_jack skylake_hdmi[3]; - -struct skl_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct skl_nau8825_private { - struct list_head hdmi_pcm_list; -}; - -enum { - SKL_DPCM_AUDIO_PB = 0, - SKL_DPCM_AUDIO_CP, - SKL_DPCM_AUDIO_REF_CP, - SKL_DPCM_AUDIO_DMIC_CP, - SKL_DPCM_AUDIO_HDMI1_PB, - SKL_DPCM_AUDIO_HDMI2_PB, - SKL_DPCM_AUDIO_HDMI3_PB, -}; - -static int platform_clock_control(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; - struct snd_soc_dai *codec_dai; - int ret; - - codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI); - if (!codec_dai) { - dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); - return -EIO; - } - - if (SND_SOC_DAPM_EVENT_ON(event)) { - ret = snd_soc_dai_set_sysclk(codec_dai, - NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN); - if (ret < 0) { - dev_err(card->dev, "set sysclk err = %d\n", ret); - return -EIO; - } - } else { - ret = snd_soc_dai_set_sysclk(codec_dai, - NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN); - if (ret < 0) { - dev_err(card->dev, "set sysclk err = %d\n", ret); - return -EIO; - } - } - - return ret; -} - -static const struct snd_kcontrol_new skylake_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Spk"), -}; - -static const struct snd_soc_dapm_widget skylake_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("Spk", NULL), - SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("DP1", NULL), - SND_SOC_DAPM_SPK("DP2", NULL), - SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, - platform_clock_control, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), -}; - -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, -}; - -static const struct snd_soc_dapm_route skylake_map[] = { - /* HP jack connectors - unknown if we have jack detection */ - { "Headphone Jack", NULL, "HPOL" }, - { "Headphone Jack", NULL, "HPOR" }, - - /* speaker */ - { "Spk", NULL, "Speaker" }, - - /* other jacks */ - { "MIC", NULL, "Headset Mic" }, - { "DMic", NULL, "SoC DMIC" }, - - /* CODEC BE connections */ - { "HiFi Playback", NULL, "ssp0 Tx" }, - { "ssp0 Tx", NULL, "codec0_out" }, - - { "Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec1_out" }, - - { "codec0_in", NULL, "ssp1 Rx" }, - { "ssp1 Rx", NULL, "Capture" }, - - /* DMIC */ - { "dmic01_hifi", NULL, "DMIC01 Rx" }, - { "DMIC01 Rx", NULL, "DMIC AIF" }, - - { "hifi3", NULL, "iDisp3 Tx"}, - { "iDisp3 Tx", NULL, "iDisp3_out"}, - { "hifi2", NULL, "iDisp2 Tx"}, - { "iDisp2 Tx", NULL, "iDisp2_out"}, - { "hifi1", NULL, "iDisp1 Tx"}, - { "iDisp1 Tx", NULL, "iDisp1_out"}, - - { "Headphone Jack", NULL, "Platform Clock" }, - { "Headset Mic", NULL, "Platform Clock" }, -}; - -static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - - /* The ADSP will convert the FE rate to 48k, stereo */ - rate->min = rate->max = 48000; - chan->min = chan->max = 2; - - /* set SSP0 to 24 bit */ - snd_mask_none(fmt); - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); - - return 0; -} - -static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret; - struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; - - /* - * Headset buttons map to the google Reference headset. - * These can be configured by userspace. - */ - ret = snd_soc_card_jack_new_pins(&skylake_audio_card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset, - jack_pins, - ARRAY_SIZE(jack_pins)); - if (ret) { - dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); - return ret; - } - - nau8825_enable_jack_detect(component, &skylake_headset); - - snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); - - return ret; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct skl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = SKL_DPCM_AUDIO_HDMI1_PB; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct skl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = SKL_DPCM_AUDIO_HDMI2_PB; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct skl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = SKL_DPCM_AUDIO_HDMI3_PB; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dapm_context *dapm; - 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"); - - return 0; -} - -static const unsigned int rates[] = { - 48000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static const unsigned int channels[] = { - 2, -}; - -static const struct snd_pcm_hw_constraint_list constraints_channels = { - .count = ARRAY_SIZE(channels), - .list = channels, - .mask = 0, -}; - -static int skl_fe_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - /* - * On this platform for PCM device we support, - * 48Khz - * stereo - * 16 bit audio - */ - - runtime->hw.channels_max = 2; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels); - - runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; - snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); - - snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); - - return 0; -} - -static const struct snd_soc_ops skylake_nau8825_fe_ops = { - .startup = skl_fe_startup, -}; - -static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - 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, - NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN); - - if (ret < 0) - dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); - - return ret; -} - -static const struct snd_soc_ops skylake_nau8825_ops = { - .hw_params = skylake_nau8825_hw_params, -}; - -static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2) - chan->min = chan->max = 2; - else - chan->min = chan->max = 4; - - return 0; -} - -static const unsigned int channels_dmic[] = { - 2, 4, -}; - -static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = { - .count = ARRAY_SIZE(channels_dmic), - .list = channels_dmic, - .mask = 0, -}; - -static const unsigned int dmic_2ch[] = { - 2, -}; - -static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { - .count = ARRAY_SIZE(dmic_2ch), - .list = dmic_2ch, - .mask = 0, -}; - -static int skylake_dmic_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw.channels_max = DMIC_CH(dmic_constraints); - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - dmic_constraints); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); -} - -static const struct snd_soc_ops skylake_dmic_ops = { - .startup = skylake_dmic_startup, -}; - -static const unsigned int rates_16000[] = { - 16000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_16000 = { - .count = ARRAY_SIZE(rates_16000), - .list = rates_16000, -}; - -static const unsigned int ch_mono[] = { - 1, -}; - -static const struct snd_pcm_hw_constraint_list constraints_refcap = { - .count = ARRAY_SIZE(ch_mono), - .list = ch_mono, -}; - -static int skylake_refcap_startup(struct snd_pcm_substream *substream) -{ - substream->runtime->hw.channels_max = 1; - snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_refcap); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &constraints_16000); -} - -static const struct snd_soc_ops skylake_refcap_ops = { - .startup = skylake_refcap_startup, -}; - -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); - -SND_SOC_DAILINK_DEF(reference, - DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); - -SND_SOC_DAILINK_DEF(dmic, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); - -SND_SOC_DAILINK_DEF(hdmi1, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi2, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi3, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); - -SND_SOC_DAILINK_DEF(ssp0_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); -SND_SOC_DAILINK_DEF(ssp0_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", SKL_MAXIM_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(ssp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); -SND_SOC_DAILINK_DEF(ssp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", - SKL_NUVOTON_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(dmic_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); -SND_SOC_DAILINK_DEF(dmic_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); - -/* skylake digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link skylake_dais[] = { - /* Front End DAI links */ - [SKL_DPCM_AUDIO_PB] = { - .name = "Skl Audio Port", - .stream_name = "Audio", - .dynamic = 1, - .nonatomic = 1, - .init = skylake_nau8825_fe_init, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .ops = &skylake_nau8825_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [SKL_DPCM_AUDIO_CP] = { - .name = "Skl Audio Capture Port", - .stream_name = "Audio Record", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, - .ops = &skylake_nau8825_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [SKL_DPCM_AUDIO_REF_CP] = { - .name = "Skl Audio Reference cap", - .stream_name = "Wake on Voice", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &skylake_refcap_ops, - SND_SOC_DAILINK_REG(reference, dummy, platform), - }, - [SKL_DPCM_AUDIO_DMIC_CP] = { - .name = "Skl Audio DMIC cap", - .stream_name = "dmiccap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &skylake_dmic_ops, - SND_SOC_DAILINK_REG(dmic, dummy, platform), - }, - [SKL_DPCM_AUDIO_HDMI1_PB] = { - .name = "Skl HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [SKL_DPCM_AUDIO_HDMI2_PB] = { - .name = "Skl HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - [SKL_DPCM_AUDIO_HDMI3_PB] = { - .name = "Skl HDMI Port3", - .stream_name = "Hdmi3", - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi3, dummy, platform), - }, - - /* Back End DAI links */ - { - /* SSP0 - Codec */ - .name = "SSP0-Codec", - .id = 0, - .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = skylake_ssp_fixup, - .dpcm_playback = 1, - SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform), - }, - { - /* SSP1 - Codec */ - .name = "SSP1-Codec", - .id = 1, - .no_pcm = 1, - .init = skylake_nau8825_codec_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = skylake_ssp_fixup, - .ops = &skylake_nau8825_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), - }, - { - .name = "dmic01", - .id = 2, - .be_hw_params_fixup = skylake_dmic_fixup, - .ignore_suspend = 1, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), - }, - { - .name = "iDisp1", - .id = 3, - .dpcm_playback = 1, - .init = skylake_hdmi1_init, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 4, - .init = skylake_hdmi2_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, - { - .name = "iDisp3", - .id = 5, - .init = skylake_hdmi3_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), - }, -}; - -#define NAME_SIZE 32 -static int skylake_card_late_probe(struct snd_soc_card *card) -{ - struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card); - struct skl_hdmi_pcm *pcm; - struct snd_soc_component *component = NULL; - int err, i = 0; - char jack_name[NAME_SIZE]; - - 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, - &skylake_hdmi[i]); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &skylake_hdmi[i]); - if (err < 0) - return err; - - i++; - } - - if (!component) - return -EINVAL; - - return hdac_hdmi_jack_port_init(component, &card->dapm); -} - -/* skylake audio machine driver for SPT + NAU88L25 */ -static struct snd_soc_card skylake_audio_card = { - .name = "sklnau8825max", - .owner = THIS_MODULE, - .dai_link = skylake_dais, - .num_links = ARRAY_SIZE(skylake_dais), - .controls = skylake_controls, - .num_controls = ARRAY_SIZE(skylake_controls), - .dapm_widgets = skylake_widgets, - .num_dapm_widgets = ARRAY_SIZE(skylake_widgets), - .dapm_routes = skylake_map, - .num_dapm_routes = ARRAY_SIZE(skylake_map), - .fully_routed = true, - .late_probe = skylake_card_late_probe, -}; - -static int skylake_audio_probe(struct platform_device *pdev) -{ - struct skl_nau8825_private *ctx; - struct snd_soc_acpi_mach *mach; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - - skylake_audio_card.dev = &pdev->dev; - snd_soc_card_set_drvdata(&skylake_audio_card, ctx); - - mach = pdev->dev.platform_data; - if (mach) - dmic_constraints = mach->mach_params.dmic_num == 2 ? - &constraints_dmic_2ch : &constraints_dmic_channels; - - return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); -} - -static const struct platform_device_id skl_board_ids[] = { - { .name = "skl_n88l25_m98357a" }, - { .name = "kbl_n88l25_m98357a" }, - { } -}; -MODULE_DEVICE_TABLE(platform, skl_board_ids); - -static struct platform_driver skylake_audio = { - .probe = skylake_audio_probe, - .driver = { - .name = "skl_n88l25_m98357a", - .pm = &snd_soc_pm_ops, - }, - .id_table = skl_board_ids, -}; - -module_platform_driver(skylake_audio) - -/* Module information */ -MODULE_DESCRIPTION("Audio Machine driver-NAU88L25 & MAX98357A in I2S mode"); -MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c deleted file mode 100644 index fadc25a536b4..000000000000 --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c +++ /dev/null @@ -1,751 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel Skylake I2S Machine Driver for NAU88L25+SSM4567 - * - * Copyright (C) 2015, Intel Corporation. All rights reserved. - * - * Modified from: - * Intel Skylake I2S Machine Driver for NAU88L25 and SSM4567 - * - * Copyright (C) 2015, Intel Corporation. All rights reserved. - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/jack.h> -#include <sound/pcm_params.h> -#include "../../codecs/nau8825.h" -#include "../../codecs/hdac_hdmi.h" - -#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi" -#define SKL_SSM_CODEC_DAI "ssm4567-hifi" -#define DMIC_CH(p) p->list[p->count-1] - -static struct snd_soc_jack skylake_headset; -static struct snd_soc_card skylake_audio_card; -static const struct snd_pcm_hw_constraint_list *dmic_constraints; -static struct snd_soc_jack skylake_hdmi[3]; - -struct skl_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct skl_nau88125_private { - struct list_head hdmi_pcm_list; -}; -enum { - SKL_DPCM_AUDIO_PB = 0, - SKL_DPCM_AUDIO_CP, - SKL_DPCM_AUDIO_REF_CP, - SKL_DPCM_AUDIO_DMIC_CP, - SKL_DPCM_AUDIO_HDMI1_PB, - SKL_DPCM_AUDIO_HDMI2_PB, - SKL_DPCM_AUDIO_HDMI3_PB, -}; - -static const struct snd_kcontrol_new skylake_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Left Speaker"), - SOC_DAPM_PIN_SWITCH("Right Speaker"), -}; - -static int platform_clock_control(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; - struct snd_soc_dai *codec_dai; - int ret; - - codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI); - if (!codec_dai) { - dev_err(card->dev, "Codec dai not found\n"); - return -EIO; - } - - if (SND_SOC_DAPM_EVENT_ON(event)) { - ret = snd_soc_dai_set_sysclk(codec_dai, - NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN); - if (ret < 0) { - dev_err(card->dev, "set sysclk err = %d\n", ret); - return -EIO; - } - } else { - ret = snd_soc_dai_set_sysclk(codec_dai, - NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN); - if (ret < 0) { - dev_err(card->dev, "set sysclk err = %d\n", ret); - return -EIO; - } - } - return ret; -} - -static const struct snd_soc_dapm_widget skylake_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("Left Speaker", NULL), - SND_SOC_DAPM_SPK("Right Speaker", NULL), - SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("DP1", NULL), - SND_SOC_DAPM_SPK("DP2", NULL), - SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, - platform_clock_control, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), -}; - -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, -}; - -static const struct snd_soc_dapm_route skylake_map[] = { - /* HP jack connectors - unknown if we have jack detection */ - {"Headphone Jack", NULL, "HPOL"}, - {"Headphone Jack", NULL, "HPOR"}, - - /* speaker */ - {"Left Speaker", NULL, "Left OUT"}, - {"Right Speaker", NULL, "Right OUT"}, - - /* other jacks */ - {"MIC", NULL, "Headset Mic"}, - {"DMic", NULL, "SoC DMIC"}, - - /* CODEC BE connections */ - { "Left Playback", NULL, "ssp0 Tx"}, - { "Right Playback", NULL, "ssp0 Tx"}, - { "ssp0 Tx", NULL, "codec0_out"}, - - /* IV feedback path */ - { "codec0_lp_in", NULL, "ssp0 Rx"}, - { "ssp0 Rx", NULL, "Left Capture Sense" }, - { "ssp0 Rx", NULL, "Right Capture Sense" }, - - { "Playback", NULL, "ssp1 Tx"}, - { "ssp1 Tx", NULL, "codec1_out"}, - - { "codec0_in", NULL, "ssp1 Rx" }, - { "ssp1 Rx", NULL, "Capture" }, - - /* DMIC */ - { "dmic01_hifi", NULL, "DMIC01 Rx" }, - { "DMIC01 Rx", NULL, "DMIC AIF" }, - - { "hifi3", NULL, "iDisp3 Tx"}, - { "iDisp3 Tx", NULL, "iDisp3_out"}, - { "hifi2", NULL, "iDisp2 Tx"}, - { "iDisp2 Tx", NULL, "iDisp2_out"}, - { "hifi1", NULL, "iDisp1 Tx"}, - { "iDisp1 Tx", NULL, "iDisp1_out"}, - - { "Headphone Jack", NULL, "Platform Clock" }, - { "Headset Mic", NULL, "Platform Clock" }, -}; - -static struct snd_soc_codec_conf ssm4567_codec_conf[] = { - { - .dlc = COMP_CODEC_CONF("i2c-INT343B:00"), - .name_prefix = "Left", - }, - { - .dlc = COMP_CODEC_CONF("i2c-INT343B:01"), - .name_prefix = "Right", - }, -}; - -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(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(snd_soc_rtd_to_codec(rtd, 1), 0x02, 0x02, 2, 48); - if (ret < 0) - return ret; - - return ret; -} - -static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret; - struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; - - /* - * 4 buttons here map to the google Reference headset - * The use of these buttons can be decided by the user space. - */ - ret = snd_soc_card_jack_new_pins(&skylake_audio_card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset, - jack_pins, - ARRAY_SIZE(jack_pins)); - if (ret) { - dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); - return ret; - } - - nau8825_enable_jack_detect(component, &skylake_headset); - - snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); - - return ret; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct skl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = SKL_DPCM_AUDIO_HDMI1_PB; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct skl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = SKL_DPCM_AUDIO_HDMI2_PB; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct skl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = SKL_DPCM_AUDIO_HDMI3_PB; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dapm_context *dapm; - 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"); - - return 0; -} - -static const unsigned int rates[] = { - 48000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static const unsigned int channels[] = { - 2, -}; - -static const struct snd_pcm_hw_constraint_list constraints_channels = { - .count = ARRAY_SIZE(channels), - .list = channels, - .mask = 0, -}; - -static int skl_fe_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - /* - * on this platform for PCM device we support, - * 48Khz - * stereo - * 16 bit audio - */ - - runtime->hw.channels_max = 2; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels); - - runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; - snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); - - snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); - - return 0; -} - -static const struct snd_soc_ops skylake_nau8825_fe_ops = { - .startup = skl_fe_startup, -}; - -static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - - /* The ADSP will convert the FE rate to 48k, stereo */ - rate->min = rate->max = 48000; - chan->min = chan->max = 2; - - /* set SSP0 to 24 bit */ - snd_mask_none(fmt); - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); - return 0; -} - -static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2) - chan->min = chan->max = 2; - else - chan->min = chan->max = 4; - - return 0; -} - -static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - 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, - NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN); - - if (ret < 0) - dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); - - return ret; -} - -static const struct snd_soc_ops skylake_nau8825_ops = { - .hw_params = skylake_nau8825_hw_params, -}; - -static const unsigned int channels_dmic[] = { - 2, 4, -}; - -static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = { - .count = ARRAY_SIZE(channels_dmic), - .list = channels_dmic, - .mask = 0, -}; - -static const unsigned int dmic_2ch[] = { - 2, -}; - -static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = { - .count = ARRAY_SIZE(dmic_2ch), - .list = dmic_2ch, - .mask = 0, -}; - -static int skylake_dmic_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw.channels_max = DMIC_CH(dmic_constraints); - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - dmic_constraints); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); -} - -static const struct snd_soc_ops skylake_dmic_ops = { - .startup = skylake_dmic_startup, -}; - -static const unsigned int rates_16000[] = { - 16000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_16000 = { - .count = ARRAY_SIZE(rates_16000), - .list = rates_16000, -}; - -static const unsigned int ch_mono[] = { - 1, -}; - -static const struct snd_pcm_hw_constraint_list constraints_refcap = { - .count = ARRAY_SIZE(ch_mono), - .list = ch_mono, -}; - -static int skylake_refcap_startup(struct snd_pcm_substream *substream) -{ - substream->runtime->hw.channels_max = 1; - snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_refcap); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &constraints_16000); -} - -static const struct snd_soc_ops skylake_refcap_ops = { - .startup = skylake_refcap_startup, -}; - -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); - -SND_SOC_DAILINK_DEF(reference, - DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); - -SND_SOC_DAILINK_DEF(dmic, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); - -SND_SOC_DAILINK_DEF(hdmi1, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi2, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi3, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); - -SND_SOC_DAILINK_DEF(ssp0_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); -SND_SOC_DAILINK_DEF(ssp0_codec, - DAILINK_COMP_ARRAY( - /* Left */ COMP_CODEC("i2c-INT343B:00", SKL_SSM_CODEC_DAI), - /* Right */ COMP_CODEC("i2c-INT343B:01", SKL_SSM_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(ssp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); -SND_SOC_DAILINK_DEF(ssp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", SKL_NUVOTON_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(dmic01_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); -SND_SOC_DAILINK_DEF(dmic_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); - -/* skylake digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link skylake_dais[] = { - /* Front End DAI links */ - [SKL_DPCM_AUDIO_PB] = { - .name = "Skl Audio Port", - .stream_name = "Audio", - .dynamic = 1, - .nonatomic = 1, - .init = skylake_nau8825_fe_init, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .ops = &skylake_nau8825_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [SKL_DPCM_AUDIO_CP] = { - .name = "Skl Audio Capture Port", - .stream_name = "Audio Record", - .dynamic = 1, - .nonatomic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_capture = 1, - .ops = &skylake_nau8825_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [SKL_DPCM_AUDIO_REF_CP] = { - .name = "Skl Audio Reference cap", - .stream_name = "Wake on Voice", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &skylake_refcap_ops, - SND_SOC_DAILINK_REG(reference, dummy, platform), - }, - [SKL_DPCM_AUDIO_DMIC_CP] = { - .name = "Skl Audio DMIC cap", - .stream_name = "dmiccap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &skylake_dmic_ops, - SND_SOC_DAILINK_REG(dmic, dummy, platform), - }, - [SKL_DPCM_AUDIO_HDMI1_PB] = { - .name = "Skl HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [SKL_DPCM_AUDIO_HDMI2_PB] = { - .name = "Skl HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - [SKL_DPCM_AUDIO_HDMI3_PB] = { - .name = "Skl HDMI Port3", - .stream_name = "Hdmi3", - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi3, dummy, platform), - }, - - /* Back End DAI links */ - { - /* SSP0 - Codec */ - .name = "SSP0-Codec", - .id = 0, - .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_DSP_A | - SND_SOC_DAIFMT_IB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .init = skylake_ssm4567_codec_init, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = skylake_ssp_fixup, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform), - }, - { - /* SSP1 - Codec */ - .name = "SSP1-Codec", - .id = 1, - .no_pcm = 1, - .init = skylake_nau8825_codec_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = skylake_ssp_fixup, - .ops = &skylake_nau8825_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), - }, - { - .name = "dmic01", - .id = 2, - .ignore_suspend = 1, - .be_hw_params_fixup = skylake_dmic_fixup, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic01_pin, dmic_codec, platform), - }, - { - .name = "iDisp1", - .id = 3, - .dpcm_playback = 1, - .init = skylake_hdmi1_init, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 4, - .init = skylake_hdmi2_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, - { - .name = "iDisp3", - .id = 5, - .init = skylake_hdmi3_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), - }, -}; - -#define NAME_SIZE 32 -static int skylake_card_late_probe(struct snd_soc_card *card) -{ - struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card); - struct skl_hdmi_pcm *pcm; - struct snd_soc_component *component = NULL; - int err, i = 0; - char jack_name[NAME_SIZE]; - - 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, - &skylake_hdmi[i]); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &skylake_hdmi[i]); - if (err < 0) - return err; - - i++; - } - - if (!component) - return -EINVAL; - - return hdac_hdmi_jack_port_init(component, &card->dapm); -} - -/* skylake audio machine driver for SPT + NAU88L25 */ -static struct snd_soc_card skylake_audio_card = { - .name = "sklnau8825adi", - .owner = THIS_MODULE, - .dai_link = skylake_dais, - .num_links = ARRAY_SIZE(skylake_dais), - .controls = skylake_controls, - .num_controls = ARRAY_SIZE(skylake_controls), - .dapm_widgets = skylake_widgets, - .num_dapm_widgets = ARRAY_SIZE(skylake_widgets), - .dapm_routes = skylake_map, - .num_dapm_routes = ARRAY_SIZE(skylake_map), - .codec_conf = ssm4567_codec_conf, - .num_configs = ARRAY_SIZE(ssm4567_codec_conf), - .fully_routed = true, - .disable_route_checks = true, - .late_probe = skylake_card_late_probe, -}; - -static int skylake_audio_probe(struct platform_device *pdev) -{ - struct skl_nau88125_private *ctx; - struct snd_soc_acpi_mach *mach; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - - skylake_audio_card.dev = &pdev->dev; - snd_soc_card_set_drvdata(&skylake_audio_card, ctx); - - mach = pdev->dev.platform_data; - if (mach) - dmic_constraints = mach->mach_params.dmic_num == 2 ? - &constraints_dmic_2ch : &constraints_dmic_channels; - - return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); -} - -static const struct platform_device_id skl_board_ids[] = { - { .name = "skl_n88l25_s4567" }, - { .name = "kbl_n88l25_s4567" }, - { } -}; -MODULE_DEVICE_TABLE(platform, skl_board_ids); - -static struct platform_driver skylake_audio = { - .probe = skylake_audio_probe, - .driver = { - .name = "skl_n88l25_s4567", - .pm = &snd_soc_pm_ops, - }, - .id_table = skl_board_ids, -}; - -module_platform_driver(skylake_audio) - -/* Module information */ -MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>"); -MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); -MODULE_AUTHOR("Naveen M <naveen.m@intel.com>"); -MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>"); -MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>"); -MODULE_DESCRIPTION("Intel Audio Machine driver for SKL with NAU88L25 and SSM4567 in I2S Mode"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c deleted file mode 100644 index c59c60e28091..000000000000 --- a/sound/soc/intel/boards/skl_rt286.c +++ /dev/null @@ -1,567 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel Skylake I2S Machine Driver - * - * Copyright (C) 2014-2015, Intel Corporation. All rights reserved. - * - * Modified from: - * Intel Broadwell Wildcatpoint SST Audio - * - * Copyright (C) 2013, Intel Corporation. All rights reserved. - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> -#include <sound/jack.h> -#include <sound/pcm_params.h> -#include "../../codecs/rt286.h" -#include "../../codecs/hdac_hdmi.h" - -static struct snd_soc_jack skylake_headset; -static struct snd_soc_jack skylake_hdmi[3]; - -struct skl_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct skl_rt286_private { - struct list_head hdmi_pcm_list; -}; - -enum { - SKL_DPCM_AUDIO_PB = 0, - SKL_DPCM_AUDIO_DB_PB, - SKL_DPCM_AUDIO_CP, - SKL_DPCM_AUDIO_REF_CP, - SKL_DPCM_AUDIO_DMIC_CP, - SKL_DPCM_AUDIO_HDMI1_PB, - SKL_DPCM_AUDIO_HDMI2_PB, - SKL_DPCM_AUDIO_HDMI3_PB, -}; - -/* Headset jack detection DAPM pins */ -static struct snd_soc_jack_pin skylake_headset_pins[] = { - { - .pin = "Mic Jack", - .mask = SND_JACK_MICROPHONE, - }, - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, -}; - -static const struct snd_kcontrol_new skylake_controls[] = { - SOC_DAPM_PIN_SWITCH("Speaker"), - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Mic Jack"), -}; - -static const struct snd_soc_dapm_widget skylake_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_SPK("Speaker", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), - SND_SOC_DAPM_MIC("DMIC2", NULL), - SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("HDMI1", NULL), - SND_SOC_DAPM_SPK("HDMI2", NULL), - SND_SOC_DAPM_SPK("HDMI3", NULL), -}; - -static const struct snd_soc_dapm_route skylake_rt286_map[] = { - /* speaker */ - {"Speaker", NULL, "SPOR"}, - {"Speaker", NULL, "SPOL"}, - - /* HP jack connectors - unknown if we have jack deteck */ - {"Headphone Jack", NULL, "HPO Pin"}, - - /* other jacks */ - {"MIC1", NULL, "Mic Jack"}, - - /* digital mics */ - {"DMIC1 Pin", NULL, "DMIC2"}, - {"DMic", NULL, "SoC DMIC"}, - - /* CODEC BE connections */ - { "AIF1 Playback", NULL, "ssp0 Tx"}, - { "ssp0 Tx", NULL, "codec0_out"}, - { "ssp0 Tx", NULL, "codec1_out"}, - - { "codec0_in", NULL, "ssp0 Rx" }, - { "codec1_in", NULL, "ssp0 Rx" }, - { "ssp0 Rx", NULL, "AIF1 Capture" }, - - { "dmic01_hifi", NULL, "DMIC01 Rx" }, - { "DMIC01 Rx", NULL, "DMIC AIF" }, - - { "hifi3", NULL, "iDisp3 Tx"}, - { "iDisp3 Tx", NULL, "iDisp3_out"}, - { "hifi2", NULL, "iDisp2 Tx"}, - { "iDisp2 Tx", NULL, "iDisp2_out"}, - { "hifi1", NULL, "iDisp1 Tx"}, - { "iDisp1 Tx", NULL, "iDisp1_out"}, - -}; - -static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dapm_context *dapm; - 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"); - - return 0; -} - -static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) -{ - 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", - SND_JACK_HEADSET | SND_JACK_BTN_0, - &skylake_headset, - skylake_headset_pins, ARRAY_SIZE(skylake_headset_pins)); - - if (ret) - return ret; - - snd_soc_component_set_jack(component, &skylake_headset, NULL); - - snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); - - return 0; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - struct skl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = SKL_DPCM_AUDIO_HDMI1_PB + dai->id; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -static const unsigned int rates[] = { - 48000, -}; - -static const struct snd_pcm_hw_constraint_list constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static const unsigned int channels[] = { - 2, -}; - -static const struct snd_pcm_hw_constraint_list constraints_channels = { - .count = ARRAY_SIZE(channels), - .list = channels, - .mask = 0, -}; - -static int skl_fe_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - /* - * on this platform for PCM device we support, - * 48Khz - * stereo - * 16 bit audio - */ - - runtime->hw.channels_max = 2; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels); - - runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; - snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); - - snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); - - return 0; -} - -static const struct snd_soc_ops skylake_rt286_fe_ops = { - .startup = skl_fe_startup, -}; - -static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - - /* The output is 48KHz, stereo, 16bits */ - rate->min = rate->max = 48000; - chan->min = chan->max = 2; - - /* set SSP0 to 24 bit */ - snd_mask_none(fmt); - snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); - return 0; -} - -static int skylake_rt286_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - 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); - if (ret < 0) - dev_err(rtd->dev, "set codec sysclk failed: %d\n", ret); - - return ret; -} - -static const struct snd_soc_ops skylake_rt286_ops = { - .hw_params = skylake_rt286_hw_params, -}; - -static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - if (params_channels(params) == 2) - chan->min = chan->max = 2; - else - chan->min = chan->max = 4; - - return 0; -} - -static const unsigned int channels_dmic[] = { - 2, 4, -}; - -static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = { - .count = ARRAY_SIZE(channels_dmic), - .list = channels_dmic, - .mask = 0, -}; - -static int skylake_dmic_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw.channels_max = 4; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_dmic_channels); - - return snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); -} - -static const struct snd_soc_ops skylake_dmic_ops = { - .startup = skylake_dmic_startup, -}; - -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); - -SND_SOC_DAILINK_DEF(deepbuffer, - DAILINK_COMP_ARRAY(COMP_CPU("Deepbuffer Pin"))); - -SND_SOC_DAILINK_DEF(reference, - DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); - -SND_SOC_DAILINK_DEF(dmic, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); - -SND_SOC_DAILINK_DEF(hdmi1, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi2, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); - -SND_SOC_DAILINK_DEF(hdmi3, - DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); - -SND_SOC_DAILINK_DEF(ssp0_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); -SND_SOC_DAILINK_DEF(ssp0_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT343A:00", "rt286-aif1"))); - -SND_SOC_DAILINK_DEF(dmic01_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); -SND_SOC_DAILINK_DEF(dmic_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); - -/* skylake digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link skylake_rt286_dais[] = { - /* Front End DAI links */ - [SKL_DPCM_AUDIO_PB] = { - .name = "Skl Audio Port", - .stream_name = "Audio", - .nonatomic = 1, - .dynamic = 1, - .init = skylake_rt286_fe_init, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST - }, - .dpcm_playback = 1, - .ops = &skylake_rt286_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [SKL_DPCM_AUDIO_DB_PB] = { - .name = "Skl Deepbuffer Port", - .stream_name = "Deep Buffer Audio", - .nonatomic = 1, - .dynamic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST - }, - .dpcm_playback = 1, - .ops = &skylake_rt286_fe_ops, - SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), - }, - [SKL_DPCM_AUDIO_CP] = { - .name = "Skl Audio Capture Port", - .stream_name = "Audio Record", - .nonatomic = 1, - .dynamic = 1, - .trigger = { - SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST - }, - .dpcm_capture = 1, - .ops = &skylake_rt286_fe_ops, - SND_SOC_DAILINK_REG(system, dummy, platform), - }, - [SKL_DPCM_AUDIO_REF_CP] = { - .name = "Skl Audio Reference cap", - .stream_name = "refcap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(reference, dummy, platform), - }, - [SKL_DPCM_AUDIO_DMIC_CP] = { - .name = "Skl Audio DMIC cap", - .stream_name = "dmiccap", - .init = NULL, - .dpcm_capture = 1, - .nonatomic = 1, - .dynamic = 1, - .ops = &skylake_dmic_ops, - SND_SOC_DAILINK_REG(dmic, dummy, platform), - }, - [SKL_DPCM_AUDIO_HDMI1_PB] = { - .name = "Skl HDMI Port1", - .stream_name = "Hdmi1", - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi1, dummy, platform), - }, - [SKL_DPCM_AUDIO_HDMI2_PB] = { - .name = "Skl HDMI Port2", - .stream_name = "Hdmi2", - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi2, dummy, platform), - }, - [SKL_DPCM_AUDIO_HDMI3_PB] = { - .name = "Skl HDMI Port3", - .stream_name = "Hdmi3", - .dpcm_playback = 1, - .init = NULL, - .nonatomic = 1, - .dynamic = 1, - SND_SOC_DAILINK_REG(hdmi3, dummy, platform), - }, - - /* Back End DAI links */ - { - /* SSP0 - Codec */ - .name = "SSP0-Codec", - .id = 0, - .no_pcm = 1, - .init = skylake_rt286_codec_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ignore_pmdown_time = 1, - .be_hw_params_fixup = skylake_ssp0_fixup, - .ops = &skylake_rt286_ops, - .dpcm_playback = 1, - .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform), - }, - { - .name = "dmic01", - .id = 1, - .be_hw_params_fixup = skylake_dmic_fixup, - .ignore_suspend = 1, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic01_pin, dmic_codec, platform), - }, - { - .name = "iDisp1", - .id = 2, - .init = skylake_hdmi_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), - }, - { - .name = "iDisp2", - .id = 3, - .init = skylake_hdmi_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), - }, - { - .name = "iDisp3", - .id = 4, - .init = skylake_hdmi_init, - .dpcm_playback = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), - }, -}; - -#define NAME_SIZE 32 -static int skylake_card_late_probe(struct snd_soc_card *card) -{ - struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card); - struct skl_hdmi_pcm *pcm; - struct snd_soc_component *component = NULL; - int err, i = 0; - char jack_name[NAME_SIZE]; - - 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, &skylake_hdmi[i]); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &skylake_hdmi[i]); - if (err < 0) - return err; - - i++; - } - - if (!component) - return -EINVAL; - - return hdac_hdmi_jack_port_init(component, &card->dapm); -} - -/* skylake audio machine driver for SPT + RT286S */ -static struct snd_soc_card skylake_rt286 = { - .name = "skylake-rt286", - .owner = THIS_MODULE, - .dai_link = skylake_rt286_dais, - .num_links = ARRAY_SIZE(skylake_rt286_dais), - .controls = skylake_controls, - .num_controls = ARRAY_SIZE(skylake_controls), - .dapm_widgets = skylake_widgets, - .num_dapm_widgets = ARRAY_SIZE(skylake_widgets), - .dapm_routes = skylake_rt286_map, - .num_dapm_routes = ARRAY_SIZE(skylake_rt286_map), - .fully_routed = true, - .late_probe = skylake_card_late_probe, -}; - -static int skylake_audio_probe(struct platform_device *pdev) -{ - struct skl_rt286_private *ctx; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - - skylake_rt286.dev = &pdev->dev; - snd_soc_card_set_drvdata(&skylake_rt286, ctx); - - return devm_snd_soc_register_card(&pdev->dev, &skylake_rt286); -} - -static const struct platform_device_id skl_board_ids[] = { - { .name = "skl_alc286s_i2s" }, - { .name = "kbl_alc286s_i2s" }, - { } -}; -MODULE_DEVICE_TABLE(platform, skl_board_ids); - -static struct platform_driver skylake_audio = { - .probe = skylake_audio_probe, - .driver = { - .name = "skl_alc286s_i2s", - .pm = &snd_soc_pm_ops, - }, - .id_table = skl_board_ids, - -}; - -module_platform_driver(skylake_audio) - -/* Module information */ -MODULE_AUTHOR("Omair Mohammed Abdullah <omair.m.abdullah@intel.com>"); -MODULE_DESCRIPTION("Intel SST Audio for Skylake"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/boards/sof_board_helpers.c b/sound/soc/intel/boards/sof_board_helpers.c index 088894ff4165..2ea1dda446ec 100644 --- a/sound/soc/intel/boards/sof_board_helpers.c +++ b/sound/soc/intel/boards/sof_board_helpers.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only // -// Copyright(c) 2023 Intel Corporation. All rights reserved. +// Copyright(c) 2023 Intel Corporation #include <sound/soc.h> #include "../common/soc-intel-quirks.h" @@ -35,7 +35,7 @@ int sof_intel_board_card_late_probe(struct snd_soc_card *card) 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); +EXPORT_SYMBOL_NS(sof_intel_board_card_late_probe, "SND_SOC_INTEL_SOF_BOARD_HELPERS"); /* * DMIC DAI Link @@ -71,9 +71,77 @@ static int dmic_init(struct snd_soc_pcm_runtime *rtd) } /* + * HDA External Codec DAI Link + */ +static const struct snd_soc_dapm_widget hda_widgets[] = { + SND_SOC_DAPM_MIC("Analog In", NULL), + SND_SOC_DAPM_MIC("Digital In", NULL), + SND_SOC_DAPM_MIC("Alt Analog In", NULL), + + SND_SOC_DAPM_HP("Analog Out", NULL), + SND_SOC_DAPM_SPK("Digital Out", NULL), + SND_SOC_DAPM_HP("Alt Analog Out", NULL), +}; + +static const struct snd_soc_dapm_route hda_routes[] = { + { "Codec Input Pin1", NULL, "Analog In" }, + { "Codec Input Pin2", NULL, "Digital In" }, + { "Codec Input Pin3", NULL, "Alt Analog In" }, + + { "Analog Out", NULL, "Codec Output Pin1" }, + { "Digital Out", NULL, "Codec Output Pin2" }, + { "Alt Analog Out", NULL, "Codec Output Pin3" }, + + /* CODEC BE connections */ + { "codec0_in", NULL, "Analog CPU Capture" }, + { "Analog CPU Capture", NULL, "Analog Codec Capture" }, + { "codec1_in", NULL, "Digital CPU Capture" }, + { "Digital CPU Capture", NULL, "Digital Codec Capture" }, + { "codec2_in", NULL, "Alt Analog CPU Capture" }, + { "Alt Analog CPU Capture", NULL, "Alt Analog Codec Capture" }, + + { "Analog Codec Playback", NULL, "Analog CPU Playback" }, + { "Analog CPU Playback", NULL, "codec0_out" }, + { "Digital Codec Playback", NULL, "Digital CPU Playback" }, + { "Digital CPU Playback", NULL, "codec1_out" }, + { "Alt Analog Codec Playback", NULL, "Alt Analog CPU Playback" }, + { "Alt Analog CPU Playback", NULL, "codec2_out" }, +}; + +static int hda_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_dapm_new_controls(&card->dapm, hda_widgets, + ARRAY_SIZE(hda_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add hda widgets, ret %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, hda_routes, + ARRAY_SIZE(hda_routes)); + if (ret) + dev_err(rtd->dev, "fail to add hda routes, ret %d\n", ret); + + return ret; +} + +/* * DAI Link Helpers */ +enum sof_dmic_be_type { + SOF_DMIC_01, + SOF_DMIC_16K, +}; + +enum sof_hda_be_type { + SOF_HDA_ANALOG, + SOF_HDA_DIGITAL, +}; + /* DEFAULT_LINK_ORDER: the order used in sof_rt5682 */ #define DEFAULT_LINK_ORDER SOF_LINK_ORDER(SOF_LINK_CODEC, \ SOF_LINK_DMIC01, \ @@ -90,6 +158,16 @@ static struct snd_soc_dai_link_component dmic_component[] = { } }; +SND_SOC_DAILINK_DEF(hda_analog_cpus, + DAILINK_COMP_ARRAY(COMP_CPU("Analog CPU DAI"))); +SND_SOC_DAILINK_DEF(hda_analog_codecs, + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D0", "Analog Codec DAI"))); + +SND_SOC_DAILINK_DEF(hda_digital_cpus, + DAILINK_COMP_ARRAY(COMP_CPU("Digital CPU DAI"))); +SND_SOC_DAILINK_DEF(hda_digital_codecs, + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D0", "Digital Codec DAI"))); + static struct snd_soc_dai_link_component platform_component[] = { { /* name might be overridden during probe */ @@ -97,14 +175,14 @@ static struct snd_soc_dai_link_component platform_component[] = { } }; -int sof_intel_board_set_codec_link(struct device *dev, - struct snd_soc_dai_link *link, int be_id, - enum sof_ssp_codec codec_type, int ssp_codec) +static int set_ssp_codec_link(struct device *dev, struct snd_soc_dai_link *link, + int be_id, enum snd_soc_acpi_intel_codec codec_type, + int ssp_codec) { struct snd_soc_dai_link_component *cpus; - dev_dbg(dev, "link %d: codec %s, ssp %d\n", be_id, - sof_ssp_get_codec_name(codec_type), ssp_codec); + dev_dbg(dev, "link %d: ssp codec %s, ssp %d\n", be_id, + snd_soc_acpi_intel_get_codec_name(codec_type), ssp_codec); /* link name */ link->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_codec); @@ -139,16 +217,12 @@ int sof_intel_board_set_codec_link(struct device *dev, link->id = be_id; link->no_pcm = 1; - link->dpcm_capture = 1; - link->dpcm_playback = 1; return 0; } -EXPORT_SYMBOL_NS(sof_intel_board_set_codec_link, SND_SOC_INTEL_SOF_BOARD_HELPERS); -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) +static int 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; @@ -192,20 +266,18 @@ int sof_intel_board_set_dmic_link(struct device *dev, link->init = dmic_init; link->ignore_suspend = 1; link->no_pcm = 1; - link->dpcm_capture = 1; + link->capture_only = 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) +static int set_idisp_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); + dev_dbg(dev, "link %d: idisp hdmi %d, idisp codec %d\n", be_id, hdmi_id, + idisp_codec); /* link name */ link->name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", hdmi_id); @@ -252,20 +324,19 @@ int sof_intel_board_set_intel_hdmi_link(struct device *dev, link->id = be_id; link->init = (hdmi_id == 1) ? hdmi_init : NULL; link->no_pcm = 1; - link->dpcm_playback = 1; + link->playback_only = 1; return 0; } -EXPORT_SYMBOL_NS(sof_intel_board_set_intel_hdmi_link, SND_SOC_INTEL_SOF_BOARD_HELPERS); -int sof_intel_board_set_ssp_amp_link(struct device *dev, - struct snd_soc_dai_link *link, int be_id, - enum sof_ssp_codec amp_type, int ssp_amp) +static int set_ssp_amp_link(struct device *dev, struct snd_soc_dai_link *link, + int be_id, enum snd_soc_acpi_intel_codec amp_type, + int ssp_amp) { struct snd_soc_dai_link_component *cpus; dev_dbg(dev, "link %d: ssp amp %s, ssp %d\n", be_id, - sof_ssp_get_codec_name(amp_type), ssp_amp); + snd_soc_acpi_intel_get_codec_name(amp_type), ssp_amp); /* link name */ link->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_amp); @@ -288,21 +359,18 @@ int sof_intel_board_set_ssp_amp_link(struct device *dev, /* codecs - caller to handle */ /* platforms */ + /* feedback stream or firmware-generated echo reference */ link->platforms = platform_component; link->num_platforms = ARRAY_SIZE(platform_component); link->id = be_id; link->no_pcm = 1; - link->dpcm_capture = 1; /* feedback stream or firmware-generated echo reference */ - link->dpcm_playback = 1; return 0; } -EXPORT_SYMBOL_NS(sof_intel_board_set_ssp_amp_link, SND_SOC_INTEL_SOF_BOARD_HELPERS); -int sof_intel_board_set_bt_link(struct device *dev, - struct snd_soc_dai_link *link, int be_id, - int ssp_bt) +static int set_bt_offload_link(struct device *dev, struct snd_soc_dai_link *link, + int be_id, int ssp_bt) { struct snd_soc_dai_link_component *cpus; @@ -336,16 +404,12 @@ int sof_intel_board_set_bt_link(struct device *dev, link->id = be_id; link->no_pcm = 1; - link->dpcm_capture = 1; - link->dpcm_playback = 1; return 0; } -EXPORT_SYMBOL_NS(sof_intel_board_set_bt_link, SND_SOC_INTEL_SOF_BOARD_HELPERS); -int sof_intel_board_set_hdmi_in_link(struct device *dev, - struct snd_soc_dai_link *link, int be_id, - int ssp_hdmi) +static int set_hdmi_in_link(struct device *dev, struct snd_soc_dai_link *link, + int be_id, int ssp_hdmi) { struct snd_soc_dai_link_component *cpus; @@ -379,11 +443,57 @@ int sof_intel_board_set_hdmi_in_link(struct device *dev, link->id = be_id; link->no_pcm = 1; - link->dpcm_capture = 1; + link->capture_only = 1; + + return 0; +} + +static int set_hda_codec_link(struct device *dev, struct snd_soc_dai_link *link, + int be_id, enum sof_hda_be_type be_type) +{ + switch (be_type) { + case SOF_HDA_ANALOG: + dev_dbg(dev, "link %d: hda analog\n", be_id); + + link->name = "Analog Playback and Capture"; + + /* cpus */ + link->cpus = hda_analog_cpus; + link->num_cpus = ARRAY_SIZE(hda_analog_cpus); + + /* codecs */ + link->codecs = hda_analog_codecs; + link->num_codecs = ARRAY_SIZE(hda_analog_codecs); + break; + case SOF_HDA_DIGITAL: + dev_dbg(dev, "link %d: hda digital\n", be_id); + + link->name = "Digital Playback and Capture"; + + /* cpus */ + link->cpus = hda_digital_cpus; + link->num_cpus = ARRAY_SIZE(hda_digital_cpus); + + /* codecs */ + link->codecs = hda_digital_codecs; + link->num_codecs = ARRAY_SIZE(hda_digital_codecs); + break; + default: + dev_err(dev, "invalid be type %d\n", be_type); + return -EINVAL; + } + + /* platforms */ + link->platforms = platform_component; + link->num_platforms = ARRAY_SIZE(platform_component); + + link->id = be_id; + if (be_type == SOF_HDA_ANALOG) + link->init = hda_init; + link->no_pcm = 1; return 0; } -EXPORT_SYMBOL_NS(sof_intel_board_set_hdmi_in_link, SND_SOC_INTEL_SOF_BOARD_HELPERS); static int calculate_num_links(struct sof_card_private *ctx) { @@ -414,6 +524,10 @@ static int calculate_num_links(struct sof_card_private *ctx) /* HDMI-In */ num_links += hweight32(ctx->ssp_mask_hdmi_in); + /* HDA external codec */ + if (ctx->hda_codec_present) + num_links += 2; + return num_links; } @@ -427,6 +541,7 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card, int ret; int ssp_hdmi_in = 0; unsigned long link_order, link; + unsigned long link_ids, be_id; num_links = calculate_num_links(ctx); @@ -440,22 +555,34 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card, else link_order = DEFAULT_LINK_ORDER; - dev_dbg(dev, "create dai links, link_order 0x%lx\n", link_order); + if (ctx->link_id_overwrite) + link_ids = ctx->link_id_overwrite; + else + link_ids = 0; + + dev_dbg(dev, "create dai links, link_order 0x%lx, id_overwrite 0x%lx\n", + link_order, link_ids); while (link_order) { link = link_order & SOF_LINK_ORDER_MASK; link_order >>= SOF_LINK_ORDER_SHIFT; + if (ctx->link_id_overwrite) { + be_id = link_ids & SOF_LINK_IDS_MASK; + link_ids >>= SOF_LINK_IDS_SHIFT; + } else { + /* use array index as link id */ + be_id = idx; + } + switch (link) { case SOF_LINK_CODEC: /* headphone codec */ if (ctx->codec_type == CODEC_NONE) continue; - ret = sof_intel_board_set_codec_link(dev, &links[idx], - idx, - ctx->codec_type, - ctx->ssp_codec); + ret = set_ssp_codec_link(dev, &links[idx], be_id, + ctx->codec_type, ctx->ssp_codec); if (ret) { dev_err(dev, "fail to set codec link, ret %d\n", ret); @@ -471,8 +598,7 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card, continue; /* at least we have dmic01 */ - ret = sof_intel_board_set_dmic_link(dev, &links[idx], - idx, SOF_DMIC_01); + ret = set_dmic_link(dev, &links[idx], be_id, SOF_DMIC_01); if (ret) { dev_err(dev, "fail to set dmic01 link, ret %d\n", ret); @@ -487,8 +613,8 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card, continue; /* set up 2 BE links at most */ - ret = sof_intel_board_set_dmic_link(dev, &links[idx], - idx, SOF_DMIC_16K); + ret = set_dmic_link(dev, &links[idx], be_id, + SOF_DMIC_16K); if (ret) { dev_err(dev, "fail to set dmic16k link, ret %d\n", ret); @@ -500,10 +626,9 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card, case SOF_LINK_IDISP_HDMI: /* idisp HDMI */ for (i = 1; i <= ctx->hdmi_num; i++) { - ret = sof_intel_board_set_intel_hdmi_link(dev, - &links[idx], - idx, i, - ctx->hdmi.idisp_codec); + ret = set_idisp_hdmi_link(dev, &links[idx], + be_id, i, + ctx->hdmi.idisp_codec); if (ret) { dev_err(dev, "fail to set hdmi link, ret %d\n", ret); @@ -511,6 +636,7 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card, } idx++; + be_id++; } break; case SOF_LINK_AMP: @@ -518,10 +644,8 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card, if (ctx->amp_type == CODEC_NONE) continue; - ret = sof_intel_board_set_ssp_amp_link(dev, &links[idx], - idx, - ctx->amp_type, - ctx->ssp_amp); + ret = set_ssp_amp_link(dev, &links[idx], be_id, + ctx->amp_type, ctx->ssp_amp); if (ret) { dev_err(dev, "fail to set amp link, ret %d\n", ret); @@ -536,8 +660,8 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card, if (!ctx->bt_offload_present) continue; - ret = sof_intel_board_set_bt_link(dev, &links[idx], idx, - ctx->ssp_bt); + ret = set_bt_offload_link(dev, &links[idx], be_id, + ctx->ssp_bt); if (ret) { dev_err(dev, "fail to set bt link, ret %d\n", ret); @@ -549,10 +673,8 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card, case SOF_LINK_HDMI_IN: /* HDMI-In */ for_each_set_bit(ssp_hdmi_in, &ctx->ssp_mask_hdmi_in, 32) { - ret = sof_intel_board_set_hdmi_in_link(dev, - &links[idx], - idx, - ssp_hdmi_in); + ret = set_hdmi_in_link(dev, &links[idx], be_id, + ssp_hdmi_in); if (ret) { dev_err(dev, "fail to set hdmi-in link, ret %d\n", ret); @@ -560,8 +682,35 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card, } idx++; + be_id++; } break; + case SOF_LINK_HDA: + /* HDA external codec */ + if (!ctx->hda_codec_present) + continue; + + ret = set_hda_codec_link(dev, &links[idx], be_id, + SOF_HDA_ANALOG); + if (ret) { + dev_err(dev, "fail to set hda analog link, ret %d\n", + ret); + return ret; + } + + idx++; + be_id++; + + ret = set_hda_codec_link(dev, &links[idx], be_id, + SOF_HDA_DIGITAL); + if (ret) { + dev_err(dev, "fail to set hda digital link, ret %d\n", + ret); + return ret; + } + + idx++; + break; case SOF_LINK_NONE: /* caught here if it's not used as terminator in macro */ fallthrough; @@ -582,28 +731,53 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card, return 0; } -EXPORT_SYMBOL_NS(sof_intel_board_set_dai_link, SND_SOC_INTEL_SOF_BOARD_HELPERS); +EXPORT_SYMBOL_NS(sof_intel_board_set_dai_link, "SND_SOC_INTEL_SOF_BOARD_HELPERS"); -struct snd_soc_dai *get_codec_dai_by_name(struct snd_soc_pcm_runtime *rtd, - const char * const dai_name[], int num_dais) +struct sof_card_private * +sof_intel_board_get_ctx(struct device *dev, unsigned long board_quirk) { - struct snd_soc_dai *dai; - int index; - int i; + struct sof_card_private *ctx; - for (index = 0; index < num_dais; index++) - for_each_rtd_codec_dais(rtd, i, dai) - if (strstr(dai->name, dai_name[index])) { - dev_dbg(rtd->card->dev, "get dai %s\n", dai->name); - return dai; - } + dev_dbg(dev, "create ctx, board_quirk 0x%lx\n", board_quirk); + + ctx = devm_kzalloc(dev, sizeof(struct sof_card_private), GFP_KERNEL); + if (!ctx) + return NULL; + + ctx->codec_type = snd_soc_acpi_intel_detect_codec_type(dev); + ctx->amp_type = snd_soc_acpi_intel_detect_amp_type(dev); + + ctx->dmic_be_num = 2; + ctx->hdmi_num = (board_quirk & SOF_NUM_IDISP_HDMI_MASK) >> + SOF_NUM_IDISP_HDMI_SHIFT; + /* default number of HDMI DAI's */ + if (!ctx->hdmi_num) + ctx->hdmi_num = 3; + + /* port number/mask of peripherals attached to ssp interface */ + if (ctx->codec_type != CODEC_NONE) + ctx->ssp_codec = (board_quirk & SOF_SSP_PORT_CODEC_MASK) >> + SOF_SSP_PORT_CODEC_SHIFT; + + if (ctx->amp_type != CODEC_NONE) + ctx->ssp_amp = (board_quirk & SOF_SSP_PORT_AMP_MASK) >> + SOF_SSP_PORT_AMP_SHIFT; + + if (board_quirk & SOF_BT_OFFLOAD_PRESENT) { + ctx->bt_offload_present = true; + ctx->ssp_bt = (board_quirk & SOF_SSP_PORT_BT_OFFLOAD_MASK) >> + SOF_SSP_PORT_BT_OFFLOAD_SHIFT; + } + + ctx->ssp_mask_hdmi_in = (board_quirk & SOF_SSP_MASK_HDMI_CAPTURE_MASK) >> + SOF_SSP_MASK_HDMI_CAPTURE_SHIFT; - return NULL; + return ctx; } -EXPORT_SYMBOL_NS(get_codec_dai_by_name, SND_SOC_INTEL_SOF_BOARD_HELPERS); +EXPORT_SYMBOL_NS(sof_intel_board_get_ctx, "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); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON"); +MODULE_IMPORT_NS("SND_SOC_ACPI_INTEL_MATCH"); diff --git a/sound/soc/intel/boards/sof_board_helpers.h b/sound/soc/intel/boards/sof_board_helpers.h index f42d5d640321..33a9601b770c 100644 --- a/sound/soc/intel/boards/sof_board_helpers.h +++ b/sound/soc/intel/boards/sof_board_helpers.h @@ -7,8 +7,46 @@ #define __SOF_INTEL_BOARD_HELPERS_H #include <sound/soc.h> +#include <sound/soc-acpi-intel-ssp-common.h> #include "sof_hdmi_common.h" -#include "sof_ssp_common.h" + +/* + * Common board quirks: from bit 8 to 31, LSB 8 bits reserved for machine + * drivers + */ + +/* SSP port number for headphone codec: 3 bits */ +#define SOF_SSP_PORT_CODEC_SHIFT 8 +#define SOF_SSP_PORT_CODEC_MASK (GENMASK(10, 8)) +#define SOF_SSP_PORT_CODEC(quirk) \ + (((quirk) << SOF_SSP_PORT_CODEC_SHIFT) & SOF_SSP_PORT_CODEC_MASK) + +/* SSP port number for speaker amplifier: 3 bits */ +#define SOF_SSP_PORT_AMP_SHIFT 11 +#define SOF_SSP_PORT_AMP_MASK (GENMASK(13, 11)) +#define SOF_SSP_PORT_AMP(quirk) \ + (((quirk) << SOF_SSP_PORT_AMP_SHIFT) & SOF_SSP_PORT_AMP_MASK) + +/* SSP port number for BT audio offload: 3 bits */ +#define SOF_SSP_PORT_BT_OFFLOAD_SHIFT 14 +#define SOF_SSP_PORT_BT_OFFLOAD_MASK (GENMASK(16, 14)) +#define SOF_SSP_PORT_BT_OFFLOAD(quirk) \ + (((quirk) << SOF_SSP_PORT_BT_OFFLOAD_SHIFT) & SOF_SSP_PORT_BT_OFFLOAD_MASK) + +/* SSP port mask for HDMI capture: 6 bits */ +#define SOF_SSP_MASK_HDMI_CAPTURE_SHIFT 17 +#define SOF_SSP_MASK_HDMI_CAPTURE_MASK (GENMASK(22, 17)) +#define SOF_SSP_MASK_HDMI_CAPTURE(quirk) \ + (((quirk) << SOF_SSP_MASK_HDMI_CAPTURE_SHIFT) & SOF_SSP_MASK_HDMI_CAPTURE_MASK) + +/* Number of idisp HDMI BE link: 3 bits */ +#define SOF_NUM_IDISP_HDMI_SHIFT 23 +#define SOF_NUM_IDISP_HDMI_MASK (GENMASK(25, 23)) +#define SOF_NUM_IDISP_HDMI(quirk) \ + (((quirk) << SOF_NUM_IDISP_HDMI_SHIFT) & SOF_NUM_IDISP_HDMI_MASK) + +/* Board uses BT audio offload */ +#define SOF_BT_OFFLOAD_PRESENT BIT(26) enum { SOF_LINK_NONE = 0, @@ -19,6 +57,7 @@ enum { SOF_LINK_AMP, SOF_LINK_BT_OFFLOAD, SOF_LINK_HDMI_IN, + SOF_LINK_HDA, }; #define SOF_LINK_ORDER_MASK (0xF) @@ -33,15 +72,40 @@ enum { (((k6) & SOF_LINK_ORDER_MASK) << (SOF_LINK_ORDER_SHIFT * 5)) | \ (((k7) & SOF_LINK_ORDER_MASK) << (SOF_LINK_ORDER_SHIFT * 6))) +#define SOF_LINK_IDS_MASK (0xF) +#define SOF_LINK_IDS_SHIFT (4) + +#define SOF_LINK_IDS(k1, k2, k3, k4, k5, k6, k7) \ + ((((k1) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 0)) | \ + (((k2) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 1)) | \ + (((k3) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 2)) | \ + (((k4) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 3)) | \ + (((k5) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 4)) | \ + (((k6) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 5)) | \ + (((k7) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 6))) + +/* + * sof_da7219_private: private data for da7219 machine driver + * + * @mclk_en: true for mclk pin is connected + * @pll_bypass: true for PLL bypass mode + */ +struct sof_da7219_private { + bool mclk_en; + bool pll_bypass; +}; + /* * sof_rt5682_private: private data for rt5682 machine driver * * @mclk: mclk clock data * @is_legacy_cpu: true for BYT/CHT boards + * @mclk_en: true for mclk pin is connected */ struct sof_rt5682_private { struct clk *mclk; bool is_legacy_cpu; + bool mclk_en; }; /* @@ -58,17 +122,20 @@ struct sof_rt5682_private { * @ssp_bt: ssp port number of BT offload BE link * @ssp_mask_hdmi_in: ssp port mask of HDMI-IN BE link * @bt_offload_present: true to create BT offload BE link + * @hda_codec_present: true to create HDA codec BE links * @codec_link: pointer to headset codec dai link * @amp_link: pointer to speaker amplifier dai link * @link_order_overwrite: custom DAI link order + * @link_id_overwrite: custom DAI link ID + * @da7219: private data for da7219 machine driver * @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; + enum snd_soc_acpi_intel_codec codec_type; + enum snd_soc_acpi_intel_codec amp_type; int dmic_be_num; int hdmi_num; @@ -79,46 +146,28 @@ struct sof_card_private { unsigned long ssp_mask_hdmi_in; bool bt_offload_present; + bool hda_codec_present; struct snd_soc_dai_link *codec_link; struct snd_soc_dai_link *amp_link; unsigned long link_order_overwrite; + /* + * A variable stores id for all BE DAI links, use SOF_LINK_IDS macro to + * build the value; use DAI link array index as id if zero. + */ + unsigned long link_id_overwrite; union { + struct sof_da7219_private da7219; 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_dai_link(struct device *dev, struct snd_soc_card *card, struct sof_card_private *ctx); - -int sof_intel_board_set_codec_link(struct device *dev, - struct snd_soc_dai_link *link, int be_id, - enum sof_ssp_codec codec_type, int ssp_codec); -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); -int sof_intel_board_set_ssp_amp_link(struct device *dev, - struct snd_soc_dai_link *link, int be_id, - enum sof_ssp_codec amp_type, int ssp_amp); -int sof_intel_board_set_bt_link(struct device *dev, - struct snd_soc_dai_link *link, int be_id, - int ssp_bt); -int sof_intel_board_set_hdmi_in_link(struct device *dev, - struct snd_soc_dai_link *link, int be_id, - int ssp_hdmi); - -struct snd_soc_dai *get_codec_dai_by_name(struct snd_soc_pcm_runtime *rtd, - const char * const dai_name[], int num_dais); +struct sof_card_private * +sof_intel_board_get_ctx(struct device *dev, unsigned long board_quirk); #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 e71e09124b34..8db7695b9747 100644 --- a/sound/soc/intel/boards/sof_cirrus_common.c +++ b/sound/soc/intel/boards/sof_cirrus_common.c @@ -193,14 +193,14 @@ void cs35l41_set_dai_link(struct snd_soc_dai_link *link) link->init = cs35l41_init; link->ops = &cs35l41_ops; } -EXPORT_SYMBOL_NS(cs35l41_set_dai_link, SND_SOC_INTEL_SOF_CIRRUS_COMMON); +EXPORT_SYMBOL_NS(cs35l41_set_dai_link, "SND_SOC_INTEL_SOF_CIRRUS_COMMON"); void cs35l41_set_codec_conf(struct snd_soc_card *card) { card->codec_conf = cs35l41_codec_conf; card->num_configs = ARRAY_SIZE(cs35l41_codec_conf); } -EXPORT_SYMBOL_NS(cs35l41_set_codec_conf, SND_SOC_INTEL_SOF_CIRRUS_COMMON); +EXPORT_SYMBOL_NS(cs35l41_set_codec_conf, "SND_SOC_INTEL_SOF_CIRRUS_COMMON"); MODULE_DESCRIPTION("ASoC Intel SOF Cirrus Logic helpers"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/boards/sof_cirrus_common.h b/sound/soc/intel/boards/sof_cirrus_common.h index d4ecf8d023d1..1c87637b9ef7 100644 --- a/sound/soc/intel/boards/sof_cirrus_common.h +++ b/sound/soc/intel/boards/sof_cirrus_common.h @@ -9,7 +9,7 @@ #define __SOF_CIRRUS_COMMON_H #include <sound/soc.h> -#include "sof_ssp_common.h" +#include <sound/soc-acpi-intel-ssp-common.h> /* * Cirrus Logic CS35L41/CS35L53 diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c index 323b86c42ef9..455c5bc8c634 100644 --- a/sound/soc/intel/boards/sof_cs42l42.c +++ b/sound/soc/intel/boards/sof_cs42l42.c @@ -22,23 +22,6 @@ #include "../common/soc-intel-quirks.h" #include "sof_board_helpers.h" #include "sof_maxim_common.h" -#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_CS42L42_SSP_AMP_SHIFT 4 -#define SOF_CS42L42_SSP_AMP_MASK (GENMASK(6, 4)) -#define SOF_CS42L42_SSP_AMP(quirk) \ - (((quirk) << SOF_CS42L42_SSP_AMP_SHIFT) & SOF_CS42L42_SSP_AMP_MASK) -#define SOF_CS42L42_NUM_HDMIDEV_SHIFT 7 -#define SOF_CS42L42_NUM_HDMIDEV_MASK (GENMASK(9, 7)) -#define SOF_CS42L42_NUM_HDMIDEV(quirk) \ - (((quirk) << SOF_CS42L42_NUM_HDMIDEV_SHIFT) & SOF_CS42L42_NUM_HDMIDEV_MASK) -#define SOF_BT_OFFLOAD_PRESENT BIT(25) -#define SOF_CS42L42_SSP_BT_SHIFT 26 -#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) static struct snd_soc_jack_pin jack_pins[] = { { @@ -52,7 +35,7 @@ static struct snd_soc_jack_pin jack_pins[] = { }; /* Default: SSP2 */ -static unsigned long sof_cs42l42_quirk = SOF_CS42L42_SSP_CODEC(2); +static unsigned long sof_cs42l42_quirk = SOF_SSP_PORT_CODEC(2); static int sof_cs42l42_init(struct snd_soc_pcm_runtime *rtd) { @@ -229,48 +212,26 @@ static int sof_audio_probe(struct platform_device *pdev) struct sof_card_private *ctx; int ret; - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - if (pdev->id_entry && pdev->id_entry->driver_data) sof_cs42l42_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); + dev_dbg(&pdev->dev, "sof_cs42l42_quirk = %lx\n", sof_cs42l42_quirk); + + /* initialize ctx with board quirk */ + ctx = sof_intel_board_get_ctx(&pdev->dev, sof_cs42l42_quirk); + if (!ctx) + return -ENOMEM; if (soc_intel_is_glk()) { ctx->dmic_be_num = 1; - ctx->hdmi_num = 3; /* overwrite the DAI link order for GLK boards */ ctx->link_order_overwrite = GLK_LINK_ORDER; - } else { - 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 (!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); - - /* port number of peripherals attached to ssp interface */ - ctx->ssp_bt = (sof_cs42l42_quirk & SOF_CS42L42_SSP_BT_MASK) >> - SOF_CS42L42_SSP_BT_SHIFT; - - ctx->ssp_amp = (sof_cs42l42_quirk & SOF_CS42L42_SSP_AMP_MASK) >> - SOF_CS42L42_SSP_AMP_SHIFT; - - ctx->ssp_codec = sof_cs42l42_quirk & SOF_CS42L42_SSP_CODEC_MASK; - - if (sof_cs42l42_quirk & SOF_BT_OFFLOAD_PRESENT) - ctx->bt_offload_present = true; - /* update dai_link */ ret = sof_card_dai_links_create(&pdev->dev, &sof_audio_card_cs42l42, ctx); if (ret) @@ -293,21 +254,36 @@ static int sof_audio_probe(struct platform_device *pdev) static const struct platform_device_id board_ids[] = { { .name = "glk_cs4242_mx98357a", - .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(2) | - SOF_CS42L42_SSP_AMP(1)), + .driver_data = (kernel_ulong_t)(SOF_SSP_PORT_CODEC(2) | + SOF_SSP_PORT_AMP(1)), }, { .name = "jsl_cs4242_mx98360a", - .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(0) | - SOF_CS42L42_SSP_AMP(1)), + .driver_data = (kernel_ulong_t)(SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1)), + }, + { + .name = "adl_cs42l42_def", + .driver_data = (kernel_ulong_t)(SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1) | + SOF_NUM_IDISP_HDMI(4) | + SOF_BT_OFFLOAD_PRESENT | + SOF_SSP_PORT_BT_OFFLOAD(2)), + }, + { + .name = "rpl_cs42l42_def", + .driver_data = (kernel_ulong_t)(SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1) | + SOF_NUM_IDISP_HDMI(4) | + SOF_BT_OFFLOAD_PRESENT | + SOF_SSP_PORT_BT_OFFLOAD(2)), }, { - .name = "adl_mx98360a_cs4242", - .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(0) | - SOF_CS42L42_SSP_AMP(1) | - SOF_CS42L42_NUM_HDMIDEV(4) | - SOF_BT_OFFLOAD_PRESENT | - SOF_CS42L42_SSP_BT(2)), + .name = "mtl_cs42l42_def", + .driver_data = (kernel_ulong_t)(SOF_SSP_PORT_CODEC(2) | + SOF_SSP_PORT_AMP(0) | + SOF_BT_OFFLOAD_PRESENT | + SOF_SSP_PORT_BT_OFFLOAD(1)), }, { } }; @@ -327,6 +303,5 @@ 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_SOF_BOARD_HELPERS); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_BOARD_HELPERS"); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_MAXIM_COMMON"); diff --git a/sound/soc/intel/boards/sof_da7219.c b/sound/soc/intel/boards/sof_da7219.c index 6eb5a6144e97..9b7082b239c1 100644 --- a/sound/soc/intel/boards/sof_da7219.c +++ b/sound/soc/intel/boards/sof_da7219.c @@ -15,35 +15,27 @@ #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_board_helpers.h" #include "sof_maxim_common.h" -#include "sof_ssp_common.h" -/* Board Quirks */ +/* Driver-specific board quirks: from bit 0 to 7 */ +#define SOF_DA7219_GLK_BOARD BIT(0) +#define SOF_DA7219_CML_BOARD BIT(1) #define SOF_DA7219_JSL_BOARD BIT(2) +#define SOF_DA7219_MCLK_EN BIT(3) #define DIALOG_CODEC_DAI "da7219-hifi" -struct 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; - - unsigned int pll_bypass:1; -}; - static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { 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 sof_card_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_dai *codec_dai; int ret = 0; - if (ctx->pll_bypass) + if (ctx->da7219.pll_bypass) return ret; /* PLL SRM mode */ @@ -74,8 +66,6 @@ static const struct snd_kcontrol_new controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headset Mic"), SOC_DAPM_PIN_SWITCH("Line Out"), - SOC_DAPM_PIN_SWITCH("Left Spk"), - SOC_DAPM_PIN_SWITCH("Right Spk"), }; static const struct snd_soc_dapm_widget widgets[] = { @@ -83,14 +73,9 @@ static const struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_LINE("Line Out", NULL), - SND_SOC_DAPM_SPK("Left Spk", NULL), - SND_SOC_DAPM_SPK("Right 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 audio_map[] = { @@ -102,9 +87,6 @@ static const struct snd_soc_dapm_route audio_map[] = { { "Headphone Jack", NULL, "Platform Clock" }, { "Headset Mic", NULL, "Platform Clock" }, { "Line Out", NULL, "Platform Clock" }, - - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, }; static struct snd_soc_jack_pin jack_pins[] = { @@ -124,7 +106,7 @@ static struct snd_soc_jack_pin jack_pins[] = { static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); + struct sof_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 = &ctx->headset_jack; @@ -147,7 +129,8 @@ static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) * 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) { + if (ctx->da7219.mclk_en && + (mclk_rate == 12288000 || mclk_rate == 24576000)) { /* PLL bypass mode */ dev_dbg(rtd->dev, "pll bypass mode, mclk rate %d\n", mclk_rate); @@ -157,7 +140,7 @@ static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ctx->pll_bypass = 1; + ctx->da7219.pll_bypass = true; } /* @@ -188,248 +171,30 @@ static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } -static int max98373_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) +static void da7219_codec_exit(struct snd_soc_pcm_runtime *rtd) { - 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 = snd_soc_rtd_to_codec(runtime, j); - - 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) { - dev_err(runtime->dev, "DEV0 TDM slot err:%d\n", ret); - return ret; - } - } - 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) { - dev_err(runtime->dev, "DEV1 TDM slot err:%d\n", ret); - return ret; - } - } - } + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; - return 0; -} - -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 = snd_soc_rtd_to_codec(rtd, 0); - - ctx->hdmi.hdmi_comp = dai->component; - - return 0; + snd_soc_component_set_jack(component, NULL, NULL); } static int card_late_probe(struct snd_soc_card *card) { - struct card_private *ctx = snd_soc_card_get_drvdata(card); - - 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, - DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); -SND_SOC_DAILINK_DEF(ssp0_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00", DIALOG_CODEC_DAI))); - -SND_SOC_DAILINK_DEF(ssp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); - -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"))); -SND_SOC_DAILINK_DEF(dmic_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); - -SND_SOC_DAILINK_DEF(dmic16k_pin, - DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin"))); - -SND_SOC_DAILINK_DEF(idisp1_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); -SND_SOC_DAILINK_DEF(idisp1_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); - -SND_SOC_DAILINK_DEF(idisp2_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); -SND_SOC_DAILINK_DEF(idisp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi2"))); - -SND_SOC_DAILINK_DEF(idisp3_pin, - DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); -SND_SOC_DAILINK_DEF(idisp3_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); - -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 jsl_dais[] = { - /* Back End DAI links */ - { - .name = "SSP1-Codec", - .id = 0, - .ignore_pmdown_time = 1, - .no_pcm = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, /* IV feedback */ - SND_SOC_DAILINK_REG(ssp1_pin, max_98373_components, platform), - }, - { - .name = "SSP0-Codec", - .id = 1, - .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 = 2, - .ignore_suspend = 1, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic_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 = "dmic16k", - .id = 6, - .ignore_suspend = 1, - .dpcm_capture = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic16k_pin, dmic_codec, platform), + struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); + struct snd_soc_dapm_context *dapm = &card->dapm; + int err; + + 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"); + err = snd_soc_dapm_sync(dapm); + if (err < 0) + return err; } -}; -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), - }, -}; + return sof_intel_board_card_late_probe(card); +} static struct snd_soc_card card_da7219 = { .name = "da7219", /* the sof- prefix is added by the core */ @@ -444,82 +209,208 @@ static struct snd_soc_card card_da7219 = { .late_probe = card_late_probe, }; +static struct snd_soc_dai_link_component da7219_component[] = { + { + .name = "i2c-DLGS7219:00", + .dai_name = DIALOG_CODEC_DAI, + } +}; + +static int +sof_card_dai_links_create(struct device *dev, struct snd_soc_card *card, + struct sof_card_private *ctx) +{ + int ret; + + ret = sof_intel_board_set_dai_link(dev, card, ctx); + if (ret) + return ret; + + if (!ctx->codec_link) { + dev_err(dev, "codec link not available"); + return -EINVAL; + } + + /* codec-specific fields for headphone codec */ + ctx->codec_link->codecs = da7219_component; + ctx->codec_link->num_codecs = ARRAY_SIZE(da7219_component); + ctx->codec_link->init = da7219_codec_init; + ctx->codec_link->exit = da7219_codec_exit; + + if (ctx->amp_type == CODEC_NONE) + return 0; + + if (!ctx->amp_link) { + dev_err(dev, "amp link not available"); + return -EINVAL; + } + + /* codec-specific fields for speaker amplifier */ + switch (ctx->amp_type) { + case CODEC_MAX98357A: + max_98357a_dai_link(ctx->amp_link); + break; + case CODEC_MAX98360A: + max_98360a_dai_link(ctx->amp_link); + break; + case CODEC_MAX98373: + max_98373_dai_link(dev, ctx->amp_link); + break; + case CODEC_MAX98390: + max_98390_dai_link(dev, ctx->amp_link); + break; + default: + dev_err(dev, "invalid amp type %d\n", ctx->amp_type); + return -EINVAL; + } + + return 0; +} + +#define GLK_LINK_ORDER SOF_LINK_ORDER(SOF_LINK_AMP, \ + SOF_LINK_CODEC, \ + SOF_LINK_DMIC01, \ + SOF_LINK_IDISP_HDMI, \ + SOF_LINK_NONE, \ + SOF_LINK_NONE, \ + SOF_LINK_NONE) + +#define CML_LINK_ORDER SOF_LINK_ORDER(SOF_LINK_AMP, \ + SOF_LINK_CODEC, \ + SOF_LINK_DMIC01, \ + SOF_LINK_IDISP_HDMI, \ + SOF_LINK_DMIC16K, \ + SOF_LINK_NONE, \ + SOF_LINK_NONE) + +#define JSL_LINK_ORDER SOF_LINK_ORDER(SOF_LINK_AMP, \ + SOF_LINK_CODEC, \ + SOF_LINK_DMIC01, \ + SOF_LINK_IDISP_HDMI, \ + SOF_LINK_DMIC16K, \ + SOF_LINK_NONE, \ + SOF_LINK_NONE) + static int audio_probe(struct platform_device *pdev) { struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; - struct snd_soc_dai_link *dai_links; - struct card_private *ctx; + struct sof_card_private *ctx; + char *card_name; unsigned long board_quirk = 0; - int ret, amp_idx; - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + int ret; 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); + dev_dbg(&pdev->dev, "board_quirk = %lx\n", board_quirk); + + /* initialize ctx with board quirk */ + ctx = sof_intel_board_get_ctx(&pdev->dev, board_quirk); + if (!ctx) + return -ENOMEM; if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) ctx->hdmi.idisp_codec = true; - if (board_quirk & SOF_DA7219_JSL_BOARD) { + if (board_quirk & SOF_DA7219_GLK_BOARD) { + /* dmic16k not support */ + ctx->dmic_be_num = 1; + + /* overwrite the DAI link order for GLK boards */ + ctx->link_order_overwrite = GLK_LINK_ORDER; + /* backward-compatible with existing devices */ switch (ctx->amp_type) { - case CODEC_MAX98360A: - card_da7219.name = devm_kstrdup(&pdev->dev, - "da7219max98360a", - GFP_KERNEL); + case CODEC_MAX98357A: + card_name = devm_kstrdup(&pdev->dev, "glkda7219max", + GFP_KERNEL); + if (!card_name) + return -ENOMEM; + + card_da7219.name = card_name; break; - case CODEC_MAX98373: - card_da7219.name = devm_kstrdup(&pdev->dev, "da7219max", - GFP_KERNEL); + default: + break; + } + } else if (board_quirk & SOF_DA7219_CML_BOARD) { + /* overwrite the DAI link order for CML boards */ + ctx->link_order_overwrite = CML_LINK_ORDER; + + /* backward-compatible with existing devices */ + switch (ctx->amp_type) { + case CODEC_MAX98357A: + card_name = devm_kstrdup(&pdev->dev, "cmlda7219max", + GFP_KERNEL); + if (!card_name) + return -ENOMEM; + + card_da7219.name = card_name; + break; + case CODEC_MAX98390: + card_name = devm_kstrdup(&pdev->dev, + "cml_max98390_da7219", + GFP_KERNEL); + if (!card_name) + return -ENOMEM; + + card_da7219.name = card_name; break; default: break; } + } else if (board_quirk & SOF_DA7219_JSL_BOARD) { + /* overwrite the DAI link order for JSL boards */ + ctx->link_order_overwrite = JSL_LINK_ORDER; - dai_links = jsl_dais; - amp_idx = 0; + /* backward-compatible with existing devices */ + switch (ctx->amp_type) { + case CODEC_MAX98360A: + card_name = devm_kstrdup(&pdev->dev, "da7219max98360a", + GFP_KERNEL); + if (!card_name) + return -ENOMEM; - card_da7219.num_links = ARRAY_SIZE(jsl_dais); - } else { - dai_links = adl_dais; - amp_idx = 7; + card_da7219.name = card_name; + break; + case CODEC_MAX98373: + card_name = devm_kstrdup(&pdev->dev, "da7219max", + GFP_KERNEL); + if (!card_name) + return -ENOMEM; - card_da7219.num_links = ARRAY_SIZE(adl_dais); + card_da7219.name = card_name; + break; + default: + break; + } } - dev_dbg(&pdev->dev, "board_quirk = %lx\n", board_quirk); + if (board_quirk & SOF_DA7219_MCLK_EN) + ctx->da7219.mclk_en = true; - /* speaker amp */ + /* update dai_link */ + ret = sof_card_dai_links_create(&pdev->dev, &card_da7219, ctx); + if (ret) + return ret; + + /* update codec_conf */ 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; + case CODEC_MAX98390: + max_98390_set_codec_conf(&pdev->dev, &card_da7219); + break; + case CODEC_MAX98357A: + case CODEC_MAX98360A: + case CODEC_NONE: + /* no codec conf required */ + break; default: dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type); return -EINVAL; } - card_da7219.dai_link = dai_links; - card_da7219.dev = &pdev->dev; ret = snd_soc_fixup_dai_links_platform_name(&card_da7219, @@ -534,16 +425,48 @@ static int audio_probe(struct platform_device *pdev) static const struct platform_device_id board_ids[] = { { - .name = "jsl_mx98373_da7219", - .driver_data = (kernel_ulong_t)(SOF_DA7219_JSL_BOARD), + .name = "glk_da7219_def", + .driver_data = (kernel_ulong_t)(SOF_DA7219_GLK_BOARD | + SOF_SSP_PORT_CODEC(2) | + SOF_SSP_PORT_AMP(1)), + }, + { + .name = "cml_da7219_def", + .driver_data = (kernel_ulong_t)(SOF_DA7219_CML_BOARD | + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1)), + }, + { + .name = "jsl_da7219_def", + .driver_data = (kernel_ulong_t)(SOF_DA7219_JSL_BOARD | + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1)), + }, + { + .name = "adl_da7219_def", + .driver_data = (kernel_ulong_t)(SOF_DA7219_MCLK_EN | + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1) | + SOF_NUM_IDISP_HDMI(4) | + SOF_SSP_PORT_BT_OFFLOAD(2) | + SOF_BT_OFFLOAD_PRESENT), }, { - .name = "jsl_mx98360_da7219", - .driver_data = (kernel_ulong_t)(SOF_DA7219_JSL_BOARD), + .name = "rpl_da7219_def", + .driver_data = (kernel_ulong_t)(SOF_DA7219_MCLK_EN | + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1) | + SOF_NUM_IDISP_HDMI(4) | + SOF_SSP_PORT_BT_OFFLOAD(2) | + SOF_BT_OFFLOAD_PRESENT), }, { - .name = "adl_mx98360_da7219", - /* no quirk needed for this board */ + .name = "mtl_da7219_def", + .driver_data = (kernel_ulong_t)(SOF_DA7219_MCLK_EN | + SOF_SSP_PORT_CODEC(2) | + SOF_SSP_PORT_AMP(0) | + SOF_SSP_PORT_BT_OFFLOAD(1) | + SOF_BT_OFFLOAD_PRESENT), }, { } }; @@ -564,6 +487,5 @@ 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); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_BOARD_HELPERS"); +MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_MAXIM_COMMON"); diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c index c1fcc156a575..a0b3679b17b4 100644 --- a/sound/soc/intel/boards/sof_es8336.c +++ b/sound/soc/intel/boards/sof_es8336.c @@ -371,7 +371,7 @@ static int sof_es8336_hw_params(struct snd_pcm_substream *substream, } /* machine stream operations */ -static struct snd_soc_ops sof_es8336_ops = { +static const struct snd_soc_ops sof_es8336_ops = { .hw_params = sof_es8336_hw_params, .trigger = sof_8336_trigger, }; @@ -455,8 +455,6 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].exit = sof_es8316_exit; links[id].ops = &sof_es8336_ops; links[id].nonatomic = true; - links[id].dpcm_playback = 1; - links[id].dpcm_capture = 1; links[id].no_pcm = 1; links[id].cpus = &cpus[id]; links[id].num_cpus = 1; @@ -496,7 +494,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, 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].capture_only = 1; links[id].no_pcm = 1; id++; @@ -539,7 +537,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, 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].playback_only = 1; links[id].no_pcm = 1; id++; @@ -569,7 +567,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].dpcm_capture = 1; + links[id].capture_only = 1; links[id].no_pcm = 1; links[id].num_cpus = 1; id++; @@ -681,7 +679,7 @@ static int sof_es8336_probe(struct platform_device *pdev) dai_links[0].codecs->dai_name = "ES8326 HiFi"; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); - return -ENXIO; + return -ENOENT; } codec_dev = acpi_get_first_physical_node(adev); @@ -818,6 +816,16 @@ static const struct platform_device_id board_ids[] = { SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK | SOF_ES8336_JD_INVERTED), }, + { + .name = "arl_es83x6_c1_h02", + .driver_data = (kernel_ulong_t)(SOF_ES8336_SSP_CODEC(1) | + 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_ES8336_SPEAKERS_EN_GPIO1_QUIRK | + SOF_ES8336_JD_INVERTED), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); @@ -828,11 +836,11 @@ static struct platform_driver sof_es8336_driver = { .pm = &snd_soc_pm_ops, }, .probe = sof_es8336_probe, - .remove_new = sof_es8336_remove, + .remove = sof_es8336_remove, .id_table = board_ids, }; module_platform_driver(sof_es8336_driver); MODULE_DESCRIPTION("ASoC Intel(R) SOF + ES8336 Machine driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON"); diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c index cf2974718271..c98a67ae5e66 100644 --- a/sound/soc/intel/boards/sof_maxim_common.c +++ b/sound/soc/intel/boards/sof_maxim_common.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only // -// Copyright(c) 2020 Intel Corporation. All rights reserved. +// Copyright(c) 2020 Intel Corporation #include <linux/module.h> #include <linux/string.h> #include <sound/pcm.h> @@ -9,9 +9,25 @@ #include <sound/soc-acpi.h> #include <sound/soc-dai.h> #include <sound/soc-dapm.h> +#include <sound/sof.h> #include <uapi/sound/asound.h> +#include "../common/soc-intel-quirks.h" #include "sof_maxim_common.h" +/* + * Common structures and functions + */ +static const struct snd_kcontrol_new maxim_2spk_kcontrols[] = { + SOC_DAPM_PIN_SWITCH("Left Spk"), + SOC_DAPM_PIN_SWITCH("Right Spk"), + +}; + +static const struct snd_soc_dapm_widget maxim_2spk_widgets[] = { + SND_SOC_DAPM_SPK("Left Spk", NULL), + SND_SOC_DAPM_SPK("Right Spk", NULL), +}; + /* helper function to get the number of specific codec */ static unsigned int get_num_codecs(const char *hid) { @@ -24,14 +40,16 @@ static unsigned int get_num_codecs(const char *hid) return dev_num; } +/* + * Maxim MAX98373 + */ #define MAX_98373_PIN_NAME 16 -const struct snd_soc_dapm_route max_98373_dapm_routes[] = { +static const struct snd_soc_dapm_route max_98373_dapm_routes[] = { /* speaker */ { "Left Spk", NULL, "Left BE_OUT" }, { "Right Spk", NULL, "Right BE_OUT" }, }; -EXPORT_SYMBOL_NS(max_98373_dapm_routes, SND_SOC_INTEL_SOF_MAXIM_COMMON); static struct snd_soc_codec_conf max_98373_codec_conf[] = { { @@ -44,7 +62,7 @@ static struct snd_soc_codec_conf max_98373_codec_conf[] = { }, }; -struct snd_soc_dai_link_component max_98373_components[] = { +static struct snd_soc_dai_link_component max_98373_components[] = { { /* For Right */ .name = MAX_98373_DEV0_NAME, .dai_name = MAX_98373_CODEC_DAI, @@ -54,34 +72,122 @@ struct snd_soc_dai_link_component max_98373_components[] = { .dai_name = MAX_98373_CODEC_DAI, }, }; -EXPORT_SYMBOL_NS(max_98373_components, SND_SOC_INTEL_SOF_MAXIM_COMMON); + +/* + * According to the definition of 'DAI Sel Mux' mixer in max98373.c, rx mask + * should choose two channels from TDM slots, the LSB of rx mask is left channel + * and the other one is right channel. + */ +static const struct { + unsigned int rx; +} max_98373_tdm_mask[] = { + {.rx = 0x3}, + {.rx = 0x3}, +}; + +/* + * The tx mask indicates which channel(s) contains output IV-sense data and + * others should set to Hi-Z. Here we get the channel number from codec's ACPI + * device property "maxim,vmon-slot-no" and "maxim,imon-slot-no" to generate the + * mask. Refer to the max98373_slot_config() function in max98373.c codec driver. + */ +static unsigned int max_98373_get_tx_mask(struct device *dev) +{ + int vmon_slot; + int imon_slot; + + if (device_property_read_u32(dev, "maxim,vmon-slot-no", &vmon_slot)) + vmon_slot = 0; + + if (device_property_read_u32(dev, "maxim,imon-slot-no", &imon_slot)) + imon_slot = 1; + + dev_dbg(dev, "vmon_slot %d imon_slot %d\n", vmon_slot, imon_slot); + + return (0x1 << vmon_slot) | (0x1 << imon_slot); +} static int max_98373_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { 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; + int tdm_slots; + unsigned int tx_mask; + unsigned int tx_mask_used = 0x0; int ret = 0; - int j; - for_each_rtd_codec_dais(rtd, j, codec_dai) { - if (!strcmp(codec_dai->component->name, MAX_98373_DEV0_NAME)) { - /* DEV0 tdm slot configuration */ - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x03, 3, 8, 32); - } else if (!strcmp(codec_dai->component->name, MAX_98373_DEV1_NAME)) { - /* DEV1 tdm slot configuration */ - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0C, 3, 8, 32); + for_each_rtd_codec_dais(rtd, i, codec_dai) { + if (i >= ARRAY_SIZE(max_98373_tdm_mask)) { + dev_err(codec_dai->dev, "only 2 amps are supported\n"); + return -EINVAL; } - if (ret < 0) { - dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", - ret); - return ret; + + switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + /* get the tplg configured tdm slot number */ + tdm_slots = sof_dai_get_tdm_slots(rtd); + if (tdm_slots <= 0) { + dev_err(rtd->dev, "invalid tdm slots %d\n", + tdm_slots); + return -EINVAL; + } + + /* get the tx mask from ACPI device properties */ + tx_mask = max_98373_get_tx_mask(codec_dai->dev); + if (!tx_mask) + return -EINVAL; + + if (tx_mask & tx_mask_used) { + dev_err(codec_dai->dev, "invalid tx mask 0x%x, used 0x%x\n", + tx_mask, tx_mask_used); + return -EINVAL; + } + + tx_mask_used |= tx_mask; + + /* + * check if tdm slot number is too small for channel + * allocation + */ + if (fls(tx_mask) > tdm_slots) { + dev_err(codec_dai->dev, "slot mismatch, tx %d slots %d\n", + fls(tx_mask), tdm_slots); + return -EINVAL; + } + + if (fls(max_98373_tdm_mask[i].rx) > tdm_slots) { + dev_err(codec_dai->dev, "slot mismatch, rx %d slots %d\n", + fls(max_98373_tdm_mask[i].rx), tdm_slots); + return -EINVAL; + } + + dev_dbg(codec_dai->dev, "set tdm slot: tx 0x%x rx 0x%x slots %d width %d\n", + tx_mask, max_98373_tdm_mask[i].rx, + tdm_slots, params_width(params)); + + ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_mask, + max_98373_tdm_mask[i].rx, + tdm_slots, + params_width(params)); + if (ret < 0) { + dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", + ret); + return ret; + } + break; + default: + dev_dbg(codec_dai->dev, "codec is in I2S mode\n"); + break; } } return 0; } -int max_98373_trigger(struct snd_pcm_substream *substream, int cmd) +static int max_98373_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; @@ -124,33 +230,67 @@ int max_98373_trigger(struct snd_pcm_substream *substream, int cmd) return ret; } -EXPORT_SYMBOL_NS(max_98373_trigger, SND_SOC_INTEL_SOF_MAXIM_COMMON); -struct snd_soc_ops max_98373_ops = { +static const struct snd_soc_ops max_98373_ops = { .hw_params = max_98373_hw_params, .trigger = max_98373_trigger, }; -EXPORT_SYMBOL_NS(max_98373_ops, SND_SOC_INTEL_SOF_MAXIM_COMMON); -int max_98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd) +static int max_98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + unsigned int num_codecs = get_num_codecs(MAX_98373_ACPI_HID); int ret; - ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes, - ARRAY_SIZE(max_98373_dapm_routes)); - if (ret) - dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); + switch (num_codecs) { + case 2: + ret = snd_soc_dapm_new_controls(&card->dapm, maxim_2spk_widgets, + ARRAY_SIZE(maxim_2spk_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add max98373 widgets, ret %d\n", + ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, maxim_2spk_kcontrols, + ARRAY_SIZE(maxim_2spk_kcontrols)); + if (ret) { + dev_err(rtd->dev, "fail to add max98373 kcontrols, ret %d\n", + ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes, + ARRAY_SIZE(max_98373_dapm_routes)); + if (ret) { + dev_err(rtd->dev, "fail to add max98373 routes, ret %d\n", + ret); + return ret; + } + break; + default: + dev_err(rtd->dev, "max98373: invalid num_codecs %d\n", num_codecs); + return -EINVAL; + } + return ret; } -EXPORT_SYMBOL_NS(max_98373_spk_codec_init, SND_SOC_INTEL_SOF_MAXIM_COMMON); + +void max_98373_dai_link(struct device *dev, struct snd_soc_dai_link *link) +{ + link->codecs = max_98373_components; + link->num_codecs = ARRAY_SIZE(max_98373_components); + link->init = max_98373_spk_codec_init; + link->ops = &max_98373_ops; +} +EXPORT_SYMBOL_NS(max_98373_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); void max_98373_set_codec_conf(struct snd_soc_card *card) { card->codec_conf = max_98373_codec_conf; card->num_configs = ARRAY_SIZE(max_98373_codec_conf); } -EXPORT_SYMBOL_NS(max_98373_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON); +EXPORT_SYMBOL_NS(max_98373_set_codec_conf, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); /* * Maxim MAX98390 @@ -177,6 +317,17 @@ static const struct snd_soc_dapm_route max_98390_tt_dapm_routes[] = { { "TR Spk", NULL, "Tweeter Right BE_OUT" }, }; +static struct snd_soc_codec_conf max_98390_cml_codec_conf[] = { + { + .dlc = COMP_CODEC_CONF(MAX_98390_DEV0_NAME), + .name_prefix = "Left", + }, + { + .dlc = COMP_CODEC_CONF(MAX_98390_DEV1_NAME), + .name_prefix = "Right", + }, +}; + static struct snd_soc_codec_conf max_98390_codec_conf[] = { { .dlc = COMP_CODEC_CONF(MAX_98390_DEV0_NAME), @@ -229,6 +380,7 @@ static int max_98390_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { 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, ret; @@ -238,13 +390,24 @@ static int max_98390_hw_params(struct snd_pcm_substream *substream, return -ENODEV; } - ret = snd_soc_dai_set_tdm_slot(codec_dai, max_98390_tdm_mask[i].tx, - max_98390_tdm_mask[i].rx, 4, - params_width(params)); - if (ret < 0) { - dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", - ret); - return ret; + switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + /* 4-slot TDM */ + ret = snd_soc_dai_set_tdm_slot(codec_dai, + max_98390_tdm_mask[i].tx, + max_98390_tdm_mask[i].rx, + 4, + params_width(params)); + if (ret < 0) { + dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", + ret); + return ret; + } + break; + default: + dev_dbg(codec_dai->dev, "codec is in I2S mode\n"); + break; } } return 0; @@ -287,6 +450,22 @@ static int max_98390_init(struct snd_soc_pcm_runtime *rtd) fallthrough; case 2: /* add regular speakers dapm route */ + ret = snd_soc_dapm_new_controls(&card->dapm, maxim_2spk_widgets, + ARRAY_SIZE(maxim_2spk_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add max98390 woofer widgets, ret %d\n", + ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, maxim_2spk_kcontrols, + ARRAY_SIZE(maxim_2spk_kcontrols)); + if (ret) { + dev_err(rtd->dev, "fail to add max98390 woofer kcontrols, ret %d\n", + ret); + return ret; + } + ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_dapm_routes, ARRAY_SIZE(max_98390_dapm_routes)); if (ret) { @@ -327,7 +506,7 @@ void max_98390_dai_link(struct device *dev, struct snd_soc_dai_link *link) link->init = max_98390_init; link->ops = &max_98390_ops; } -EXPORT_SYMBOL_NS(max_98390_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); +EXPORT_SYMBOL_NS(max_98390_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card) { @@ -337,6 +516,10 @@ void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card) switch (num_codecs) { case 2: + if (soc_intel_is_cml()) + card->codec_conf = max_98390_cml_codec_conf; + + fallthrough; case 4: card->num_configs = num_codecs; break; @@ -346,7 +529,7 @@ void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card) break; } } -EXPORT_SYMBOL_NS(max_98390_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON); +EXPORT_SYMBOL_NS(max_98390_set_codec_conf, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); /* * Maxim MAX98357A/MAX98360A @@ -413,7 +596,7 @@ void max_98357a_dai_link(struct snd_soc_dai_link *link) link->num_codecs = ARRAY_SIZE(max_98357a_components); link->init = max_98357a_init; } -EXPORT_SYMBOL_NS(max_98357a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); +EXPORT_SYMBOL_NS(max_98357a_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); void max_98360a_dai_link(struct snd_soc_dai_link *link) { @@ -421,7 +604,7 @@ void max_98360a_dai_link(struct snd_soc_dai_link *link) link->num_codecs = ARRAY_SIZE(max_98360a_components); link->init = max_98357a_init; } -EXPORT_SYMBOL_NS(max_98360a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); +EXPORT_SYMBOL_NS(max_98360a_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); MODULE_DESCRIPTION("ASoC Intel SOF Maxim helpers"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/boards/sof_maxim_common.h b/sound/soc/intel/boards/sof_maxim_common.h index fe0212fbad8e..3d34c7dae6f5 100644 --- a/sound/soc/intel/boards/sof_maxim_common.h +++ b/sound/soc/intel/boards/sof_maxim_common.h @@ -11,7 +11,7 @@ #define __SOF_MAXIM_COMMON_H #include <sound/soc.h> -#include "sof_ssp_common.h" +#include <sound/soc-acpi-intel-ssp-common.h> /* * Maxim MAX98373 @@ -20,13 +20,8 @@ #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; -extern const struct snd_soc_dapm_route max_98373_dapm_routes[]; - -int max_98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd); +void max_98373_dai_link(struct device *dev, struct snd_soc_dai_link *link); void max_98373_set_codec_conf(struct snd_soc_card *card); -int max_98373_trigger(struct snd_pcm_substream *substream, int cmd); /* * Maxim MAX98390 diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index 719c2fbaf515..72ce32e2cd57 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -24,27 +24,8 @@ #include "sof_realtek_common.h" #include "sof_maxim_common.h" #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_NAU8825_SSP_AMP_SHIFT 4 -#define SOF_NAU8825_SSP_AMP_MASK (GENMASK(6, 4)) -#define SOF_NAU8825_SSP_AMP(quirk) \ - (((quirk) << SOF_NAU8825_SSP_AMP_SHIFT) & SOF_NAU8825_SSP_AMP_MASK) -#define SOF_NAU8825_NUM_HDMIDEV_SHIFT 7 -#define SOF_NAU8825_NUM_HDMIDEV_MASK (GENMASK(9, 7)) -#define SOF_NAU8825_NUM_HDMIDEV(quirk) \ - (((quirk) << SOF_NAU8825_NUM_HDMIDEV_SHIFT) & SOF_NAU8825_NUM_HDMIDEV_MASK) - -/* BT audio offload: reserve 3 bits for future */ -#define SOF_BT_OFFLOAD_SSP_SHIFT 10 -#define SOF_BT_OFFLOAD_SSP_MASK (GENMASK(12, 10)) -#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) - -static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0); + +static unsigned long sof_nau8825_quirk = SOF_SSP_PORT_CODEC(0); static struct snd_soc_jack_pin jack_pins[] = { { @@ -134,7 +115,7 @@ static int sof_nau8825_hw_params(struct snd_pcm_substream *substream, return ret; } -static struct snd_soc_ops sof_nau8825_ops = { +static const struct snd_soc_ops sof_nau8825_ops = { .hw_params = sof_nau8825_hw_params, }; @@ -159,15 +140,11 @@ static int sof_card_late_probe(struct snd_soc_card *card) static const struct snd_kcontrol_new sof_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Left Spk"), - SOC_DAPM_PIN_SWITCH("Right Spk"), }; static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("Left Spk", NULL), - SND_SOC_DAPM_SPK("Right Spk", NULL), }; static const struct snd_soc_dapm_route sof_map[] = { @@ -236,10 +213,7 @@ sof_card_dai_links_create(struct device *dev, struct snd_soc_card *card, max_98360a_dai_link(ctx->amp_link); break; case CODEC_MAX98373: - ctx->amp_link->codecs = max_98373_components; - ctx->amp_link->num_codecs = ARRAY_SIZE(max_98373_components); - ctx->amp_link->init = max_98373_spk_codec_init; - ctx->amp_link->ops = &max_98373_ops; + max_98373_dai_link(dev, ctx->amp_link); break; case CODEC_NAU8318: nau8318_set_dai_link(ctx->amp_link); @@ -264,41 +238,19 @@ static int sof_audio_probe(struct platform_device *pdev) struct sof_card_private *ctx; int ret; - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - if (pdev->id_entry && pdev->id_entry->driver_data) sof_nau8825_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); - dev_dbg(&pdev->dev, "sof_nau8825_quirk = %lx\n", sof_nau8825_quirk); - /* default number of DMIC DAI's */ - 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 (!ctx->hdmi_num) - ctx->hdmi_num = 3; + /* initialize ctx with board quirk */ + ctx = sof_intel_board_get_ctx(&pdev->dev, sof_nau8825_quirk); + if (!ctx) + return -ENOMEM; if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) ctx->hdmi.idisp_codec = true; - /* port number of peripherals attached to ssp interface */ - ctx->ssp_bt = (sof_nau8825_quirk & SOF_BT_OFFLOAD_SSP_MASK) >> - SOF_BT_OFFLOAD_SSP_SHIFT; - - ctx->ssp_amp = (sof_nau8825_quirk & SOF_NAU8825_SSP_AMP_MASK) >> - SOF_NAU8825_SSP_AMP_SHIFT; - - ctx->ssp_codec = sof_nau8825_quirk & SOF_NAU8825_SSP_CODEC_MASK; - - if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) - ctx->bt_offload_present = true; - /* update dai_link */ ret = sof_card_dai_links_create(&pdev->dev, &sof_audio_card_nau8825, ctx); if (ret) @@ -312,10 +264,10 @@ static int sof_audio_probe(struct platform_device *pdev) case CODEC_RT1015P: sof_rt1015p_codec_conf(&sof_audio_card_nau8825); break; - case CODEC_NONE: case CODEC_MAX98360A: case CODEC_NAU8318: case CODEC_RT1019P: + case CODEC_NONE: /* no codec conf required */ break; default: @@ -339,34 +291,33 @@ static int sof_audio_probe(struct platform_device *pdev) static const struct platform_device_id board_ids[] = { { - .name = "sof_nau8825", - .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_NAU8825_NUM_HDMIDEV(4) | - SOF_BT_OFFLOAD_SSP(2) | - SOF_SSP_BT_OFFLOAD_PRESENT), - - }, - { .name = "adl_rt1019p_8825", - .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_NAU8825_SSP_AMP(2) | - SOF_NAU8825_NUM_HDMIDEV(4)), + .driver_data = (kernel_ulong_t)(SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(2) | + SOF_NUM_IDISP_HDMI(4)), }, { .name = "adl_nau8825_def", - .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) | - SOF_SSP_BT_OFFLOAD_PRESENT), + .driver_data = (kernel_ulong_t)(SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1) | + SOF_NUM_IDISP_HDMI(4) | + SOF_SSP_PORT_BT_OFFLOAD(2) | + SOF_BT_OFFLOAD_PRESENT), }, { .name = "rpl_nau8825_def", - .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) | - SOF_SSP_BT_OFFLOAD_PRESENT), + .driver_data = (kernel_ulong_t)(SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1) | + SOF_NUM_IDISP_HDMI(4) | + SOF_SSP_PORT_BT_OFFLOAD(2) | + SOF_BT_OFFLOAD_PRESENT), + }, + { + .name = "mtl_nau8825_def", + .driver_data = (kernel_ulong_t)(SOF_SSP_PORT_CODEC(2) | + SOF_SSP_PORT_AMP(0) | + SOF_SSP_PORT_BT_OFFLOAD(1) | + SOF_BT_OFFLOAD_PRESENT), }, { } }; @@ -388,8 +339,7 @@ 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_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); +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"); diff --git a/sound/soc/intel/boards/sof_nuvoton_common.c b/sound/soc/intel/boards/sof_nuvoton_common.c index 549a412f5d53..ed41cb6f7fa5 100644 --- a/sound/soc/intel/boards/sof_nuvoton_common.c +++ b/sound/soc/intel/boards/sof_nuvoton_common.c @@ -67,7 +67,7 @@ void nau8318_set_dai_link(struct snd_soc_dai_link *link) link->num_codecs = ARRAY_SIZE(nau8318_components); link->init = nau8318_init; } -EXPORT_SYMBOL_NS(nau8318_set_dai_link, SND_SOC_INTEL_SOF_NUVOTON_COMMON); +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 index 53a84f9a67c0..8a0f283260e7 100644 --- a/sound/soc/intel/boards/sof_nuvoton_common.h +++ b/sound/soc/intel/boards/sof_nuvoton_common.h @@ -9,7 +9,7 @@ #define __SOF_NUVOTON_COMMON_H #include <sound/soc.h> -#include "sof_ssp_common.h" +#include <sound/soc-acpi-intel-ssp-common.h> /* * Nuvoton NAU8318 diff --git a/sound/soc/intel/boards/sof_pcm512x.c b/sound/soc/intel/boards/sof_pcm512x.c index b01cb2329542..2f43710c1bae 100644 --- a/sound/soc/intel/boards/sof_pcm512x.c +++ b/sound/soc/intel/boards/sof_pcm512x.c @@ -246,12 +246,11 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].init = sof_pcm512x_codec_init; links[id].ops = &sof_pcm512x_ops; - links[id].dpcm_playback = 1; /* * capture only supported with specific versions of the Hifiberry DAC+ */ - if (sof_pcm512x_quirk & SOF_PCM512X_ENABLE_SSP_CAPTURE) - links[id].dpcm_capture = 1; + if (!(sof_pcm512x_quirk & SOF_PCM512X_ENABLE_SSP_CAPTURE)) + links[id].playback_only = 1; links[id].no_pcm = 1; links[id].cpus = &cpus[id]; links[id].num_cpus = 1; @@ -294,7 +293,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, 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].capture_only = 1; links[id].no_pcm = 1; id++; } @@ -341,7 +340,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, 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].playback_only = 1; links[id].no_pcm = 1; id++; } @@ -371,8 +370,7 @@ static int sof_audio_probe(struct platform_device *pdev) sof_pcm512x_quirk = SOF_PCM512X_SSP_CODEC(2); } else { dmic_be_num = 2; - if (mach->mach_params.common_hdmi_codec_drv && - (mach->mach_params.codec_mask & IDISP_CODEC_MASK)) + if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) ctx->idisp_codec = true; /* links are always present in topology */ @@ -430,7 +428,7 @@ static void sof_pcm512x_remove(struct platform_device *pdev) static struct platform_driver sof_audio = { .probe = sof_audio_probe, - .remove_new = sof_pcm512x_remove, + .remove = sof_pcm512x_remove, .driver = { .name = "sof_pcm512x", .pm = &snd_soc_pm_ops, @@ -442,4 +440,4 @@ MODULE_DESCRIPTION("ASoC Intel(R) SOF + PCM512x Machine driver"); MODULE_AUTHOR("Pierre-Louis Bossart"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:sof_pcm512x"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON"); diff --git a/sound/soc/intel/boards/sof_realtek_common.c b/sound/soc/intel/boards/sof_realtek_common.c index 80c8687cd1da..600707d403b9 100644 --- a/sound/soc/intel/boards/sof_realtek_common.c +++ b/sound/soc/intel/boards/sof_realtek_common.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only // -// Copyright(c) 2020 Intel Corporation. All rights reserved. +// Copyright(c) 2020 Intel Corporation #include <linux/device.h> #include <linux/kernel.h> @@ -15,10 +15,51 @@ #include "../../codecs/rt1011.h" #include "../../codecs/rt1015.h" #include "../../codecs/rt1308.h" +#include "../common/soc-intel-quirks.h" #include "sof_realtek_common.h" /* - * Current only 2-amp configuration is supported for rt1011 + * Common structures and functions + */ +static const struct snd_kcontrol_new realtek_2spk_kcontrols[] = { + SOC_DAPM_PIN_SWITCH("Left Spk"), + SOC_DAPM_PIN_SWITCH("Right Spk"), + +}; + +static const struct snd_soc_dapm_widget realtek_2spk_widgets[] = { + SND_SOC_DAPM_SPK("Left Spk", NULL), + SND_SOC_DAPM_SPK("Right Spk", NULL), +}; + +static const struct snd_kcontrol_new realtek_4spk_kcontrols[] = { + SOC_DAPM_PIN_SWITCH("WL Ext Spk"), + SOC_DAPM_PIN_SWITCH("WR Ext Spk"), + SOC_DAPM_PIN_SWITCH("TL Ext Spk"), + SOC_DAPM_PIN_SWITCH("TR Ext Spk"), +}; + +static const struct snd_soc_dapm_widget realtek_4spk_widgets[] = { + SND_SOC_DAPM_SPK("WL Ext Spk", NULL), + SND_SOC_DAPM_SPK("WR Ext Spk", NULL), + SND_SOC_DAPM_SPK("TL Ext Spk", NULL), + SND_SOC_DAPM_SPK("TR Ext Spk", NULL), +}; + +/* helper function to get the number of specific codec */ +static unsigned int get_num_codecs(const char *hid) +{ + struct acpi_device *adev; + unsigned int dev_num = 0; + + for_each_acpi_dev_match(adev, hid, NULL, -1) + dev_num++; + + return dev_num; +} + +/* + * Realtek ALC1011 */ static const struct snd_soc_dapm_route speaker_map_lr[] = { /* speaker */ @@ -26,16 +67,14 @@ static const struct snd_soc_dapm_route speaker_map_lr[] = { { "Right Spk", NULL, "Right SPO" }, }; -/* - * Make sure device's Unique ID follows this configuration: - * - * Two speakers: - * 0: left, 1: right - * Four speakers: - * 0: Woofer left, 1: Woofer right - * 2: Tweeter left, 3: Tweeter right - */ -static struct snd_soc_codec_conf rt1011_codec_confs[] = { +static const struct snd_soc_dapm_route rt1011_4spk_routes[] = { + {"WL Ext Spk", NULL, "WL SPO" }, + {"WR Ext Spk", NULL, "WR SPO" }, + {"TL Ext Spk", NULL, "TL SPO" }, + {"TR Ext Spk", NULL, "TR SPO" }, +}; + +static struct snd_soc_codec_conf rt1011_2spk_codec_confs[] = { { .dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME), .name_prefix = "Left", @@ -46,6 +85,25 @@ static struct snd_soc_codec_conf rt1011_codec_confs[] = { }, }; +static struct snd_soc_codec_conf rt1011_4spk_codec_confs[] = { + { + .dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME), + .name_prefix = "WL", + }, + { + .dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME), + .name_prefix = "WR", + }, + { + .dlc = COMP_CODEC_CONF(RT1011_DEV2_NAME), + .name_prefix = "TL", + }, + { + .dlc = COMP_CODEC_CONF(RT1011_DEV3_NAME), + .name_prefix = "TR", + }, +}; + static struct snd_soc_dai_link_component rt1011_dai_link_components[] = { { .name = RT1011_DEV0_NAME, @@ -55,6 +113,14 @@ static struct snd_soc_dai_link_component rt1011_dai_link_components[] = { .name = RT1011_DEV1_NAME, .dai_name = RT1011_CODEC_DAI, }, + { + .name = RT1011_DEV2_NAME, + .dai_name = RT1011_CODEC_DAI, + }, + { + .name = RT1011_DEV3_NAME, + .dai_name = RT1011_CODEC_DAI, + }, }; static const struct { @@ -63,6 +129,8 @@ static const struct { } rt1011_tdm_mask[] = { {.tx = 0x4, .rx = 0x1}, {.tx = 0x8, .rx = 0x2}, + {.tx = 0x1, .rx = 0x1}, + {.tx = 0x2, .rx = 0x2}, }; static int rt1011_hw_params(struct snd_pcm_substream *substream, @@ -118,30 +186,127 @@ static const struct snd_soc_ops rt1011_ops = { static int rt1011_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID); int ret; - ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr, - ARRAY_SIZE(speaker_map_lr)); - if (ret) - dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); + switch (num_codecs) { + case 2: + if (!soc_intel_is_cml()) { + ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets, + ARRAY_SIZE(realtek_2spk_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n", + ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols, + ARRAY_SIZE(realtek_2spk_kcontrols)); + if (ret) { + dev_err(rtd->dev, "fail to add rt1011 kcontrols, ret %d\n", + ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr, + ARRAY_SIZE(speaker_map_lr)); + if (ret) { + dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n", + ret); + return ret; + } + + break; + } + + /* + * register speaker widgets "WL Ext Spk" and "WR Ext Spk" to + * keep backward compatible with cml devices + */ + fallthrough; + case 4: + ret = snd_soc_dapm_new_controls(&card->dapm, realtek_4spk_widgets, + num_codecs); + if (ret) { + dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n", + ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, realtek_4spk_kcontrols, + num_codecs); + if (ret) { + dev_err(rtd->dev, "fail to add rt1011 controls, ret %d\n", + ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, rt1011_4spk_routes, + num_codecs); + if (ret) { + dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n", + ret); + return ret; + } + break; + default: + dev_err(rtd->dev, "rt1011: invalid num_codecs %d\n", num_codecs); + return -EINVAL; + } + return ret; } -void sof_rt1011_dai_link(struct snd_soc_dai_link *link) +void sof_rt1011_dai_link(struct device *dev, struct snd_soc_dai_link *link) { + unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID); + link->codecs = rt1011_dai_link_components; - link->num_codecs = ARRAY_SIZE(rt1011_dai_link_components); + + switch (num_codecs) { + case 2: + case 4: + link->num_codecs = num_codecs; + break; + default: + dev_err(dev, "rt1011: invalid num_codecs %d\n", num_codecs); + break; + } + link->init = rt1011_init; link->ops = &rt1011_ops; } -EXPORT_SYMBOL_NS(sof_rt1011_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1011_dai_link, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); -void sof_rt1011_codec_conf(struct snd_soc_card *card) +void sof_rt1011_codec_conf(struct device *dev, struct snd_soc_card *card) { - card->codec_conf = rt1011_codec_confs; - card->num_configs = ARRAY_SIZE(rt1011_codec_confs); + unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID); + + switch (num_codecs) { + case 2: + if (soc_intel_is_cml()) { + /* + * use name prefix 'WL' and 'WR' for speaker widgets to + * keep backward compatible with cml devices + */ + card->codec_conf = rt1011_4spk_codec_confs; + } else { + card->codec_conf = rt1011_2spk_codec_confs; + } + + card->num_configs = num_codecs; + break; + case 4: + card->codec_conf = rt1011_4spk_codec_confs; + card->num_configs = ARRAY_SIZE(rt1011_4spk_codec_confs); + break; + default: + dev_err(dev, "rt1011: invalid num_codecs %d\n", num_codecs); + break; + } + } -EXPORT_SYMBOL_NS(sof_rt1011_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1011_codec_conf, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); /* * rt1015: i2c mode driver for ALC1015 and ALC1015Q @@ -149,59 +314,21 @@ EXPORT_SYMBOL_NS(sof_rt1011_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); * * For stereo output, there are always two amplifiers on the board. * However, the ACPI implements only one device instance (UID=0) if they - * are sharing the same enable pin. The code will detect the number of - * device instance and use corresponding DAPM structures for - * initialization. + * are sharing the same enable pin. This is the case of rt1015p. */ -static const struct snd_soc_dapm_route rt1015p_1dev_dapm_routes[] = { +static const struct snd_soc_dapm_route rt1015p_dapm_routes[] = { /* speaker */ { "Left Spk", NULL, "Speaker" }, { "Right Spk", NULL, "Speaker" }, }; -static const struct snd_soc_dapm_route rt1015p_2dev_dapm_routes[] = { - /* speaker */ - { "Left Spk", NULL, "Left Speaker" }, - { "Right Spk", NULL, "Right Speaker" }, -}; - -static struct snd_soc_codec_conf rt1015p_codec_confs[] = { - { - .dlc = COMP_CODEC_CONF(RT1015P_DEV0_NAME), - .name_prefix = "Left", - }, - { - .dlc = COMP_CODEC_CONF(RT1015P_DEV1_NAME), - .name_prefix = "Right", - }, -}; - static struct snd_soc_dai_link_component rt1015p_dai_link_components[] = { { .name = RT1015P_DEV0_NAME, .dai_name = RT1015P_CODEC_DAI, }, - { - .name = RT1015P_DEV1_NAME, - .dai_name = RT1015P_CODEC_DAI, - }, }; -static int rt1015p_get_num_codecs(void) -{ - static int dev_num; - - if (dev_num) - return dev_num; - - if (!acpi_dev_present("RTL1015", "1", -1)) - dev_num = 1; - else - dev_num = 2; - - return dev_num; -} - static int rt1015p_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -219,12 +346,22 @@ static int rt1015p_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_card *card = rtd->card; int ret; - if (rt1015p_get_num_codecs() == 1) - ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_1dev_dapm_routes, - ARRAY_SIZE(rt1015p_1dev_dapm_routes)); - else - ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_2dev_dapm_routes, - ARRAY_SIZE(rt1015p_2dev_dapm_routes)); + ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets, + ARRAY_SIZE(realtek_2spk_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add rt1015p widgets, ret %d\n", ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols, + ARRAY_SIZE(realtek_2spk_kcontrols)); + if (ret) { + dev_err(rtd->dev, "fail to add rt1015p kcontrols, ret %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_dapm_routes, + ARRAY_SIZE(rt1015p_dapm_routes)); if (ret) dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); return ret; @@ -233,21 +370,16 @@ static int rt1015p_init(struct snd_soc_pcm_runtime *rtd) void sof_rt1015p_dai_link(struct snd_soc_dai_link *link) { link->codecs = rt1015p_dai_link_components; - link->num_codecs = rt1015p_get_num_codecs(); + link->num_codecs = ARRAY_SIZE(rt1015p_dai_link_components); link->init = rt1015p_init; link->ops = &rt1015p_ops; } -EXPORT_SYMBOL_NS(sof_rt1015p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1015p_dai_link, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); void sof_rt1015p_codec_conf(struct snd_soc_card *card) { - if (rt1015p_get_num_codecs() == 1) - return; - - card->codec_conf = rt1015p_codec_confs; - card->num_configs = ARRAY_SIZE(rt1015p_codec_confs); } -EXPORT_SYMBOL_NS(sof_rt1015p_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1015p_codec_conf, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); /* * RT1015 audio amplifier @@ -320,7 +452,7 @@ static int rt1015_hw_params(struct snd_pcm_substream *substream, return ret; } -static struct snd_soc_ops rt1015_ops = { +static const struct snd_soc_ops rt1015_ops = { .hw_params = rt1015_hw_params, }; @@ -348,8 +480,42 @@ static struct snd_soc_dai_link_component rt1015_components[] = { static int speaker_codec_init_lr(struct snd_soc_pcm_runtime *rtd) { - return snd_soc_dapm_add_routes(&rtd->card->dapm, speaker_map_lr, - ARRAY_SIZE(speaker_map_lr)); + struct snd_soc_card *card = rtd->card; + unsigned int num_codecs = get_num_codecs(RT1015_ACPI_HID); + int ret; + + switch (num_codecs) { + case 2: + ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets, + ARRAY_SIZE(realtek_2spk_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add rt1015 widgets, ret %d\n", + ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols, + ARRAY_SIZE(realtek_2spk_kcontrols)); + if (ret) { + dev_err(rtd->dev, "fail to add rt1015 kcontrols, ret %d\n", + ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&rtd->card->dapm, speaker_map_lr, + ARRAY_SIZE(speaker_map_lr)); + if (ret) { + dev_err(rtd->dev, "fail to add rt1015 routes, ret %d\n", + ret); + return ret; + } + break; + default: + dev_err(rtd->dev, "rt1015: invalid num_codecs %d\n", num_codecs); + return -EINVAL; + } + + return ret; } void sof_rt1015_codec_conf(struct snd_soc_card *card) @@ -357,7 +523,7 @@ void sof_rt1015_codec_conf(struct snd_soc_card *card) card->codec_conf = rt1015_amp_conf; card->num_configs = ARRAY_SIZE(rt1015_amp_conf); } -EXPORT_SYMBOL_NS(sof_rt1015_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1015_codec_conf, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); void sof_rt1015_dai_link(struct snd_soc_dai_link *link) { @@ -366,7 +532,7 @@ void sof_rt1015_dai_link(struct snd_soc_dai_link *link) link->init = speaker_codec_init_lr; link->ops = &rt1015_ops; } -EXPORT_SYMBOL_NS(sof_rt1015_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1015_dai_link, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); /* * RT1308 audio amplifier @@ -462,7 +628,7 @@ void sof_rt1308_dai_link(struct snd_soc_dai_link *link) link->init = rt1308_init; link->ops = &rt1308_ops; } -EXPORT_SYMBOL_NS(sof_rt1308_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1308_dai_link, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); /* * 2-amp Configuration for RT1019 @@ -486,6 +652,20 @@ static int rt1019p_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_card *card = rtd->card; int ret; + ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets, + ARRAY_SIZE(realtek_2spk_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add rt1019p widgets, ret %d\n", ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols, + ARRAY_SIZE(realtek_2spk_kcontrols)); + if (ret) { + dev_err(rtd->dev, "fail to add rt1019p kcontrols, ret %d\n", ret); + return ret; + } + ret = snd_soc_dapm_add_routes(&card->dapm, rt1019p_dapm_routes, ARRAY_SIZE(rt1019p_dapm_routes)); if (ret) { @@ -501,7 +681,7 @@ void sof_rt1019p_dai_link(struct snd_soc_dai_link *link) link->num_codecs = ARRAY_SIZE(rt1019p_components); link->init = rt1019p_init; } -EXPORT_SYMBOL_NS(sof_rt1019p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1019p_dai_link, "SND_SOC_INTEL_SOF_REALTEK_COMMON"); MODULE_DESCRIPTION("ASoC Intel SOF Realtek helpers"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/boards/sof_realtek_common.h b/sound/soc/intel/boards/sof_realtek_common.h index e3fa2924c1c1..876290555c22 100644 --- a/sound/soc/intel/boards/sof_realtek_common.h +++ b/sound/soc/intel/boards/sof_realtek_common.h @@ -11,7 +11,7 @@ #define __SOF_REALTEK_COMMON_H #include <sound/soc.h> -#include "sof_ssp_common.h" +#include <sound/soc-acpi-intel-ssp-common.h> /* * Realtek ALC1011 @@ -23,15 +23,14 @@ #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); +void sof_rt1011_dai_link(struct device *dev, struct snd_soc_dai_link *link); +void sof_rt1011_codec_conf(struct device *dev, struct snd_soc_card *card); /* * Realtek ALC1015 (AUTO) */ #define RT1015P_CODEC_DAI "HiFi" #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); diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 640d17c6cd35..f5925bd0a3fc 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -27,37 +27,13 @@ #include "sof_board_helpers.h" #include "sof_maxim_common.h" #include "sof_realtek_common.h" -#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_SSP_AMP_SHIFT 6 -#define SOF_RT5682_SSP_AMP_MASK (GENMASK(8, 6)) -#define SOF_RT5682_SSP_AMP(quirk) \ - (((quirk) << SOF_RT5682_SSP_AMP_SHIFT) & SOF_RT5682_SSP_AMP_MASK) -#define SOF_RT5682_MCLK_BYTCHT_EN BIT(9) -#define SOF_RT5682_NUM_HDMIDEV_SHIFT 10 -#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) - -/* BT audio offload: reserve 3 bits for future */ -#define SOF_BT_OFFLOAD_SSP_SHIFT 19 -#define SOF_BT_OFFLOAD_SSP_MASK (GENMASK(21, 19)) -#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) - -/* HDMI capture*/ -#define SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT 27 -#define SOF_SSP_HDMI_CAPTURE_PRESENT_MASK (GENMASK(30, 27)) -#define SOF_HDMI_CAPTURE_SSP_MASK(quirk) \ - (((quirk) << SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT) & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) + +/* Driver-specific board quirks: from bit 0 to 7 */ +#define SOF_RT5682_MCLK_EN BIT(0) /* Default: MCLK on, MCLK 19.2M, SSP0 */ static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0); + SOF_SSP_PORT_CODEC(0); static int sof_rt5682_quirk_cb(const struct dmi_system_id *id) { @@ -72,7 +48,7 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max"), }, - .driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)), + .driver_data = (void *)(SOF_SSP_PORT_CODEC(2)), }, { .callback = sof_rt5682_quirk_cb, @@ -80,7 +56,7 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), DMI_MATCH(DMI_PRODUCT_NAME, "UP-CHT01"), }, - .driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)), + .driver_data = (void *)(SOF_SSP_PORT_CODEC(2)), }, { .callback = sof_rt5682_quirk_cb, @@ -89,25 +65,7 @@ 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_SSP_CODEC(1)), - }, - { - .callback = sof_rt5682_quirk_cb, - .matches = { - DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"), - }, - .driver_data = (void *)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682_SSP_AMP(1)), - }, - { - .callback = sof_rt5682_quirk_cb, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), - }, - .driver_data = (void *)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0)), + SOF_SSP_PORT_CODEC(1)), }, { .callback = sof_rt5682_quirk_cb, @@ -116,9 +74,9 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98373_ALC5682I_I2S_UP4"), }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682_SSP_AMP(2) | - SOF_RT5682_NUM_HDMIDEV(4)), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(2) | + SOF_NUM_IDISP_HDMI(4)), }, { .callback = sof_rt5682_quirk_cb, @@ -128,9 +86,9 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { DMI_MATCH(DMI_OEM_STRING, "AUDIO-ADL_MAX98373_ALC5682I_I2S"), }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682_SSP_AMP(2) | - SOF_RT5682_NUM_HDMIDEV(4)), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(2) | + SOF_NUM_IDISP_HDMI(4)), }, { .callback = sof_rt5682_quirk_cb, @@ -139,9 +97,9 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98390_ALC5682I_I2S"), }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682_SSP_AMP(2) | - SOF_RT5682_NUM_HDMIDEV(4)), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(2) | + SOF_NUM_IDISP_HDMI(4)), }, { .callback = sof_rt5682_quirk_cb, @@ -150,9 +108,9 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_I2S_AMP_SSP2"), }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682_SSP_AMP(2) | - SOF_RT5682_NUM_HDMIDEV(4)), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(2) | + SOF_NUM_IDISP_HDMI(4)), }, { .callback = sof_rt5682_quirk_cb, @@ -160,11 +118,10 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"), }, .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 + SOF_SSP_PORT_CODEC(2) | + SOF_SSP_PORT_AMP(0) | + SOF_SSP_PORT_BT_OFFLOAD(1) | + SOF_BT_OFFLOAD_PRESENT ), }, {} @@ -189,7 +146,7 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) int extra_jack_data; int ret, mclk_freq; - if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) { + if (ctx->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); @@ -230,7 +187,7 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) } } - if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { + if (ctx->rt5682.is_legacy_cpu) { /* * The firmware might enable the clock at * boot (this information may or may not @@ -302,8 +259,8 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream, 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) { + if (ctx->rt5682.mclk_en) { + if (ctx->rt5682.is_legacy_cpu) { ret = clk_prepare_enable(ctx->rt5682.mclk); if (ret < 0) { dev_err(rtd->dev, @@ -351,25 +308,12 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - pll_in = params_rate(params) * 50; - } - - switch (ctx->codec_type) { - case CODEC_RT5650: - pll_id = 0; /* not used in codec driver */ - clk_id = RT5645_SCLK_S_PLL1; - 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; + /* get the tplg configured bclk. */ + pll_in = sof_dai_get_bclk(rtd); + if (pll_in <= 0) { + dev_err(rtd->dev, "invalid bclk freq %d\n", pll_in); + return -EINVAL; + } } pll_out = params_rate(params) * 512; @@ -392,6 +336,40 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } } else { + switch (ctx->codec_type) { + case CODEC_RT5650: + pll_id = 0; /* not used in codec driver */ + clk_id = RT5645_SCLK_S_PLL1; + break; + case CODEC_RT5682: + pll_id = RT5682_PLL1; + clk_id = RT5682_SCLK_S_PLL1; + break; + case CODEC_RT5682S: + /* check plla_table and pllb_table in rt5682s.c */ + switch (pll_in) { + case 3072000: + case 24576000: + /* + * For MCLK = 24.576MHz and sample rate = 96KHz case, use PLL1 We don't test + * pll_out or params_rate() here since rt5682s PLL2 doesn't support 24.576MHz + * input, so we have no choice but to use PLL1. Besides, we will not use PLL at + * all if pll_in == pll_out. ex, MCLK = 24.576Mhz and sample rate = 48KHz + */ + pll_id = RT5682S_PLL1; + clk_id = RT5682S_SCLK_S_PLL1; + break; + default: + pll_id = RT5682S_PLL2; + clk_id = RT5682S_SCLK_S_PLL2; + break; + } + break; + default: + dev_err(rtd->dev, "invalid codec type %d\n", ctx->codec_type); + return -EINVAL; + } + /* Configure pll for codec */ ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, pll_in, pll_out); @@ -419,7 +397,7 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream, return ret; } -static struct snd_soc_ops sof_rt5682_ops = { +static const struct snd_soc_ops sof_rt5682_ops = { .hw_params = sof_rt5682_hw_params, }; @@ -444,16 +422,11 @@ static int sof_card_late_probe(struct snd_soc_card *card) static const struct snd_kcontrol_new sof_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Left Spk"), - SOC_DAPM_PIN_SWITCH("Right Spk"), - }; static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("Left Spk", NULL), - SND_SOC_DAPM_SPK("Right Spk", NULL), }; static const struct snd_soc_dapm_route sof_map[] = { @@ -465,6 +438,17 @@ static const struct snd_soc_dapm_route sof_map[] = { { "IN1P", NULL, "Headset Mic" }, }; +static const struct snd_kcontrol_new rt5650_spk_kcontrols[] = { + SOC_DAPM_PIN_SWITCH("Left Spk"), + SOC_DAPM_PIN_SWITCH("Right Spk"), + +}; + +static const struct snd_soc_dapm_widget rt5650_spk_widgets[] = { + SND_SOC_DAPM_SPK("Left Spk", NULL), + SND_SOC_DAPM_SPK("Right Spk", NULL), +}; + static const struct snd_soc_dapm_route rt5650_spk_dapm_routes[] = { /* speaker */ { "Left Spk", NULL, "SPOL" }, @@ -476,6 +460,22 @@ static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_card *card = rtd->card; int ret; + ret = snd_soc_dapm_new_controls(&card->dapm, rt5650_spk_widgets, + ARRAY_SIZE(rt5650_spk_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add rt5650 spk widgets, ret %d\n", + ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, rt5650_spk_kcontrols, + ARRAY_SIZE(rt5650_spk_kcontrols)); + if (ret) { + dev_err(rtd->dev, "fail to add rt5650 spk kcontrols, ret %d\n", + ret); + return ret; + } + ret = snd_soc_dapm_add_routes(&card->dapm, rt5650_spk_dapm_routes, ARRAY_SIZE(rt5650_spk_dapm_routes)); if (ret) @@ -591,16 +591,13 @@ sof_card_dai_links_create(struct device *dev, struct snd_soc_card *card, max_98360a_dai_link(ctx->amp_link); break; case CODEC_MAX98373: - ctx->amp_link->codecs = max_98373_components; - ctx->amp_link->num_codecs = ARRAY_SIZE(max_98373_components); - ctx->amp_link->init = max_98373_spk_codec_init; - ctx->amp_link->ops = &max_98373_ops; + max_98373_dai_link(dev, ctx->amp_link); break; case CODEC_MAX98390: max_98390_dai_link(dev, ctx->amp_link); break; case CODEC_RT1011: - sof_rt1011_dai_link(ctx->amp_link); + sof_rt1011_dai_link(dev, ctx->amp_link); break; case CODEC_RT1015: sof_rt1015_dai_link(ctx->amp_link); @@ -626,90 +623,112 @@ sof_card_dai_links_create(struct device *dev, struct snd_soc_card *card, return 0; } +#define GLK_LINK_ORDER SOF_LINK_ORDER(SOF_LINK_AMP, \ + SOF_LINK_CODEC, \ + SOF_LINK_DMIC01, \ + SOF_LINK_IDISP_HDMI, \ + SOF_LINK_NONE, \ + SOF_LINK_NONE, \ + SOF_LINK_NONE) + static int sof_audio_probe(struct platform_device *pdev) { struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct sof_card_private *ctx; + char *card_name; int ret; - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - if (pdev->id_entry && pdev->id_entry->driver_data) sof_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data; dmi_check_system(sof_rt5682_quirk_table); - 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_rt5682_quirk = %lx\n", sof_rt5682_quirk); + + /* initialize ctx with board quirk */ + ctx = sof_intel_board_get_ctx(&pdev->dev, sof_rt5682_quirk); + if (!ctx) + return -ENOMEM; if (ctx->codec_type == CODEC_RT5650) { - sof_audio_card_rt5682.name = devm_kstrdup(&pdev->dev, "rt5650", - GFP_KERNEL); + card_name = devm_kstrdup(&pdev->dev, "rt5650", GFP_KERNEL); + if (!card_name) + return -ENOMEM; + + sof_audio_card_rt5682.name = card_name; /* create speaker dai link also */ if (ctx->amp_type == CODEC_NONE) ctx->amp_type = CODEC_RT5650; } + if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) + ctx->hdmi.idisp_codec = true; + if (soc_intel_is_byt() || soc_intel_is_cht()) { 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 { - 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 (!ctx->hdmi_num) - ctx->hdmi_num = 3; - - if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) - ctx->hdmi.idisp_codec = true; - } - - /* need to get main clock from pmc */ - if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { - 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", - ret); - return ret; + } else if (soc_intel_is_glk()) { + /* dmic16k not support */ + ctx->dmic_be_num = 1; + + /* overwrite the DAI link order for GLK boards */ + ctx->link_order_overwrite = GLK_LINK_ORDER; + + /* backward-compatible with existing devices */ + switch (ctx->amp_type) { + case CODEC_MAX98357A: + card_name = devm_kstrdup(&pdev->dev, "glkrt5682max", + GFP_KERNEL); + if (!card_name) + return -ENOMEM; + + sof_audio_card_rt5682.name = card_name; + break; + default: + break; } - - ret = clk_prepare_enable(ctx->rt5682.mclk); - if (ret < 0) { - dev_err(&pdev->dev, - "could not configure MCLK state"); - return ret; + } else if (soc_intel_is_cml()) { + /* backward-compatible with existing devices */ + switch (ctx->amp_type) { + case CODEC_RT1011: + card_name = devm_kstrdup(&pdev->dev, "cml_rt1011_rt5682", + GFP_KERNEL); + if (!card_name) + return -ENOMEM; + + sof_audio_card_rt5682.name = card_name; + break; + default: + break; } } - dev_dbg(&pdev->dev, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk); - - /* port number/mask of peripherals attached to ssp interface */ - ctx->ssp_mask_hdmi_in = (sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) >> - SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT; - - ctx->ssp_bt = (sof_rt5682_quirk & SOF_BT_OFFLOAD_SSP_MASK) >> - SOF_BT_OFFLOAD_SSP_SHIFT; + if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) { + ctx->rt5682.mclk_en = true; - ctx->ssp_amp = (sof_rt5682_quirk & SOF_RT5682_SSP_AMP_MASK) >> - SOF_RT5682_SSP_AMP_SHIFT; + /* need to get main clock from pmc */ + if (ctx->rt5682.is_legacy_cpu) { + ctx->rt5682.mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (IS_ERR(ctx->rt5682.mclk)) { + ret = PTR_ERR(ctx->rt5682.mclk); - ctx->ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK; + dev_err(&pdev->dev, + "Failed to get MCLK from pmc_plt_clk_3: %d\n", + ret); + return ret; + } - if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) - ctx->bt_offload_present = true; + ret = clk_prepare_enable(ctx->rt5682.mclk); + if (ret < 0) { + dev_err(&pdev->dev, + "could not configure MCLK state"); + return ret; + } + } + } /* update dai_link */ ret = sof_card_dai_links_create(&pdev->dev, &sof_audio_card_rt5682, ctx); @@ -725,7 +744,7 @@ static int sof_audio_probe(struct platform_device *pdev) max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682); break; case CODEC_RT1011: - sof_rt1011_codec_conf(&sof_audio_card_rt5682); + sof_rt1011_codec_conf(&pdev->dev, &sof_audio_card_rt5682); break; case CODEC_RT1015: sof_rt1015_codec_conf(&sof_audio_card_rt5682); @@ -733,11 +752,11 @@ static int sof_audio_probe(struct platform_device *pdev) 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: + case CODEC_NONE: /* no codec conf required */ break; default: @@ -762,100 +781,116 @@ static int sof_audio_probe(struct platform_device *pdev) static const struct platform_device_id board_ids[] = { { .name = "sof_rt5682", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_SSP_PORT_CODEC(2)), + }, + { + .name = "glk_rt5682_def", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_SSP_PORT_CODEC(2) | + SOF_SSP_PORT_AMP(1)), + }, + { + .name = "icl_rt5682_def", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_SSP_PORT_CODEC(0)), }, { - .name = "cml_rt1015_rt5682", + .name = "cml_rt5682_def", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682_SSP_AMP(1)), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1)), }, { .name = "jsl_rt5682_def", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682_SSP_AMP(1)), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1)), }, { .name = "tgl_rt5682_def", .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), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1) | + SOF_NUM_IDISP_HDMI(4) | + SOF_SSP_PORT_BT_OFFLOAD(2) | + SOF_BT_OFFLOAD_PRESENT), }, { .name = "adl_rt5682_def", .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), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1) | + SOF_NUM_IDISP_HDMI(4) | + SOF_SSP_PORT_BT_OFFLOAD(2) | + SOF_BT_OFFLOAD_PRESENT), }, { .name = "adl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682_SSP_AMP(2) | - SOF_RT5682_NUM_HDMIDEV(4)), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(2) | + SOF_NUM_IDISP_HDMI(4)), }, { .name = "adl_rt5682_c1_h02", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(1) | - SOF_RT5682_NUM_HDMIDEV(3) | + SOF_SSP_PORT_CODEC(1) | /* SSP 0 and SSP 2 are used for HDMI IN */ - SOF_HDMI_CAPTURE_SSP_MASK(0x5)), + SOF_SSP_MASK_HDMI_CAPTURE(0x5)), }, { .name = "rpl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682_SSP_AMP(2) | - SOF_RT5682_NUM_HDMIDEV(4)), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(2) | + SOF_NUM_IDISP_HDMI(4)), }, { .name = "rpl_rt5682_def", .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), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1) | + SOF_NUM_IDISP_HDMI(4) | + SOF_SSP_PORT_BT_OFFLOAD(2) | + SOF_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) | + SOF_SSP_PORT_CODEC(1) | /* SSP 0 and SSP 2 are used for HDMI IN */ - SOF_HDMI_CAPTURE_SSP_MASK(0x5)), + SOF_SSP_MASK_HDMI_CAPTURE(0x5)), }, { - .name = "mtl_mx98357_rt5682", + .name = "mtl_rt5682_def", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682_SSP_AMP(1) | - SOF_RT5682_NUM_HDMIDEV(3) | - SOF_BT_OFFLOAD_SSP(2) | - SOF_SSP_BT_OFFLOAD_PRESENT), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1) | + SOF_SSP_PORT_BT_OFFLOAD(2) | + SOF_BT_OFFLOAD_PRESENT), }, { - .name = "mtl_mx98360_rt5682", + .name = "mtl_rt5682_c1_h02", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682_SSP_AMP(1) | - SOF_RT5682_NUM_HDMIDEV(3)), + SOF_SSP_PORT_CODEC(1) | + /* SSP 0 and SSP 2 are used for HDMI IN */ + SOF_SSP_MASK_HDMI_CAPTURE(0x5)), }, { - .name = "mtl_rt5682_def", + .name = "arl_rt5682_c1_h02", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_SSP_PORT_CODEC(1) | + /* SSP 0 and SSP 2 are used for HDMI IN */ + SOF_SSP_MASK_HDMI_CAPTURE(0x5)), + }, + { + .name = "ptl_rt5682_def", .driver_data = (kernel_ulong_t)(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), + SOF_SSP_PORT_CODEC(0) | + SOF_SSP_PORT_AMP(1) | + SOF_SSP_PORT_BT_OFFLOAD(2) | + SOF_BT_OFFLOAD_PRESENT), }, { } }; @@ -878,7 +913,6 @@ 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_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); +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"); diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 08f330ed5c2e..81a914bd7ec2 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -5,37 +5,48 @@ * sof_sdw - ASOC Machine driver for Intel SoundWire platforms */ +#include <linux/acpi.h> +#include <linux/bitmap.h> #include <linux/device.h> #include <linux/dmi.h> #include <linux/module.h> #include <linux/soundwire/sdw.h> #include <linux/soundwire/sdw_type.h> -#include <sound/soc.h> +#include <linux/soundwire/sdw_intel.h> +#include <sound/core.h> #include <sound/soc-acpi.h> #include "sof_sdw_common.h" #include "../../codecs/rt711.h" -unsigned long sof_sdw_quirk = RT711_JD1; +static unsigned long sof_sdw_quirk = RT711_JD1; static int quirk_override = -1; module_param_named(quirk, quirk_override, int, 0444); MODULE_PARM_DESC(quirk, "Board-specific quirk override"); +#define DMIC_DEFAULT_CHANNELS 2 + static void log_quirks(struct device *dev) { - if (SOF_JACK_JDSRC(sof_sdw_quirk)) + if (SOC_SDW_JACK_JDSRC(sof_sdw_quirk)) dev_dbg(dev, "quirk realtek,jack-detect-source %ld\n", - SOF_JACK_JDSRC(sof_sdw_quirk)); - if (sof_sdw_quirk & SOF_SDW_FOUR_SPK) - dev_dbg(dev, "quirk SOF_SDW_FOUR_SPK enabled\n"); + SOC_SDW_JACK_JDSRC(sof_sdw_quirk)); + if (sof_sdw_quirk & SOC_SDW_FOUR_SPK) + dev_err(dev, "quirk SOC_SDW_FOUR_SPK enabled but no longer supported\n"); if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) dev_dbg(dev, "quirk SOF_SDW_TGL_HDMI enabled\n"); - if (sof_sdw_quirk & SOF_SDW_PCH_DMIC) - dev_dbg(dev, "quirk SOF_SDW_PCH_DMIC enabled\n"); + if (sof_sdw_quirk & SOC_SDW_PCH_DMIC) + dev_dbg(dev, "quirk SOC_SDW_PCH_DMIC enabled\n"); if (SOF_SSP_GET_PORT(sof_sdw_quirk)) dev_dbg(dev, "SSP port %ld\n", SOF_SSP_GET_PORT(sof_sdw_quirk)); - if (sof_sdw_quirk & SOF_SDW_NO_AGGREGATION) - dev_dbg(dev, "quirk SOF_SDW_NO_AGGREGATION enabled\n"); + if (sof_sdw_quirk & SOC_SDW_NO_AGGREGATION) + dev_err(dev, "quirk SOC_SDW_NO_AGGREGATION enabled but no longer supported\n"); + if (sof_sdw_quirk & SOC_SDW_CODEC_SPKR) + dev_dbg(dev, "quirk SOC_SDW_CODEC_SPKR enabled\n"); + if (sof_sdw_quirk & SOC_SDW_SIDECAR_AMPS) + dev_dbg(dev, "quirk SOC_SDW_SIDECAR_AMPS enabled\n"); + if (sof_sdw_quirk & SOC_SDW_CODEC_MIC) + dev_dbg(dev, "quirk SOC_SDW_CODEC_MIC enabled\n"); } static int sof_sdw_quirk_cb(const struct dmi_system_id *id) @@ -52,7 +63,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), }, - .driver_data = (void *)SOF_SDW_PCH_DMIC, + .driver_data = (void *)SOC_SDW_PCH_DMIC, }, { .callback = sof_sdw_quirk_cb, @@ -77,8 +88,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"), }, - .driver_data = (void *)(RT711_JD2 | - SOF_SDW_FOUR_SPK), + .driver_data = (void *)(RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -86,8 +96,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"), }, - .driver_data = (void *)(RT711_JD2 | - SOF_SDW_FOUR_SPK), + .driver_data = (void *)(RT711_JD2), }, /* IceLake devices */ { @@ -96,7 +105,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), }, - .driver_data = (void *)SOF_SDW_PCH_DMIC, + .driver_data = (void *)SOC_SDW_PCH_DMIC, }, /* TigerLake devices */ { @@ -108,7 +117,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | RT711_JD1 | - SOF_SDW_PCH_DMIC | + SOC_SDW_PCH_DMIC | SOF_SSP_PORT(SOF_I2S_SSP2)), }, { @@ -138,8 +147,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5D") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -148,8 +156,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -158,8 +165,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_SDW_PCH_DMIC | - SOF_SDW_FOUR_SPK | + SOC_SDW_PCH_DMIC | SOF_BT_OFFLOAD_SSP(2) | SOF_SSP_BT_OFFLOAD_PRESENT), }, @@ -170,8 +176,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Ripto"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_SDW_PCH_DMIC | - SOF_SDW_FOUR_SPK), + SOC_SDW_PCH_DMIC), }, { /* @@ -186,7 +191,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Conv"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_SDW_PCH_DMIC | + SOC_SDW_PCH_DMIC | RT711_JD1), }, { @@ -200,7 +205,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_BOARD_NAME, "8709"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_SDW_PCH_DMIC | + SOC_SDW_PCH_DMIC | RT711_JD1), }, { @@ -211,7 +216,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "LAPBC"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_SDW_PCH_DMIC | + SOC_SDW_PCH_DMIC | RT711_JD1), }, { @@ -222,7 +227,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_SDW_PCH_DMIC | + SOC_SDW_PCH_DMIC | RT711_JD1), }, { @@ -233,7 +238,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "LAPRC"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_SDW_PCH_DMIC | + SOC_SDW_PCH_DMIC | RT711_JD2_100K), }, { @@ -244,7 +249,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_BOARD_NAME, "LAPRC710"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_SDW_PCH_DMIC | + SOC_SDW_PCH_DMIC | RT711_JD2_100K), }, /* TigerLake-SDCA devices */ @@ -255,8 +260,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -282,12 +286,20 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { { .callback = sof_sdw_quirk_cb, .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_SKU, "0000000000070000"), + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2_100K), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Google"), DMI_MATCH(DMI_PRODUCT_NAME, "Brya"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_SDW_PCH_DMIC | - SOF_SDW_FOUR_SPK | + SOC_SDW_PCH_DMIC | SOF_BT_OFFLOAD_SSP(2) | SOF_SSP_BT_OFFLOAD_PRESENT), }, @@ -298,8 +310,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AF0") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -308,8 +319,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AF3"), }, /* No Jack */ - .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_SDW_FOUR_SPK), + .driver_data = (void *)(SOF_SDW_TGL_HDMI), }, { .callback = sof_sdw_quirk_cb, @@ -318,8 +328,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFE") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -328,8 +337,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFF") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -338,8 +346,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -348,8 +355,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -358,8 +364,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B11") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -368,8 +373,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B12") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -397,8 +401,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B29"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -412,6 +415,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { { .callback = sof_sdw_quirk_cb, .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B8C"), + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "HP"), DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16"), }, @@ -426,8 +438,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0BDA") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C0F") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -436,8 +456,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C10"), }, /* No Jack */ - .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_SDW_FOUR_SPK), + .driver_data = (void *)(SOF_SDW_TGL_HDMI), }, { .callback = sof_sdw_quirk_cb, @@ -446,8 +465,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C11") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -456,8 +474,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C40") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), }, { .callback = sof_sdw_quirk_cb, @@ -466,8 +483,31 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C4F") }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | - RT711_JD2 | - SOF_SDW_FOUR_SPK), + RT711_JD2), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CF6") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CF9") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CFA") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), }, /* MeteorLake devices */ { @@ -491,10 +531,19 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Google"), DMI_MATCH(DMI_PRODUCT_NAME, "Rex"), }, - .driver_data = (void *)(SOF_SDW_PCH_DMIC | + .driver_data = (void *)(SOC_SDW_PCH_DMIC | SOF_BT_OFFLOAD_SSP(1) | SOF_SSP_BT_OFFLOAD_PRESENT), }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "OMEN Transcend Gaming Laptop"), + }, + .driver_data = (void *)(RT711_JD2), + }, + /* LunarLake devices */ { .callback = sof_sdw_quirk_cb, @@ -504,1137 +553,572 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { }, .driver_data = (void *)(RT711_JD2), }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CE3") + }, + .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CE4") + }, + .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CDB") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CDC") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CDD") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0D36") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CF8") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83JX") + }, + .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS | SOC_SDW_CODEC_MIC), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83LC") + }, + .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS | SOC_SDW_CODEC_MIC), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83MC") + }, + .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS | SOC_SDW_CODEC_MIC), + }, { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83NM") + }, + .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS | SOC_SDW_CODEC_MIC), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83HM") + }, + .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS | + SOC_SDW_CODEC_MIC), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21QB") + }, + /* Note this quirk excludes the CODEC mic */ + .driver_data = (void *)(SOC_SDW_CODEC_MIC), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21QA") + }, + /* Note this quirk excludes the CODEC mic */ + .driver_data = (void *)(SOC_SDW_CODEC_MIC), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21Q6") + }, + .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS | SOC_SDW_CODEC_MIC), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21Q7") + }, + .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS | SOC_SDW_CODEC_MIC), + }, + + /* ArrowLake devices */ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CE8") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CF1") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CF7") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CF0") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CF3") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CF4") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CF5") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, + /* Pantherlake devices*/ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_ptlrvp"), + }, + .driver_data = (void *)(SOC_SDW_PCH_DMIC), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + DMI_MATCH(DMI_PRODUCT_NAME, "Fatcat"), + }, + .driver_data = (void *)(SOC_SDW_PCH_DMIC | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, + /* Wildcatlake devices*/ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_wclrvp"), + }, + .driver_data = (void *)(SOC_SDW_PCH_DMIC), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + DMI_MATCH(DMI_PRODUCT_NAME, "Ocelot"), + }, + .driver_data = (void *)(SOC_SDW_PCH_DMIC | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, {} }; -static struct snd_soc_dai_link_component platform_component[] = { - { - /* name might be overridden during probe */ - .name = "0000:00:1f.3" - } +static const struct snd_pci_quirk sof_sdw_ssid_quirk_table[] = { + SND_PCI_QUIRK(0x1043, 0x1e13, "ASUS Zenbook S14", SOC_SDW_CODEC_MIC), + SND_PCI_QUIRK(0x1043, 0x1f43, "ASUS Zenbook S16", SOC_SDW_CODEC_MIC), + {} }; -/* these wrappers are only needed to avoid typecast compilation errors */ -int sdw_startup(struct snd_pcm_substream *substream) +static void sof_sdw_check_ssid_quirk(const struct snd_soc_acpi_mach *mach) { - return sdw_startup_stream(substream); -} + const struct snd_pci_quirk *quirk_entry; -int sdw_prepare(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); - struct sdw_stream_runtime *sdw_stream; - struct snd_soc_dai *dai; + quirk_entry = snd_pci_quirk_lookup_id(mach->mach_params.subsystem_vendor, + mach->mach_params.subsystem_device, + sof_sdw_ssid_quirk_table); - /* Find stream from first CPU DAI */ - dai = snd_soc_rtd_to_cpu(rtd, 0); + if (quirk_entry) + sof_sdw_quirk = quirk_entry->value; +} - sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); - if (IS_ERR(sdw_stream)) { - dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); - return PTR_ERR(sdw_stream); - } +static const struct snd_soc_ops sdw_ops = { + .startup = asoc_sdw_startup, + .prepare = asoc_sdw_prepare, + .trigger = asoc_sdw_trigger, + .hw_params = asoc_sdw_hw_params, + .hw_free = asoc_sdw_hw_free, + .shutdown = asoc_sdw_shutdown, +}; - return sdw_prepare_stream(sdw_stream); -} +static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"}; -int sdw_trigger(struct snd_pcm_substream *substream, int cmd) +static int create_sdw_dailink(struct snd_soc_card *card, + struct asoc_sdw_dailink *sof_dai, + struct snd_soc_dai_link **dai_links, + int *be_id, struct snd_soc_codec_conf **codec_conf) { - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); - struct sdw_stream_runtime *sdw_stream; - struct snd_soc_dai *dai; + struct device *dev = card->dev; + struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev); + struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); + struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; + struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private; + struct asoc_sdw_endpoint *sof_end; + int stream; int ret; - /* Find stream from first CPU DAI */ - dai = snd_soc_rtd_to_cpu(rtd, 0); + list_for_each_entry(sof_end, &sof_dai->endpoints, list) { + if (sof_end->name_prefix) { + (*codec_conf)->dlc.name = sof_end->codec_name; + (*codec_conf)->name_prefix = sof_end->name_prefix; + (*codec_conf)++; + } - sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); - if (IS_ERR(sdw_stream)) { - dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); - return PTR_ERR(sdw_stream); + if (sof_end->include_sidecar) { + ret = sof_end->codec_info->add_sidecar(card, dai_links, codec_conf); + if (ret) + return ret; + } } - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - case SNDRV_PCM_TRIGGER_RESUME: - ret = sdw_enable_stream(sdw_stream); - break; - - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_STOP: - ret = sdw_disable_stream(sdw_stream); - break; - default: - ret = -EINVAL; - break; - } + for_each_pcm_streams(stream) { + static const char * const sdw_stream_name[] = { + "SDW%d-Playback", + "SDW%d-Capture", + "SDW%d-Playback-%s", + "SDW%d-Capture-%s", + }; + struct snd_soc_dai_link_ch_map *codec_maps; + struct snd_soc_dai_link_component *codecs; + struct snd_soc_dai_link_component *cpus; + struct snd_soc_dai_link_component *platform; + int num_cpus = hweight32(sof_dai->link_mask[stream]); + int num_codecs = sof_dai->num_devs[stream]; + int playback, capture; + int cur_link = 0; + int i = 0, j = 0; + char *name; - if (ret) - dev_err(rtd->dev, "%s trigger %d failed: %d\n", __func__, cmd, ret); + if (!sof_dai->num_devs[stream]) + continue; - return ret; -} + sof_end = list_first_entry(&sof_dai->endpoints, + struct asoc_sdw_endpoint, list); -int sdw_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); - struct snd_soc_dai_link_ch_map *ch_maps; - int ch = params_channels(params); - unsigned int ch_mask; - int num_codecs; - int step; - int i; - - if (!rtd->dai_link->ch_maps) - return 0; - - /* Identical data will be sent to all codecs in playback */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ch_mask = GENMASK(ch - 1, 0); - step = 0; - } else { - num_codecs = rtd->dai_link->num_codecs; - - if (ch < num_codecs || ch % num_codecs != 0) { - dev_err(rtd->dev, "Channels number %d is invalid when codec number = %d\n", - ch, num_codecs); + *be_id = sof_end->dai_info->dailink[stream]; + if (*be_id < 0) { + dev_err(dev, "Invalid dailink id %d\n", *be_id); return -EINVAL; } - ch_mask = GENMASK(ch / num_codecs - 1, 0); - step = hweight_long(ch_mask); - - } - - /* - * The captured data will be combined from each cpu DAI if the dai - * link has more than one codec DAIs. Set codec channel mask and - * ASoC will set the corresponding channel numbers for each cpu dai. - */ - for_each_link_ch_maps(rtd->dai_link, i, ch_maps) - ch_maps->ch_mask = ch_mask << (i * step); - - return 0; -} - -int sdw_hw_free(struct snd_pcm_substream *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 = snd_soc_rtd_to_cpu(rtd, 0); - - sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); - if (IS_ERR(sdw_stream)) { - dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); - return PTR_ERR(sdw_stream); - } - - return sdw_deprepare_stream(sdw_stream); -} - -void sdw_shutdown(struct snd_pcm_substream *substream) -{ - sdw_shutdown_stream(substream); -} - -static const struct snd_soc_ops sdw_ops = { - .startup = sdw_startup, - .prepare = sdw_prepare, - .trigger = sdw_trigger, - .hw_params = sdw_hw_params, - .hw_free = sdw_hw_free, - .shutdown = sdw_shutdown, -}; - -static struct sof_sdw_codec_info codec_info_list[] = { - { - .part_id = 0x700, - .dais = { - { - .direction = {true, true}, - .dai_name = "rt700-aif1", - .dai_type = SOF_SDW_DAI_TYPE_JACK, - .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, - .rtd_init = rt700_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x711, - .version_id = 3, - .dais = { - { - .direction = {true, true}, - .dai_name = "rt711-sdca-aif1", - .dai_type = SOF_SDW_DAI_TYPE_JACK, - .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, - .init = sof_sdw_rt_sdca_jack_init, - .exit = sof_sdw_rt_sdca_jack_exit, - .rtd_init = rt_sdca_jack_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x711, - .version_id = 2, - .dais = { - { - .direction = {true, true}, - .dai_name = "rt711-aif1", - .dai_type = SOF_SDW_DAI_TYPE_JACK, - .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, - .init = sof_sdw_rt711_init, - .exit = sof_sdw_rt711_exit, - .rtd_init = rt711_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x712, - .version_id = 3, - .dais = { - { - .direction = {true, true}, - .dai_name = "rt712-sdca-aif1", - .dai_type = SOF_SDW_DAI_TYPE_JACK, - .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, - .init = sof_sdw_rt_sdca_jack_init, - .exit = sof_sdw_rt_sdca_jack_exit, - .rtd_init = rt_sdca_jack_rtd_init, - }, - { - .direction = {true, false}, - .dai_name = "rt712-sdca-aif2", - .dai_type = SOF_SDW_DAI_TYPE_AMP, - .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, - .rtd_init = rt712_spk_rtd_init, - }, - }, - .dai_num = 2, - }, - { - .part_id = 0x1712, - .version_id = 3, - .dais = { - { - .direction = {false, true}, - .dai_name = "rt712-sdca-dmic-aif1", - .dai_type = SOF_SDW_DAI_TYPE_MIC, - .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, - .rtd_init = rt712_sdca_dmic_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x713, - .version_id = 3, - .dais = { - { - .direction = {true, true}, - .dai_name = "rt712-sdca-aif1", - .dai_type = SOF_SDW_DAI_TYPE_JACK, - .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, - .init = sof_sdw_rt_sdca_jack_init, - .exit = sof_sdw_rt_sdca_jack_exit, - .rtd_init = rt_sdca_jack_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x1713, - .version_id = 3, - .dais = { - { - .direction = {false, true}, - .dai_name = "rt712-sdca-dmic-aif1", - .dai_type = SOF_SDW_DAI_TYPE_MIC, - .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, - .rtd_init = rt712_sdca_dmic_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x1308, - .acpi_id = "10EC1308", - .dais = { - { - .direction = {true, false}, - .dai_name = "rt1308-aif", - .dai_type = SOF_SDW_DAI_TYPE_AMP, - .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, - .init = sof_sdw_rt_amp_init, - .exit = sof_sdw_rt_amp_exit, - .rtd_init = rt_amp_spk_rtd_init, - }, - }, - .dai_num = 1, - .ops = &sof_sdw_rt1308_i2s_ops, - }, - { - .part_id = 0x1316, - .dais = { - { - .direction = {true, true}, - .dai_name = "rt1316-aif", - .dai_type = SOF_SDW_DAI_TYPE_AMP, - .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, - .init = sof_sdw_rt_amp_init, - .exit = sof_sdw_rt_amp_exit, - .rtd_init = rt_amp_spk_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x1318, - .dais = { - { - .direction = {true, true}, - .dai_name = "rt1318-aif", - .dai_type = SOF_SDW_DAI_TYPE_AMP, - .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, - .init = sof_sdw_rt_amp_init, - .exit = sof_sdw_rt_amp_exit, - .rtd_init = rt_amp_spk_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x714, - .version_id = 3, - .ignore_pch_dmic = true, - .dais = { - { - .direction = {false, true}, - .dai_name = "rt715-aif2", - .dai_type = SOF_SDW_DAI_TYPE_MIC, - .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, - .rtd_init = rt715_sdca_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x715, - .version_id = 3, - .ignore_pch_dmic = true, - .dais = { - { - .direction = {false, true}, - .dai_name = "rt715-aif2", - .dai_type = SOF_SDW_DAI_TYPE_MIC, - .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, - .rtd_init = rt715_sdca_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x714, - .version_id = 2, - .ignore_pch_dmic = true, - .dais = { - { - .direction = {false, true}, - .dai_name = "rt715-aif2", - .dai_type = SOF_SDW_DAI_TYPE_MIC, - .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, - .rtd_init = rt715_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x715, - .version_id = 2, - .ignore_pch_dmic = true, - .dais = { - { - .direction = {false, true}, - .dai_name = "rt715-aif2", - .dai_type = SOF_SDW_DAI_TYPE_MIC, - .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, - .rtd_init = rt715_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x722, - .version_id = 3, - .dais = { - { - .direction = {true, true}, - .dai_name = "rt722-sdca-aif1", - .dai_type = SOF_SDW_DAI_TYPE_JACK, - .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, - .init = sof_sdw_rt_sdca_jack_init, - .exit = sof_sdw_rt_sdca_jack_exit, - }, - { - .direction = {true, false}, - .dai_name = "rt722-sdca-aif2", - .dai_type = SOF_SDW_DAI_TYPE_AMP, - /* No feedback capability is provided by rt722-sdca codec driver*/ - .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, - .init = sof_sdw_rt722_spk_init, - }, - { - .direction = {false, true}, - .dai_name = "rt722-sdca-aif3", - .dai_type = SOF_SDW_DAI_TYPE_MIC, - .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, - .init = sof_sdw_rt722_sdca_dmic_init, - }, - }, - .dai_num = 3, - }, - { - .part_id = 0x8373, - .dais = { - { - .direction = {true, true}, - .dai_name = "max98373-aif1", - .dai_type = SOF_SDW_DAI_TYPE_AMP, - .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, - .init = sof_sdw_maxim_init, - .rtd_init = maxim_spk_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x8363, - .dais = { - { - .direction = {true, false}, - .dai_name = "max98363-aif1", - .dai_type = SOF_SDW_DAI_TYPE_AMP, - .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, - .init = sof_sdw_maxim_init, - .rtd_init = maxim_spk_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x5682, - .dais = { - { - .direction = {true, true}, - .dai_name = "rt5682-sdw", - .dai_type = SOF_SDW_DAI_TYPE_JACK, - .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, - .rtd_init = rt5682_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x3556, - .dais = { - { - .direction = {true, true}, - .dai_name = "cs35l56-sdw1", - .dai_type = SOF_SDW_DAI_TYPE_AMP, - .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, - .init = sof_sdw_cs_amp_init, - .rtd_init = cs_spk_rtd_init, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x4242, - .dais = { - { - .direction = {true, true}, - .dai_name = "cs42l42-sdw", - .dai_type = SOF_SDW_DAI_TYPE_JACK, - .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, - .rtd_init = cs42l42_rtd_init, - }, - }, - .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}, - .rtd_init = cs42l43_hs_rtd_init, - }, - { - .direction = {false, true}, - .dai_name = "cs42l43-dp1", - .dai_type = SOF_SDW_DAI_TYPE_MIC, - .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, - .rtd_init = cs42l43_dmic_rtd_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 = { - { - .direction = {true, true}, - .dai_name = "sdw-mockup-aif1", - .dai_type = SOF_SDW_DAI_TYPE_JACK, - .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, - .init = NULL, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0xaa55, /* headset codec mockup */ - .version_id = 0, - .dais = { - { - .direction = {true, true}, - .dai_name = "sdw-mockup-aif1", - .dai_type = SOF_SDW_DAI_TYPE_JACK, - .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, - .init = NULL, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x55aa, /* amplifier mockup */ - .version_id = 0, - .dais = { - { - .direction = {true, true}, - .dai_name = "sdw-mockup-aif1", - .dai_type = SOF_SDW_DAI_TYPE_AMP, - .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, - .init = NULL, - }, - }, - .dai_num = 1, - }, - { - .part_id = 0x5555, - .version_id = 0, - .dais = { - { - .dai_name = "sdw-mockup-aif1", - .direction = {false, true}, - .dai_type = SOF_SDW_DAI_TYPE_MIC, - .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, - .init = NULL, - }, - }, - .dai_num = 1, - }, -}; - -static inline int find_codec_info_part(const u64 adr) -{ - unsigned int part_id, sdw_version; - int i; - - part_id = SDW_PART_ID(adr); - sdw_version = SDW_VERSION(adr); - for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) - /* - * A codec info is for all sdw version with the part id if - * version_id is not specified in the codec info. - */ - if (part_id == codec_info_list[i].part_id && - (!codec_info_list[i].version_id || - sdw_version == codec_info_list[i].version_id)) - return i; - - return -EINVAL; - -} - -static inline int find_codec_info_acpi(const u8 *acpi_id) -{ - int i; - - if (!acpi_id[0]) - return -EINVAL; - - for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) - if (!memcmp(codec_info_list[i].acpi_id, acpi_id, ACPI_ID_LEN)) - return i; - - return -EINVAL; -} - -/* - * get BE dailink number and CPU DAI number based on sdw link adr. - * Since some sdw slaves may be aggregated, the CPU DAI number - * may be larger than the number of BE dailinks. - */ -static int get_dailink_info(struct device *dev, - const struct snd_soc_acpi_link_adr *adr_link, - int *sdw_be_num, int *codecs_num) -{ - bool group_visited[SDW_MAX_GROUPS]; - bool no_aggregation; - int i; - int j; - - no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; - *sdw_be_num = 0; + /* create stream name according to first link id */ + if (ctx->append_dai_type) + name = devm_kasprintf(dev, GFP_KERNEL, + sdw_stream_name[stream + 2], + ffs(sof_end->link_mask) - 1, + type_strings[sof_end->dai_info->dai_type]); + else + name = devm_kasprintf(dev, GFP_KERNEL, + sdw_stream_name[stream], + ffs(sof_end->link_mask) - 1); + if (!name) + return -ENOMEM; - if (!adr_link) - return -EINVAL; + cpus = devm_kcalloc(dev, num_cpus, sizeof(*cpus), GFP_KERNEL); + if (!cpus) + return -ENOMEM; - for (i = 0; i < SDW_MAX_GROUPS; i++) - group_visited[i] = false; + codecs = devm_kcalloc(dev, num_codecs, sizeof(*codecs), GFP_KERNEL); + if (!codecs) + return -ENOMEM; - for (; adr_link->num_adr; adr_link++) { - const struct snd_soc_acpi_endpoint *endpoint; - struct sof_sdw_codec_info *codec_info; - int codec_index; - int stream; - u64 adr; + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!platform) + return -ENOMEM; - /* make sure the link mask has a single bit set */ - if (!is_power_of_2(adr_link->mask)) - return -EINVAL; + codec_maps = devm_kcalloc(dev, num_codecs, sizeof(*codec_maps), GFP_KERNEL); + if (!codec_maps) + return -ENOMEM; - for (i = 0; i < adr_link->num_adr; i++) { - adr = adr_link->adr_d[i].adr; - codec_index = find_codec_info_part(adr); - if (codec_index < 0) - return codec_index; + list_for_each_entry(sof_end, &sof_dai->endpoints, list) { + if (!sof_end->dai_info->direction[stream]) + continue; - codec_info = &codec_info_list[codec_index]; + if (cur_link != sof_end->link_mask) { + int link_num = ffs(sof_end->link_mask) - 1; + int pin_num = intel_ctx->sdw_pin_index[link_num]++; - *codecs_num += codec_info->dai_num; + cur_link = sof_end->link_mask; - if (!adr_link->adr_d[i].name_prefix) { - dev_err(dev, "codec 0x%llx does not have a name prefix\n", - adr_link->adr_d[i].adr); - return -EINVAL; + cpus[i].dai_name = devm_kasprintf(dev, GFP_KERNEL, + "SDW%d Pin%d", + link_num, pin_num); + if (!cpus[i].dai_name) + return -ENOMEM; + i++; } - endpoint = adr_link->adr_d[i].endpoints; - if (endpoint->aggregated && !endpoint->group_id) { - dev_err(dev, "invalid group id on link %x\n", - adr_link->mask); - return -EINVAL; - } + codec_maps[j].cpu = i - 1; + codec_maps[j].codec = j; - for (j = 0; j < codec_info->dai_num; j++) { - /* count DAI number for playback and capture */ - for_each_pcm_streams(stream) { - if (!codec_info->dais[j].direction[stream]) - continue; - - /* count BE for each non-aggregated slave or group */ - if (!endpoint->aggregated || no_aggregation || - !group_visited[endpoint->group_id]) - (*sdw_be_num)++; - } + codecs[j].name = sof_end->codec_name; + codecs[j].dai_name = sof_end->dai_info->dai_name; + if (sof_end->dai_info->dai_type == SOC_SDW_DAI_TYPE_MIC && + mach_params->dmic_num > 0) { + dev_warn(dev, + "Both SDW DMIC and PCH DMIC are present, if incorrect, please set kernel params snd_sof_intel_hda_generic dmic_num=0 to disable PCH DMIC\n"); } - - if (endpoint->aggregated) - group_visited[endpoint->group_id] = true; + j++; } - } - - return 0; -} - -static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, - 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)++; - dai_links->name = name; - dai_links->platforms = platform_component; - dai_links->num_platforms = ARRAY_SIZE(platform_component); - dai_links->no_pcm = 1; - dai_links->cpus = cpus; - dai_links->num_cpus = cpus_num; - dai_links->codecs = codecs; - dai_links->num_codecs = codecs_num; - dai_links->dpcm_playback = playback; - dai_links->dpcm_capture = capture; - dai_links->init = init; - 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; + WARN_ON(i != num_cpus || j != num_codecs); - /* 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; + playback = (stream == SNDRV_PCM_STREAM_PLAYBACK); + capture = (stream == SNDRV_PCM_STREAM_CAPTURE); - dlc[0].dai_name = cpu_dai_name; + asoc_sdw_init_dai_link(dev, *dai_links, be_id, name, playback, capture, + cpus, num_cpus, platform, 1, codecs, num_codecs, + 1, asoc_sdw_rtd_init, &sdw_ops); - dlc[1].name = codec_name; - dlc[1].dai_name = codec_dai_name; + /* + * SoundWire DAILINKs use 'stream' functions and Bank Switch operations + * based on wait_for_completion(), tag them as 'nonatomic'. + */ + (*dai_links)->nonatomic = true; + (*dai_links)->ch_maps = codec_maps; + + list_for_each_entry(sof_end, &sof_dai->endpoints, list) { + if (sof_end->dai_info->init) + sof_end->dai_info->init(card, *dai_links, + sof_end->codec_info, + playback); + } - init_dai_link(dev, dai_links, be_id, name, playback, capture, - &dlc[0], 1, &dlc[1], 1, init, ops); + (*dai_links)++; + } return 0; } -static bool is_unique_device(const struct snd_soc_acpi_link_adr *adr_link, - unsigned int sdw_version, - unsigned int mfg_id, - unsigned int part_id, - unsigned int class_id, - int index_in_link) +static int create_sdw_dailinks(struct snd_soc_card *card, + struct snd_soc_dai_link **dai_links, int *be_id, + struct asoc_sdw_dailink *sof_dais, + struct snd_soc_codec_conf **codec_conf) { - int i; + struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); + struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private; + int ret, i; - for (i = 0; i < adr_link->num_adr; i++) { - unsigned int sdw1_version, mfg1_id, part1_id, class1_id; - u64 adr; + for (i = 0; i < SDW_INTEL_MAX_LINKS; i++) + intel_ctx->sdw_pin_index[i] = SOC_SDW_INTEL_BIDIR_PDI_BASE; - /* skip itself */ - if (i == index_in_link) - continue; + /* generate DAI links by each sdw link */ + while (sof_dais->initialised) { + int current_be_id = 0; - adr = adr_link->adr_d[i].adr; + ret = create_sdw_dailink(card, sof_dais, dai_links, + ¤t_be_id, codec_conf); + if (ret) + return ret; - sdw1_version = SDW_VERSION(adr); - mfg1_id = SDW_MFG_ID(adr); - part1_id = SDW_PART_ID(adr); - class1_id = SDW_CLASS_ID(adr); + /* Update the be_id to match the highest ID used for SDW link */ + if (*be_id < current_be_id) + *be_id = current_be_id; - if (sdw_version == sdw1_version && - mfg_id == mfg1_id && - part_id == part1_id && - class_id == class1_id) - return false; + sof_dais++; } - return true; -} - -static int fill_sdw_codec_dlc(struct device *dev, - const struct snd_soc_acpi_link_adr *adr_link, - struct snd_soc_dai_link_component *codec, - int adr_index, int dai_index) -{ - unsigned int sdw_version, unique_id, mfg_id, link_id, part_id, class_id; - u64 adr = adr_link->adr_d[adr_index].adr; - int codec_index; - - codec_index = find_codec_info_part(adr); - if (codec_index < 0) - return codec_index; - - sdw_version = SDW_VERSION(adr); - link_id = SDW_DISCO_LINK_ID(adr); - unique_id = SDW_UNIQUE_ID(adr); - mfg_id = SDW_MFG_ID(adr); - part_id = SDW_PART_ID(adr); - class_id = SDW_CLASS_ID(adr); - - if (codec_info_list[codec_index].codec_name) - codec->name = devm_kstrdup(dev, - codec_info_list[codec_index].codec_name, - GFP_KERNEL); - else if (is_unique_device(adr_link, sdw_version, mfg_id, part_id, - class_id, adr_index)) - codec->name = devm_kasprintf(dev, GFP_KERNEL, - "sdw:0:%01x:%04x:%04x:%02x", link_id, - mfg_id, part_id, class_id); - else - codec->name = devm_kasprintf(dev, GFP_KERNEL, - "sdw:0:%01x:%04x:%04x:%02x:%01x", link_id, - mfg_id, part_id, class_id, unique_id); - - if (!codec->name) - return -ENOMEM; - - codec->dai_name = codec_info_list[codec_index].dais[dai_index].dai_name; - return 0; } -static int set_codec_init_func(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *adr_link, - struct snd_soc_dai_link *dai_links, - bool playback, int group_id, int adr_index, int dai_index) +static int create_ssp_dailinks(struct snd_soc_card *card, + struct snd_soc_dai_link **dai_links, int *be_id, + struct asoc_sdw_codec_info *ssp_info, + unsigned long ssp_mask) { - int i = adr_index; + struct device *dev = card->dev; + int i, j = 0; + int ret; - do { - /* - * Initialize the codec. If codec is part of an aggregated - * group (group_id>0), initialize all codecs belonging to - * same group. - * The first link should start with adr_link->adr_d[adr_index] - * because that is the device that we want to initialize and - * we should end immediately if it is not aggregated (group_id=0) - */ - for ( ; i < adr_link->num_adr; i++) { - int codec_index; + for_each_set_bit(i, &ssp_mask, BITS_PER_TYPE(ssp_mask)) { + char *name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", i); + char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i); + char *codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d", + ssp_info->acpi_id, j++); + if (!name || !cpu_dai_name || !codec_name) + return -ENOMEM; - codec_index = find_codec_info_part(adr_link->adr_d[i].adr); - if (codec_index < 0) - return codec_index; + int playback = ssp_info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK]; + int capture = ssp_info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE]; - /* The group_id is > 0 iff the codec is aggregated */ - if (adr_link->adr_d[i].endpoints->group_id != group_id) - continue; + ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name, + playback, capture, cpu_dai_name, + "dummy", codec_name, + ssp_info->dais[0].dai_name, 1, NULL, + ssp_info->ops); + if (ret) + return ret; - if (codec_info_list[codec_index].dais[dai_index].init) - codec_info_list[codec_index].dais[dai_index].init(card, - adr_link, - dai_links, - &codec_info_list[codec_index], - playback); - if (!group_id) - return 0; - } + ret = ssp_info->dais[0].init(card, *dai_links, ssp_info, 0); + if (ret < 0) + return ret; - i = 0; - adr_link++; - } while (adr_link->mask); + (*dai_links)++; + } return 0; } -/* - * check endpoint status in slaves and gather link ID for all slaves in - * the same group to generate different CPU DAI. Now only support - * one sdw link with all slaves set with only single group id. - * - * one slave on one sdw link with aggregated = 0 - * one sdw BE DAI <---> one-cpu DAI <---> one-codec DAI - * - * two or more slaves on one sdw link with aggregated = 0 - * one sdw BE DAI <---> one-cpu DAI <---> multi-codec DAIs - * - * multiple links with multiple slaves with aggregated = 1 - * one sdw BE DAI <---> 1 .. N CPU DAIs <----> 1 .. N codec DAIs - */ -static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link, - struct device *dev, int *cpu_dai_id, int *cpu_dai_num, - int *codec_num, unsigned int *group_id, - int adr_index) +static int create_dmic_dailinks(struct snd_soc_card *card, + struct snd_soc_dai_link **dai_links, int *be_id) { - bool no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; - int i; - - if (!adr_link->adr_d[adr_index].endpoints->aggregated || no_aggregation) { - cpu_dai_id[0] = ffs(adr_link->mask) - 1; - *cpu_dai_num = 1; - *codec_num = 1; - *group_id = 0; - return 0; - } - - *codec_num = 0; - *cpu_dai_num = 0; - *group_id = adr_link->adr_d[adr_index].endpoints->group_id; - - /* Count endpoints with the same group_id in the adr_link */ - for (; adr_link && adr_link->num_adr; adr_link++) { - unsigned int link_codecs = 0; + struct device *dev = card->dev; + int ret; - for (i = 0; i < adr_link->num_adr; i++) { - if (adr_link->adr_d[i].endpoints->aggregated && - adr_link->adr_d[i].endpoints->group_id == *group_id) - link_codecs++; - } + ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, "dmic01", + 0, 1, // DMIC only supports capture + "DMIC01 Pin", "dummy", + "dmic-codec", "dmic-hifi", 1, + asoc_sdw_dmic_init, NULL); + if (ret) + return ret; - if (link_codecs) { - *codec_num += link_codecs; + (*dai_links)++; - if (*cpu_dai_num >= SDW_MAX_CPU_DAIS) { - dev_err(dev, "cpu_dai_id array overflowed\n"); - return -EINVAL; - } + ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, "dmic16k", + 0, 1, // DMIC only supports capture + "DMIC16k Pin", "dummy", + "dmic-codec", "dmic-hifi", 1, + /* don't call asoc_sdw_dmic_init() twice */ + NULL, NULL); + if (ret) + return ret; - cpu_dai_id[(*cpu_dai_num)++] = ffs(adr_link->mask) - 1; - } - } + (*dai_links)++; return 0; } -static void set_dailink_map(struct snd_soc_dai_link_ch_map *sdw_codec_ch_maps, - int codec_num, int cpu_num) +static int create_hdmi_dailinks(struct snd_soc_card *card, + struct snd_soc_dai_link **dai_links, int *be_id, + int hdmi_num) { - int step; - int i; + struct device *dev = card->dev; + struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); + struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private; + int i, ret; - step = codec_num / cpu_num; - for (i = 0; i < codec_num; i++) { - sdw_codec_ch_maps[i].cpu = i / step; - sdw_codec_ch_maps[i].codec = i; - } -} + for (i = 0; i < hdmi_num; i++) { + char *name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", i + 1); + char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", i + 1); + if (!name || !cpu_dai_name) + return -ENOMEM; -static inline int find_codec_info_dai(const char *dai_name, int *dai_index) -{ - int i, j; + char *codec_name, *codec_dai_name; - for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { - for (j = 0; j < codec_info_list[i].dai_num; j++) { - if (!strcmp(codec_info_list[i].dais[j].dai_name, dai_name)) { - *dai_index = j; - return i; - } + if (intel_ctx->hdmi.idisp_codec) { + codec_name = "ehdaudio0D2"; + codec_dai_name = devm_kasprintf(dev, GFP_KERNEL, + "intel-hdmi-hifi%d", i + 1); + } else { + codec_name = "snd-soc-dummy"; + codec_dai_name = "snd-soc-dummy-dai"; } - } - return -EINVAL; -} - -static int sof_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd) -{ - struct sof_sdw_codec_info *codec_info; - struct snd_soc_dai *dai; - int codec_index; - int dai_index; - int ret; - int i; + if (!codec_dai_name) + return -ENOMEM; - for_each_rtd_codec_dais(rtd, i, dai) { - codec_index = find_codec_info_dai(dai->name, &dai_index); - if (codec_index < 0) - return -EINVAL; + ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name, + 1, 0, // HDMI only supports playback + cpu_dai_name, "dummy", + codec_name, codec_dai_name, 1, + i == 0 ? sof_sdw_hdmi_init : NULL, NULL); + if (ret) + return ret; - codec_info = &codec_info_list[codec_index]; - /* - * A codec dai can be connected to different dai links for capture and playback, - * but we only need to call the rtd_init function once. - * The rtd_init for each codec dai is independent. So, the order of rtd_init - * doesn't matter. - */ - if (codec_info->dais[dai_index].rtd_init_done) - continue; - if (codec_info->dais[dai_index].rtd_init) { - ret = codec_info->dais[dai_index].rtd_init(rtd); - if (ret) - return ret; - } - codec_info->dais[dai_index].rtd_init_done = true; + (*dai_links)++; } return 0; } -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, - const struct snd_soc_acpi_link_adr *adr_link, - struct snd_soc_codec_conf *codec_conf, - int codec_count, int *be_id, - int *codec_conf_index, - bool *ignore_pch_dmic, - bool append_dai_type, - int adr_index, - int dai_index) +static int create_bt_dailinks(struct snd_soc_card *card, + struct snd_soc_dai_link **dai_links, int *be_id) { - 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; - unsigned int group_id; - int codec_dlc_index = 0; - int codec_index; - int codec_num; - int stream; - int i = 0; - int j, k; + int port = (sof_sdw_quirk & SOF_BT_OFFLOAD_SSP_MASK) >> + SOF_BT_OFFLOAD_SSP_SHIFT; + char *name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); + char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port); + if (!name || !cpu_dai_name) + return -ENOMEM; + int ret; - ret = get_slave_info(adr_link, dev, cpu_dai_id, &cpu_dai_num, &codec_num, - &group_id, adr_index); + ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name, + 1, 1, cpu_dai_name, "dummy", + snd_soc_dummy_dlc.name, snd_soc_dummy_dlc.dai_name, + 1, NULL, NULL); if (ret) return ret; - codecs = devm_kcalloc(dev, codec_num, sizeof(*codecs), GFP_KERNEL); - if (!codecs) - return -ENOMEM; - - /* generate codec name on different links in the same group */ - j = adr_index; - for (adr_link_next = adr_link; adr_link_next && adr_link_next->num_adr && - i < cpu_dai_num; adr_link_next++) { - /* skip the link excluded by this processed group */ - if (cpu_dai_id[i] != ffs(adr_link_next->mask) - 1) - continue; - - /* j reset after loop, adr_index only applies to first link */ - for (; j < adr_link_next->num_adr && codec_dlc_index < codec_num; j++) { - const struct snd_soc_acpi_endpoint *endpoints; - - endpoints = adr_link_next->adr_d[j].endpoints; - - if (group_id && (!endpoints->aggregated || - endpoints->group_id != group_id)) - continue; - - /* sanity check */ - if (*codec_conf_index >= codec_count) { - dev_err(dev, "codec_conf array overflowed\n"); - return -EINVAL; - } - - ret = fill_sdw_codec_dlc(dev, adr_link_next, - &codecs[codec_dlc_index], - j, dai_index); - if (ret) - return ret; - - codec_conf[*codec_conf_index].dlc = codecs[codec_dlc_index]; - codec_conf[*codec_conf_index].name_prefix = - adr_link_next->adr_d[j].name_prefix; - - codec_dlc_index++; - (*codec_conf_index)++; - } - j = 0; - - /* check next link to create codec dai in the processed group */ - i++; - } - - /* find codec info to create BE DAI */ - codec_index = find_codec_info_part(adr_link->adr_d[adr_index].adr); - if (codec_index < 0) - return codec_index; - codec_info = &codec_info_list[codec_index]; - - if (codec_info->ignore_pch_dmic) - *ignore_pch_dmic = true; - - for_each_pcm_streams(stream) { - struct snd_soc_dai_link_ch_map *sdw_codec_ch_maps; - char *name, *cpu_name; - int playback, capture; - static const char * const sdw_stream_name[] = { - "SDW%d-Playback", - "SDW%d-Capture", - "SDW%d-Playback-%s", - "SDW%d-Capture-%s", - }; - - if (!codec_info->dais[dai_index].direction[stream]) - continue; - - *be_id = codec_info->dais[dai_index].dailink[stream]; - if (*be_id < 0) { - dev_err(dev, "Invalid dailink id %d\n", *be_id); - return -EINVAL; - } - - sdw_codec_ch_maps = devm_kcalloc(dev, codec_num, - sizeof(*sdw_codec_ch_maps), GFP_KERNEL); - if (!sdw_codec_ch_maps) - return -ENOMEM; - - /* create stream name according to first link id */ - if (append_dai_type) { - name = devm_kasprintf(dev, GFP_KERNEL, - sdw_stream_name[stream + 2], cpu_dai_id[0], - type_strings[codec_info->dais[dai_index].dai_type]); - } else { - name = devm_kasprintf(dev, GFP_KERNEL, - sdw_stream_name[stream], cpu_dai_id[0]); - } - 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. - */ - for (k = 0; k < cpu_dai_num; k++) { - cpu_name = devm_kasprintf(dev, GFP_KERNEL, - "SDW%d Pin%d", cpu_dai_id[k], - ctx->sdw_pin_index[cpu_dai_id[k]]++); - if (!cpu_name) - return -ENOMEM; - - cpus[k].dai_name = cpu_name; - } - - /* - * We create sdw dai links at first stage, so link index should - * not be larger than sdw_be_num - */ - if (*link_index >= sdw_be_num) { - dev_err(dev, "invalid dai link index %d\n", *link_index); - 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_dai_num, codecs, codec_num, - sof_sdw_rtd_init, &sdw_ops); - - /* - * SoundWire DAILINKs use 'stream' functions and Bank Switch operations - * based on wait_for_completion(), tag them as 'nonatomic'. - */ - dai_links[*link_index].nonatomic = true; - - set_dailink_map(sdw_codec_ch_maps, codec_num, cpu_dai_num); - dai_links[*link_index].ch_maps = sdw_codec_ch_maps; - ret = set_codec_init_func(card, adr_link, dai_links + (*link_index)++, - playback, group_id, adr_index, dai_index); - if (ret < 0) { - dev_err(dev, "failed to init codec %d\n", codec_index); - return ret; - } - } + (*dai_links)++; return 0; } @@ -1644,46 +1128,64 @@ 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, bt_num = 0; - struct mc_private *ctx = snd_soc_card_get_drvdata(card); + struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); + struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private; 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_codec_conf *codec_conf; - bool append_dai_type = false; - bool ignore_pch_dmic = false; - int codec_conf_num = 0; - int codec_conf_index = 0; - bool group_generated[SDW_MAX_GROUPS] = { }; - int ssp_codec_index, ssp_mask; + struct asoc_sdw_codec_info *ssp_info; + struct asoc_sdw_endpoint *sof_ends; + struct asoc_sdw_dailink *sof_dais; + int num_devs = 0; + int num_ends = 0; struct snd_soc_dai_link *dai_links; - int num_links, link_index = 0; - char *name, *cpu_dai_name; - char *codec_name, *codec_dai_name; - int i, j, be_id = 0; - int codec_index; + int num_links; + int be_id = 0; int hdmi_num; + unsigned long ssp_mask; int ret; - ret = get_dailink_info(dev, adr_link, &sdw_be_num, &codec_conf_num); + ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends); if (ret < 0) { - dev_err(dev, "failed to get sdw link info %d\n", ret); + dev_err(dev, "failed to count devices/endpoints: %d\n", ret); return ret; } /* + * One per DAI link, worst case is a DAI link for every endpoint, also + * add one additional to act as a terminator such that code can iterate + * until it hits an uninitialised DAI. + */ + sof_dais = kcalloc(num_ends + 1, sizeof(*sof_dais), GFP_KERNEL); + if (!sof_dais) + return -ENOMEM; + + /* One per endpoint, ie. each DAI on each codec/amp */ + sof_ends = kcalloc(num_ends, sizeof(*sof_ends), GFP_KERNEL); + if (!sof_ends) { + ret = -ENOMEM; + goto err_dai; + } + + ret = asoc_sdw_parse_sdw_endpoints(card, sof_dais, sof_ends, &num_devs); + if (ret < 0) + goto err_end; + + sdw_be_num = ret; + + /* * on generic tgl platform, I2S or sdw mode is supported * based on board rework. A ACPI device is registered in * system only when I2S mode is supported, not sdw mode. * Here check ACPI ID to confirm I2S is supported. */ - ssp_codec_index = find_codec_info_acpi(mach->id); - if (ssp_codec_index >= 0) { + ssp_info = asoc_sdw_find_codec_info_acpi(mach->id); + if (ssp_info) { ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk); ssp_num = hweight_long(ssp_mask); } if (mach_params->codec_mask & IDISP_CODEC_MASK) - ctx->hdmi.idisp_codec = true; + intel_ctx->hdmi.idisp_codec = true; if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) hdmi_num = SOF_TGL_HDMI_COUNT; @@ -1691,313 +1193,144 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) hdmi_num = SOF_PRE_TGL_HDMI_COUNT; /* enable dmic01 & dmic16k */ - if (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) + if (ctx->ignore_internal_dmic) { + dev_dbg(dev, "SoundWire DMIC is used, ignoring internal DMIC\n"); + mach_params->dmic_num = 0; + } else if (mach_params->dmic_num) { + dmic_num = 2; + } else if (sof_sdw_quirk & SOC_SDW_PCH_DMIC) { dmic_num = 2; + /* + * mach_params->dmic_num will be used to set the cfg-mics value of + * card->components string. Set it to the default value. + */ + mach_params->dmic_num = DMIC_DEFAULT_CHANNELS; + } if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) bt_num = 1; - dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d, bt: %d\n", + dev_dbg(dev, "DAI link numbers: sdw %d, ssp %d, dmic %d, hdmi %d, bt: %d\n", sdw_be_num, ssp_num, dmic_num, - ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num); + intel_ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num); + + codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL); + if (!codec_conf) { + ret = -ENOMEM; + goto err_end; + } /* allocate BE dailinks */ num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num; dai_links = devm_kcalloc(dev, num_links, sizeof(*dai_links), GFP_KERNEL); - if (!dai_links) - 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); - if (!codec_conf) - return -ENOMEM; - - /* SDW */ - if (!sdw_be_num) - goto SSP; - - for (i = 0; i < SDW_MAX_LINKS; i++) - ctx->sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE; - - for (; adr_link->num_adr; adr_link++) { - /* - * If there are two or more different devices on the same sdw link, we have to - * append the codec type to the dai link name to prevent duplicated dai link name. - * The same type devices on the same sdw link will be in the same - * snd_soc_acpi_adr_device array. They won't be described in different adr_links. - */ - for (i = 0; i < adr_link->num_adr; i++) { - /* find codec info to get dai_num */ - codec_index = find_codec_info_part(adr_link->adr_d[i].adr); - if (codec_index < 0) - return codec_index; - if (codec_info_list[codec_index].dai_num > 1) { - append_dai_type = true; - goto out; - } - for (j = 0; j < i; j++) { - if ((SDW_PART_ID(adr_link->adr_d[i].adr) != - SDW_PART_ID(adr_link->adr_d[j].adr)) || - (SDW_MFG_ID(adr_link->adr_d[i].adr) != - SDW_MFG_ID(adr_link->adr_d[j].adr))) { - append_dai_type = true; - goto out; - } - } - } + if (!dai_links) { + ret = -ENOMEM; + goto err_end; } -out: - /* generate DAI links by each sdw link */ - for (adr_link = mach_params->links ; adr_link->num_adr; adr_link++) { - for (i = 0; i < adr_link->num_adr; i++) { - const struct snd_soc_acpi_endpoint *endpoint; - - endpoint = adr_link->adr_d[i].endpoints; - - /* this group has been generated */ - if (endpoint->aggregated && - group_generated[endpoint->group_id]) - continue; - - /* find codec info to get dai_num */ - codec_index = find_codec_info_part(adr_link->adr_d[i].adr); - if (codec_index < 0) - return codec_index; - - for (j = 0; j < codec_info_list[codec_index].dai_num ; j++) { - int current_be_id; - - ret = create_sdw_dailink(card, &link_index, dai_links, - sdw_be_num, adr_link, - codec_conf, codec_conf_num, - ¤t_be_id, &codec_conf_index, - &ignore_pch_dmic, append_dai_type, i, j); - if (ret < 0) { - dev_err(dev, "failed to create dai link %d\n", link_index); - return ret; - } - - /* Update the be_id to match the highest ID used for SDW link */ - if (be_id < current_be_id) - be_id = current_be_id; - } + card->codec_conf = codec_conf; + card->num_configs = num_devs; + card->dai_link = dai_links; + card->num_links = num_links; - if (aggregation && endpoint->aggregated) - group_generated[endpoint->group_id] = true; - } + /* SDW */ + if (sdw_be_num) { + ret = create_sdw_dailinks(card, &dai_links, &be_id, + sof_dais, &codec_conf); + if (ret) + goto err_end; } -SSP: /* SSP */ - if (!ssp_num) - goto DMIC; - - for (i = 0, j = 0; ssp_mask; i++, ssp_mask >>= 1) { - struct sof_sdw_codec_info *info; - int playback, capture; - - if (!(ssp_mask & 0x1)) - continue; - - 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++); - - playback = info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK]; - capture = info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE]; - - 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 (ssp_num) { + ret = create_ssp_dailinks(card, &dai_links, &be_id, + ssp_info, ssp_mask); if (ret) - return ret; - - ret = info->dais[0].init(card, NULL, dai_links + link_index, info, 0); - if (ret < 0) - return ret; - - link_index++; + goto err_end; } -DMIC: /* dmic */ - if (dmic_num > 0) { - if (ignore_pch_dmic) { - dev_warn(dev, "Ignoring PCH DMIC\n"); - goto HDMI; - } - - 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 (dmic_num) { + ret = create_dmic_dailinks(card, &dai_links, &be_id); 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++; + goto err_end; } -HDMI: /* HDMI */ - for (i = 0; i < hdmi_num; i++) { - 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->hdmi.idisp_codec) { - codec_name = "ehdaudio0D2"; - codec_dai_name = devm_kasprintf(dev, GFP_KERNEL, - "intel-hdmi-hifi%d", i + 1); - } else { - codec_name = "snd-soc-dummy"; - codec_dai_name = "snd-soc-dummy-dai"; - } - - 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; - - link_index++; - } + ret = create_hdmi_dailinks(card, &dai_links, &be_id, hdmi_num); + if (ret) + goto err_end; + /* BT */ if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) { - int port = (sof_sdw_quirk & SOF_BT_OFFLOAD_SSP_MASK) >> - SOF_BT_OFFLOAD_SSP_SHIFT; - - name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); - cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port); - - 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); + ret = create_bt_dailinks(card, &dai_links, &be_id); if (ret) - return ret; + goto err_end; } - card->dai_link = dai_links; - card->num_links = num_links; + WARN_ON(codec_conf != card->codec_conf + card->num_configs); + WARN_ON(dai_links != card->dai_link + card->num_links); - card->codec_conf = codec_conf; - card->num_configs = codec_conf_num; +err_end: + kfree(sof_ends); +err_dai: + kfree(sof_dais); - return 0; + return ret; } static int sof_sdw_card_late_probe(struct snd_soc_card *card) { - struct mc_private *ctx = snd_soc_card_get_drvdata(card); + struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); + struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private; int ret = 0; - int i; - - for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { - if (codec_info_list[i].codec_card_late_probe) { - ret = codec_info_list[i].codec_card_late_probe(card); - if (ret < 0) - return ret; - } - } + ret = asoc_sdw_card_late_probe(card); + if (ret < 0) + return ret; - if (ctx->hdmi.idisp_codec) + if (intel_ctx->hdmi.idisp_codec) ret = sof_sdw_hdmi_card_late_probe(card); return ret; } -/* SoC card */ -static const char sdw_card_long_name[] = "Intel Soundwire SOF"; - -static struct snd_soc_card card_sof_sdw = { - .name = "soundwire", - .owner = THIS_MODULE, - .late_probe = sof_sdw_card_late_probe, -}; - -/* helper to get the link that the codec DAI is used */ -static struct snd_soc_dai_link *mc_find_codec_dai_used(struct snd_soc_card *card, - const char *dai_name) -{ - struct snd_soc_dai_link *dai_link; - int i; - int j; - - for_each_card_prelinks(card, i, dai_link) { - for (j = 0; j < dai_link->num_codecs; j++) { - /* Check each codec in a link */ - if (!strcmp(dai_link->codecs[j].dai_name, dai_name)) - return dai_link; - } - } - return NULL; -} - -static void mc_dailink_exit_loop(struct snd_soc_card *card) -{ - struct snd_soc_dai_link *dai_link; - int ret; - int i, j; - - for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { - for (j = 0; j < codec_info_list[i].dai_num; j++) { - codec_info_list[i].dais[j].rtd_init_done = false; - /* Check each dai in codec_info_lis to see if it is used in the link */ - if (!codec_info_list[i].dais[j].exit) - continue; - /* - * We don't need to call .exit function if there is no matched - * dai link found. - */ - dai_link = mc_find_codec_dai_used(card, - codec_info_list[i].dais[j].dai_name); - if (dai_link) { - /* Do the .exit function if the codec dai is used in the link */ - ret = codec_info_list[i].dais[j].exit(card, dai_link); - if (ret) - dev_warn(card->dev, - "codec exit failed %d\n", - ret); - break; - } - } - } -} - static int mc_probe(struct platform_device *pdev) { - struct snd_soc_card *card = &card_sof_sdw; struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev); - struct mc_private *ctx; + struct snd_soc_card *card; + struct asoc_sdw_mc_private *ctx; + struct intel_mc_ctx *intel_ctx; int amp_num = 0, i; int ret; - card->dev = &pdev->dev; + dev_dbg(&pdev->dev, "Entry\n"); - dev_dbg(card->dev, "Entry\n"); + intel_ctx = devm_kzalloc(&pdev->dev, sizeof(*intel_ctx), GFP_KERNEL); + if (!intel_ctx) + return -ENOMEM; - ctx = devm_kzalloc(card->dev, sizeof(*ctx), GFP_KERNEL); + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; + ctx->private = intel_ctx; + ctx->codec_info_list_count = asoc_sdw_get_codec_info_list_count(); + card = &ctx->card; + card->dev = &pdev->dev; + card->name = "soundwire"; + card->owner = THIS_MODULE; + card->late_probe = sof_sdw_card_late_probe; + snd_soc_card_set_drvdata(card, ctx); + if (mach->mach_params.subsystem_id_set) { + snd_soc_card_set_pci_ssid(card, + mach->mach_params.subsystem_vendor, + mach->mach_params.subsystem_device); + sof_sdw_check_ssid_quirk(mach); + } + dmi_check_system(sof_sdw_quirk_table); if (quirk_override != -1) { @@ -2008,16 +1341,11 @@ static int mc_probe(struct platform_device *pdev) log_quirks(card->dev); + ctx->mc_quirk = sof_sdw_quirk; /* reset amp_num to ensure amp_num++ starts from 0 in each probe */ - for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) + for (i = 0; i < ctx->codec_info_list_count; i++) codec_info_list[i].amp_num = 0; - if (mach->mach_params.subsystem_id_set) { - snd_soc_card_set_pci_ssid(card, - mach->mach_params.subsystem_vendor, - mach->mach_params.subsystem_device); - } - ret = sof_card_dai_links_create(card); if (ret < 0) return ret; @@ -2027,13 +1355,11 @@ static int mc_probe(struct platform_device *pdev) * amp_num will only be increased for active amp * codecs on used platform */ - for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) + for (i = 0; i < ctx->codec_info_list_count; i++) amp_num += codec_info_list[i].amp_num; card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "cfg-spk:%d cfg-amp:%d", - (sof_sdw_quirk & SOF_SDW_FOUR_SPK) - ? 4 : 2, amp_num); + " cfg-amp:%d", amp_num); if (!card->components) return -ENOMEM; @@ -2046,13 +1372,11 @@ static int mc_probe(struct platform_device *pdev) return -ENOMEM; } - card->long_name = sdw_card_long_name; - /* Register the card */ ret = devm_snd_soc_register_card(card->dev, card); if (ret) { dev_err_probe(card->dev, ret, "snd_soc_register_card failed %d\n", ret); - mc_dailink_exit_loop(card); + asoc_sdw_mc_dailink_exit_loop(card); return ret; } @@ -2065,7 +1389,7 @@ static void mc_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - mc_dailink_exit_loop(card); + asoc_sdw_mc_dailink_exit_loop(card); } static const struct platform_device_id mc_id_table[] = { @@ -2080,7 +1404,7 @@ static struct platform_driver sof_sdw_driver = { .pm = &snd_soc_pm_ops, }, .probe = mc_probe, - .remove_new = mc_remove, + .remove = mc_remove, .id_table = mc_id_table, }; @@ -2091,5 +1415,5 @@ MODULE_AUTHOR("Bard Liao <yung-chuan.liao@linux.intel.com>"); MODULE_AUTHOR("Rander Wang <rander.wang@linux.intel.com>"); MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.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_HDA_DSP_COMMON"); +MODULE_IMPORT_NS("SND_SOC_SDW_UTILS"); diff --git a/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h b/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h deleted file mode 100644 index 4a3e6fdbd623..000000000000 --- a/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h +++ /dev/null @@ -1,300 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only - */ - -/* - * sof_sdw_amp_coeff_tables.h - related coefficients for amplifier parameters - */ - -#ifndef SND_SOC_SOF_SDW_AMP_COEFF_H -#define SND_SOC_SOF_SDW_AMP_COEFF_H - -#define RT1308_MAX_BQ_REG 480 -#define RT1316_MAX_BQ_REG 580 - -static const u8 __maybe_unused dell_0a5d_bq_params[] = { - 0xb0, 0xc5, 0x00, /* address: 0xc5b0; data: 0x00 */ - 0xb1, 0xc5, 0x32, - 0xb2, 0xc5, 0x44, - 0xb3, 0xc5, 0x19, - 0xc0, 0xc5, 0x04, - 0xc1, 0xc5, 0x00, - 0xc2, 0xc5, 0x00, - 0xc3, 0xc5, 0x00, - 0xd0, 0xc5, 0x02, - 0xd1, 0xc5, 0x00, - 0xd2, 0xc5, 0x00, - 0xd3, 0xc5, 0x00, - 0xe0, 0xc5, 0x01, - 0xe1, 0xc5, 0xe8, - 0xe2, 0xc5, 0x5f, - 0xe3, 0xc5, 0x8a, - 0xf0, 0xc5, 0x1f, - 0xf1, 0xc5, 0x4e, - 0xf2, 0xc5, 0x90, - 0xf3, 0xc5, 0x11, - 0x50, 0xc6, 0x01, - 0x51, 0xc6, 0xff, - 0x52, 0xc6, 0x45, - 0x53, 0xc6, 0x41, - 0x60, 0xc6, 0x1c, - 0x61, 0xc6, 0x00, - 0x62, 0xc6, 0x00, - 0x63, 0xc6, 0x00, - 0x70, 0xc6, 0x02, - 0x71, 0xc6, 0x00, - 0x72, 0xc6, 0x00, - 0x73, 0xc6, 0x00, - 0x80, 0xc6, 0x03, - 0x81, 0xc6, 0xfe, - 0x82, 0xc6, 0x89, - 0x83, 0xc6, 0xfa, - 0x90, 0xc6, 0x1e, - 0x91, 0xc6, 0x01, - 0x92, 0xc6, 0x74, - 0x93, 0xc6, 0xf6, - 0x00, 0xc6, 0x01, - 0x01, 0xc6, 0xd9, - 0x02, 0xc6, 0xfb, - 0x03, 0xc6, 0xc4, - 0x10, 0xc6, 0x1c, - 0x11, 0xc6, 0x00, - 0x12, 0xc6, 0x00, - 0x13, 0xc6, 0x00, - 0x20, 0xc6, 0x02, - 0x21, 0xc6, 0x00, - 0x22, 0xc6, 0x00, - 0x23, 0xc6, 0x00, - 0x30, 0xc6, 0x03, - 0x31, 0xc6, 0xaf, - 0x32, 0xc6, 0x23, - 0x33, 0xc6, 0xcb, - 0x40, 0xc6, 0x1e, - 0x41, 0xc6, 0x47, - 0x42, 0xc6, 0x34, - 0x43, 0xc6, 0xba, - 0xa0, 0xc6, 0x01, - 0xa1, 0xc6, 0xff, - 0xa2, 0xc6, 0x45, - 0xa3, 0xc6, 0x41, - 0xb0, 0xc6, 0x1c, - 0xb1, 0xc6, 0x00, - 0xb2, 0xc6, 0x00, - 0xb3, 0xc6, 0x00, - 0xc0, 0xc6, 0x02, - 0xc1, 0xc6, 0x00, - 0xc2, 0xc6, 0x00, - 0xc3, 0xc6, 0x00, - 0xd0, 0xc6, 0x03, - 0xd1, 0xc6, 0xfe, - 0xd2, 0xc6, 0x89, - 0xd3, 0xc6, 0xfa, - 0xe0, 0xc6, 0x1e, - 0xe1, 0xc6, 0x01, - 0xe2, 0xc6, 0x74, - 0xe3, 0xc6, 0xf6, - 0x40, 0xc5, 0x0d, - 0x30, 0xc7, 0x15, - 0x31, 0xc7, 0x7c, - 0x32, 0xc7, 0x0f, - 0x33, 0xc7, 0xa0, - 0x40, 0xc7, 0x00, - 0x41, 0xc7, 0x00, - 0x42, 0xc7, 0xf8, - 0x43, 0xc7, 0xf8, - 0x50, 0xc7, 0x00, - 0x51, 0xc7, 0x00, - 0x52, 0xc7, 0x00, - 0x53, 0xc7, 0x01, - 0x90, 0xc7, 0x00, - 0x91, 0xc7, 0x14, - 0x92, 0xc7, 0x00, - 0x93, 0xc7, 0x14, - 0xa0, 0xc7, 0x00, - 0xa1, 0xc7, 0x00, - 0xa2, 0xc7, 0xf8, - 0xa3, 0xc7, 0xf8, - 0xb0, 0xc7, 0x00, - 0xb1, 0xc7, 0x00, - 0xb2, 0xc7, 0x00, - 0xb3, 0xc7, 0x00, - 0x60, 0xc7, 0x03, - 0x61, 0xc7, 0xe8, - 0x62, 0xc7, 0x03, - 0x63, 0xc7, 0xb6, - 0x70, 0xc7, 0x00, - 0x71, 0xc7, 0x00, - 0x72, 0xc7, 0xf8, - 0x73, 0xc7, 0xf8, - 0x80, 0xc7, 0x00, - 0x81, 0xc7, 0x00, - 0x82, 0xc7, 0x00, - 0x83, 0xc7, 0x00, - 0xc0, 0xc7, 0x00, - 0xc1, 0xc7, 0x14, - 0xc2, 0xc7, 0x00, - 0xc3, 0xc7, 0x14, - 0xd0, 0xc7, 0x00, - 0xd1, 0xc7, 0x00, - 0xd2, 0xc7, 0xf8, - 0xd3, 0xc7, 0xf8, - 0xe0, 0xc7, 0x00, - 0xe1, 0xc7, 0x00, - 0xe2, 0xc7, 0x00, - 0xe3, 0xc7, 0x00, - 0x60, 0xc5, 0x02, - 0x61, 0xc5, 0x00, - 0x62, 0xc5, 0x00, - 0x63, 0xc5, 0x00, - 0x70, 0xc5, 0x02, - 0x71, 0xc5, 0x00, - 0x72, 0xc5, 0x00, - 0x73, 0xc5, 0x00, - 0x80, 0xc5, 0x02, - 0x81, 0xc5, 0x00, - 0x82, 0xc5, 0x00, - 0x83, 0xc5, 0x00, - 0x90, 0xc5, 0x02, - 0x91, 0xc5, 0x00, - 0x92, 0xc5, 0x00, - 0x93, 0xc5, 0x00, - 0x50, 0xc5, 0x01, -}; - -static const u8 __maybe_unused dell_0b00_bq_params[] = { - 0x03, 0xc2, 0x00, - 0x04, 0xc2, 0xb2, - 0x05, 0xc2, 0xe0, - 0x06, 0xc2, 0x3a, - 0x07, 0xc2, 0x01, - 0x08, 0xc2, 0x65, - 0x09, 0xc2, 0xc0, - 0x0a, 0xc2, 0x75, - 0x0b, 0xc2, 0x00, - 0x0c, 0xc2, 0xb2, - 0x0d, 0xc2, 0xe0, - 0x0e, 0xc2, 0x3a, - 0x0f, 0xc2, 0xf7, - 0x10, 0xc2, 0x4d, - 0x11, 0xc2, 0x5b, - 0x12, 0xc2, 0xe9, - 0x13, 0xc2, 0x03, - 0x14, 0xc2, 0x7e, - 0x15, 0xc2, 0x25, - 0x16, 0xc2, 0x01, - 0x17, 0xc2, 0x07, - 0x18, 0xc2, 0xfd, - 0x19, 0xc2, 0x15, - 0x1a, 0xc2, 0x04, - 0x1b, 0xc2, 0xf0, - 0x1c, 0xc2, 0x05, - 0x1d, 0xc2, 0xd5, - 0x1e, 0xc2, 0xf7, - 0x1f, 0xc2, 0x07, - 0x20, 0xc2, 0xfd, - 0x21, 0xc2, 0x15, - 0x22, 0xc2, 0x04, - 0x23, 0xc2, 0xf0, - 0x24, 0xc2, 0x05, - 0x25, 0xc2, 0xd8, - 0x26, 0xc2, 0x17, - 0x27, 0xc2, 0x07, - 0x28, 0xc2, 0xfa, - 0x29, 0xc2, 0x2c, - 0x2a, 0xc2, 0x29, - 0x2b, 0xc2, 0x07, - 0x2c, 0xc2, 0x74, - 0x2d, 0xc2, 0xe0, - 0x2e, 0xc2, 0x33, - 0x2f, 0xc2, 0xf1, - 0x30, 0xc2, 0x16, - 0x31, 0xc2, 0x3f, - 0x32, 0xc2, 0x9b, - 0x33, 0xc2, 0x07, - 0x34, 0xc2, 0x74, - 0x35, 0xc2, 0xe0, - 0x36, 0xc2, 0x33, - 0x37, 0xc2, 0xf1, - 0x38, 0xc2, 0x29, - 0x39, 0xc2, 0xb0, - 0x3a, 0xc2, 0x4d, - 0x3b, 0xc2, 0x06, - 0x3c, 0xc2, 0xfd, - 0x3d, 0xc2, 0x31, - 0x3e, 0xc2, 0x18, - 0x3f, 0xc2, 0x07, - 0x40, 0xc2, 0xfd, - 0x41, 0xc2, 0x15, - 0x42, 0xc2, 0x04, - 0x43, 0xc2, 0xf0, - 0x44, 0xc2, 0x05, - 0x45, 0xc2, 0xd5, - 0x46, 0xc2, 0xf7, - 0x47, 0xc2, 0x07, - 0x48, 0xc2, 0xfd, - 0x49, 0xc2, 0x15, - 0x4a, 0xc2, 0x04, - 0x4b, 0xc2, 0xf0, - 0x4c, 0xc2, 0x05, - 0x4d, 0xc2, 0xd8, - 0x4e, 0xc2, 0x17, - 0x4f, 0xc2, 0x07, - 0x50, 0xc2, 0xfa, - 0x51, 0xc2, 0x2c, - 0x52, 0xc2, 0x29, - 0x0b, 0xc0, 0x30, - 0x80, 0xc3, 0x13, - 0x81, 0xc3, 0x88, - 0x82, 0xc3, 0x17, - 0x83, 0xc3, 0x70, - 0x84, 0xc3, 0x00, - 0x85, 0xc3, 0x00, - 0x86, 0xc3, 0xff, - 0x87, 0xc3, 0xee, - 0x88, 0xc3, 0x02, - 0x92, 0xc3, 0x00, - 0x93, 0xc3, 0x14, - 0x94, 0xc3, 0x00, - 0x95, 0xc3, 0x14, - 0x96, 0xc3, 0x00, - 0x97, 0xc3, 0x00, - 0x98, 0xc3, 0x00, - 0x99, 0xc3, 0x00, - 0x9a, 0xc3, 0x01, - 0x89, 0xc3, 0x03, - 0x8a, 0xc3, 0xe8, - 0x8b, 0xc3, 0x03, - 0x8c, 0xc3, 0xb6, - 0x8d, 0xc3, 0x00, - 0x8e, 0xc3, 0x00, - 0x8f, 0xc3, 0xff, - 0x90, 0xc3, 0xee, - 0x91, 0xc3, 0x01, - 0x9b, 0xc3, 0x00, - 0x9c, 0xc3, 0x14, - 0x9d, 0xc3, 0x00, - 0x9e, 0xc3, 0x14, - 0x9f, 0xc3, 0x00, - 0xa0, 0xc3, 0x00, - 0xa1, 0xc3, 0x00, - 0xa2, 0xc3, 0x00, - 0xa3, 0xc3, 0x01, - 0x61, 0xc2, 0x08, - 0x62, 0xc2, 0x00, - 0x63, 0xc2, 0x00, - 0x64, 0xc2, 0x00, - 0x65, 0xc2, 0x08, - 0x66, 0xc2, 0x00, - 0x67, 0xc2, 0x00, - 0x68, 0xc2, 0x00, - 0x69, 0xc2, 0x08, - 0x6a, 0xc2, 0x00, - 0x6b, 0xc2, 0x00, - 0x6c, 0xc2, 0x00, - 0x6d, 0xc2, 0x08, - 0x6e, 0xc2, 0x00, - 0x6f, 0xc2, 0x00, - 0x70, 0xc2, 0x00, - 0x00, 0xc2, 0xc0, -}; - -#endif diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index b1d57034361c..3aa1dcec5172 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -12,20 +12,12 @@ #include <linux/bits.h> #include <linux/types.h> #include <sound/soc.h> +#include <sound/soc_sdw_utils.h> #include "sof_hdmi_common.h" -#define MAX_NO_PROPS 2 #define MAX_HDMI_NUM 4 -#define SDW_UNUSED_DAI_ID -1 -#define SDW_JACK_OUT_DAI_ID 0 -#define SDW_JACK_IN_DAI_ID 1 -#define SDW_AMP_OUT_DAI_ID 2 -#define SDW_AMP_IN_DAI_ID 3 -#define SDW_DMIC_DAI_ID 4 -#define SDW_MAX_CPU_DAIS 16 -#define SDW_INTEL_BIDIR_PDI_BASE 2 - -#define SDW_MAX_LINKS 4 +#define SOC_SDW_MAX_CPU_DAIS 16 +#define SOC_SDW_INTEL_BIDIR_PDI_BASE 2 /* 8 combinations with 4 links + unused group 0 */ #define SDW_MAX_GROUPS 9 @@ -44,13 +36,14 @@ enum { SOF_I2S_SSP5 = BIT(5), }; -#define SOF_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0)) -#define SOF_SDW_FOUR_SPK BIT(4) +/* Deprecated and no longer supported by the code */ +#define SOC_SDW_FOUR_SPK BIT(4) #define SOF_SDW_TGL_HDMI BIT(5) -#define SOF_SDW_PCH_DMIC BIT(6) +#define SOC_SDW_PCH_DMIC BIT(6) #define SOF_SSP_PORT(x) (((x) & GENMASK(5, 0)) << 7) #define SOF_SSP_GET_PORT(quirk) (((quirk) >> 7) & GENMASK(5, 0)) -#define SOF_SDW_NO_AGGREGATION BIT(14) +/* Deprecated and no longer supported by the code */ +#define SOC_SDW_NO_AGGREGATION BIT(14) /* BT audio offload: reserve 3 bits for future */ #define SOF_BT_OFFLOAD_SSP_SHIFT 15 @@ -59,138 +52,15 @@ enum { (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK) #define SOF_SSP_BT_OFFLOAD_PRESENT BIT(18) -#define SOF_SDW_DAI_TYPE_JACK 0 -#define SOF_SDW_DAI_TYPE_AMP 1 -#define SOF_SDW_DAI_TYPE_MIC 2 - -#define SOF_SDW_MAX_DAI_NUM 3 - -struct sof_sdw_codec_info; - -struct sof_sdw_dai_info { - const bool direction[2]; /* playback & capture support */ - const char *dai_name; - const int dai_type; - const int dailink[2]; /* dailink id for each direction */ - int (*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 (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); - int (*rtd_init)(struct snd_soc_pcm_runtime *rtd); - bool rtd_init_done; /* Indicate that the rtd_init callback is done */ -}; - -struct sof_sdw_codec_info { - const int part_id; - const int version_id; - const char *codec_name; - int amp_num; - const u8 acpi_id[ACPI_ID_LEN]; - const bool ignore_pch_dmic; - const struct snd_soc_ops *ops; - struct sof_sdw_dai_info dais[SOF_SDW_MAX_DAI_NUM]; - const int dai_num; - - int (*codec_card_late_probe)(struct snd_soc_card *card); -}; - -struct mc_private { - struct snd_soc_jack sdw_headset; +struct intel_mc_ctx { 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]; + unsigned int sdw_pin_index[SDW_INTEL_MAX_LINKS]; }; -extern unsigned long sof_sdw_quirk; - -int sdw_startup(struct snd_pcm_substream *substream); -int sdw_prepare(struct snd_pcm_substream *substream); -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); -int sdw_hw_free(struct snd_pcm_substream *substream); -void sdw_shutdown(struct snd_pcm_substream *substream); - /* generic HDMI support */ int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd); int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card); -/* DMIC support */ -int sof_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd); - -/* RT711 support */ -int sof_sdw_rt711_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_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); - -/* RT711-SDCA support */ -int sof_sdw_rt_sdca_jack_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_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); - -/* RT1308 I2S support */ -extern struct snd_soc_ops sof_sdw_rt1308_i2s_ops; - -/* generic amp support */ -int sof_sdw_rt_amp_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_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); - -/* RT722-SDCA support */ -int sof_sdw_rt722_spk_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_rt722_sdca_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); - -/* MAXIM codec support */ -int sof_sdw_maxim_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, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback); - -/* dai_link init callbacks */ - -int cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd); -int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd); -int cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd); -int cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd); -int maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd); -int rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd); -int rt700_rtd_init(struct snd_soc_pcm_runtime *rtd); -int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd); -int rt712_sdca_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd); -int rt712_spk_rtd_init(struct snd_soc_pcm_runtime *rtd); -int rt715_rtd_init(struct snd_soc_pcm_runtime *rtd); -int rt715_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd); -int rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd); -int rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd); - #endif diff --git a/sound/soc/intel/boards/sof_sdw_cs42l42.c b/sound/soc/intel/boards/sof_sdw_cs42l42.c deleted file mode 100644 index 0dc297f7de01..000000000000 --- a/sound/soc/intel/boards/sof_sdw_cs42l42.c +++ /dev/null @@ -1,124 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2023 Intel Corporation - -/* - * sof_sdw_cs42l42 - Helpers to handle CS42L42 from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/input.h> -#include <linux/soundwire/sdw.h> -#include <linux/soundwire/sdw_type.h> -#include <sound/control.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/soc-dapm.h> -#include <sound/jack.h> -#include "sof_board_helpers.h" -#include "sof_sdw_common.h" - -static const struct snd_soc_dapm_widget cs42l42_widgets[] = { - SND_SOC_DAPM_HP("Headphone", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), -}; - -static const struct snd_soc_dapm_route cs42l42_map[] = { - /* HP jack connectors - unknown if we have jack detection */ - {"Headphone", NULL, "cs42l42 HP"}, - - /* other jacks */ - {"cs42l42 HS", NULL, "Headset Mic"}, -}; - -static const struct snd_kcontrol_new cs42l42_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), -}; - -static struct snd_soc_jack_pin cs42l42_jack_pins[] = { - { - .pin = "Headphone", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, -}; - -static const char * const jack_codecs[] = { - "cs42l42" -}; - -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; - struct snd_soc_component *component; - struct snd_soc_jack *jack; - int ret; - - codec_dai = get_codec_dai_by_name(rtd, jack_codecs, ARRAY_SIZE(jack_codecs)); - if (!codec_dai) - return -EINVAL; - - component = codec_dai->component; - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s hs:cs42l42", - card->components); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, cs42l42_controls, - ARRAY_SIZE(cs42l42_controls)); - if (ret) { - dev_err(card->dev, "cs42l42 control addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, cs42l42_widgets, - ARRAY_SIZE(cs42l42_widgets)); - if (ret) { - dev_err(card->dev, "cs42l42 widgets addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, cs42l42_map, - ARRAY_SIZE(cs42l42_map)); - - if (ret) { - dev_err(card->dev, "cs42l42 map addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | - SND_JACK_BTN_1 | SND_JACK_BTN_2 | - SND_JACK_BTN_3, - &ctx->sdw_headset, - cs42l42_jack_pins, - ARRAY_SIZE(cs42l42_jack_pins)); - if (ret) { - dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n", - ret); - return ret; - } - - jack = &ctx->sdw_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); - - ret = snd_soc_component_set_jack(component, jack, NULL); - - if (ret) - dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n", - ret); - - return ret; -} -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); diff --git a/sound/soc/intel/boards/sof_sdw_cs42l43.c b/sound/soc/intel/boards/sof_sdw_cs42l43.c deleted file mode 100644 index a9b6edac2ecd..000000000000 --- a/sound/soc/intel/boards/sof_sdw_cs42l43.c +++ /dev/null @@ -1,135 +0,0 @@ -// 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, - }, -}; - -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 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; -} - diff --git a/sound/soc/intel/boards/sof_sdw_cs_amp.c b/sound/soc/intel/boards/sof_sdw_cs_amp.c deleted file mode 100644 index 56cf75bc6cc4..000000000000 --- a/sound/soc/intel/boards/sof_sdw_cs_amp.c +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2023 Intel Corporation - -/* - * sof_sdw_cs_amp - Helpers to handle CS35L56 from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/soc-dai.h> -#include "sof_sdw_common.h" - -#define CODEC_NAME_SIZE 8 - -static const struct snd_soc_dapm_widget sof_widgets[] = { - SND_SOC_DAPM_SPK("Speakers", NULL), -}; - -int cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd) -{ - const char *dai_name = rtd->dai_link->codecs->dai_name; - struct snd_soc_card *card = rtd->card; - char codec_name[CODEC_NAME_SIZE]; - char widget_name[16]; - struct snd_soc_dapm_route route = { "Speakers", NULL, widget_name }; - struct snd_soc_dai *codec_dai; - int i, ret; - - snprintf(codec_name, CODEC_NAME_SIZE, "%s", dai_name); - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s spk:%s", - card->components, codec_name); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_dapm_new_controls(&card->dapm, sof_widgets, - ARRAY_SIZE(sof_widgets)); - if (ret) { - dev_err(card->dev, "widgets addition failed: %d\n", ret); - return ret; - } - - for_each_rtd_codec_dais(rtd, i, codec_dai) { - if (!strstr(codec_dai->name, "cs35l56")) - continue; - - snprintf(widget_name, sizeof(widget_name), "%s SPK", - codec_dai->component->name_prefix); - ret = snd_soc_dapm_add_routes(&card->dapm, &route, 1); - if (ret) - return ret; - } - - return 0; -} - -int sof_sdw_cs_amp_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) -{ - /* Do init on playback link only. */ - if (!playback) - return 0; - - info->amp_num++; - - return 0; -} diff --git a/sound/soc/intel/boards/sof_sdw_dmic.c b/sound/soc/intel/boards/sof_sdw_dmic.c deleted file mode 100644 index 19df0f7a1d85..000000000000 --- a/sound/soc/intel/boards/sof_sdw_dmic.c +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2020 Intel Corporation - -/* - * sof_sdw_dmic - Helpers to handle dmic from generic machine driver - */ - -#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 dmic_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - -static const struct snd_soc_dapm_route dmic_map[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - -int sof_sdw_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; -} - diff --git a/sound/soc/intel/boards/sof_sdw_hdmi.c b/sound/soc/intel/boards/sof_sdw_hdmi.c index f34fabdf9d93..f92867deb029 100644 --- a/sound/soc/intel/boards/sof_sdw_hdmi.c +++ b/sound/soc/intel/boards/sof_sdw_hdmi.c @@ -5,10 +5,12 @@ * sof_sdw_hdmi - Helpers to handle HDMI from generic machine driver */ +#include <linux/acpi.h> #include <linux/device.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/list.h> +#include <linux/soundwire/sdw_intel.h> #include <sound/soc.h> #include <sound/soc-acpi.h> #include <sound/jack.h> @@ -17,23 +19,25 @@ int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd) { - struct mc_private *ctx = snd_soc_card_get_drvdata(rtd->card); + struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(rtd->card); + struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private; struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); - ctx->hdmi.hdmi_comp = dai->component; + intel_ctx->hdmi.hdmi_comp = dai->component; return 0; } int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card) { - struct mc_private *ctx = snd_soc_card_get_drvdata(card); + struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); + struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private; - if (!ctx->hdmi.idisp_codec) + if (!intel_ctx->hdmi.idisp_codec) return 0; - if (!ctx->hdmi.hdmi_comp) + if (!intel_ctx->hdmi.hdmi_comp) return -EINVAL; - return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp); + return hda_dsp_hdmi_build_controls(card, intel_ctx->hdmi.hdmi_comp); } diff --git a/sound/soc/intel/boards/sof_sdw_maxim.c b/sound/soc/intel/boards/sof_sdw_maxim.c deleted file mode 100644 index 034730432671..000000000000 --- a/sound/soc/intel/boards/sof_sdw_maxim.c +++ /dev/null @@ -1,165 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2020 Intel Corporation -// -// sof_sdw_maxim - Helpers to handle maxim codecs -// codec devices from generic machine driver - -#include <linux/device.h> -#include <linux/errno.h> -#include <sound/control.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/soc-dapm.h> -#include "sof_sdw_common.h" -#include "sof_maxim_common.h" - -static int maxim_part_id; -#define SOF_SDW_PART_ID_MAX98363 0x8363 -#define SOF_SDW_PART_ID_MAX98373 0x8373 - -static const struct snd_soc_dapm_widget maxim_widgets[] = { - SND_SOC_DAPM_SPK("Left Spk", NULL), - SND_SOC_DAPM_SPK("Right Spk", NULL), -}; - -static const struct snd_kcontrol_new maxim_controls[] = { - SOC_DAPM_PIN_SWITCH("Left Spk"), - SOC_DAPM_PIN_SWITCH("Right Spk"), -}; - -int maxim_spk_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 spk:mx%04x", - card->components, maxim_part_id); - if (!card->components) - return -ENOMEM; - - dev_dbg(card->dev, "soundwire maxim card components assigned : %s\n", - card->components); - - ret = snd_soc_add_card_controls(card, maxim_controls, - ARRAY_SIZE(maxim_controls)); - if (ret) { - dev_err(card->dev, "mx%04x ctrls addition failed: %d\n", maxim_part_id, ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, maxim_widgets, - ARRAY_SIZE(maxim_widgets)); - if (ret) { - dev_err(card->dev, "mx%04x widgets addition failed: %d\n", maxim_part_id, ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes, 2); - if (ret) - dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); - - return ret; -} - -static int mx8373_enable_spk_pin(struct snd_pcm_substream *substream, bool enable) -{ - 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; - int j; - - /* set spk pin by playback only */ - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - return 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); - char pin_name[16]; - - snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk", - codec_dai->component->name_prefix); - - if (enable) - ret = snd_soc_dapm_enable_pin(dapm, pin_name); - else - ret = snd_soc_dapm_disable_pin(dapm, pin_name); - - if (!ret) - snd_soc_dapm_sync(dapm); - } - - return 0; -} - -static int mx8373_sdw_prepare(struct snd_pcm_substream *substream) -{ - int ret; - - /* according to soc_pcm_prepare dai link prepare is called first */ - ret = sdw_prepare(substream); - if (ret < 0) - return ret; - - return mx8373_enable_spk_pin(substream, true); -} - -static int mx8373_sdw_hw_free(struct snd_pcm_substream *substream) -{ - int ret; - - /* according to soc_pcm_hw_free dai link free is called first */ - ret = sdw_hw_free(substream); - if (ret < 0) - return ret; - - return mx8373_enable_spk_pin(substream, false); -} - -static const struct snd_soc_ops max_98373_sdw_ops = { - .startup = sdw_startup, - .prepare = mx8373_sdw_prepare, - .trigger = sdw_trigger, - .hw_params = sdw_hw_params, - .hw_free = mx8373_sdw_hw_free, - .shutdown = sdw_shutdown, -}; - -static int mx8373_sdw_late_probe(struct snd_soc_card *card) -{ - struct snd_soc_dapm_context *dapm = &card->dapm; - - /* Disable Left and Right Spk pin after boot */ - snd_soc_dapm_disable_pin(dapm, "Left Spk"); - snd_soc_dapm_disable_pin(dapm, "Right Spk"); - return snd_soc_dapm_sync(dapm); -} - -int sof_sdw_maxim_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) -{ - info->amp_num++; - - maxim_part_id = info->part_id; - switch (maxim_part_id) { - case SOF_SDW_PART_ID_MAX98363: - /* Default ops are set in function init_dai_link. - * called as part of function create_sdw_dailink - */ - break; - case SOF_SDW_PART_ID_MAX98373: - info->codec_card_late_probe = mx8373_sdw_late_probe; - dai_links->ops = &max_98373_sdw_ops; - break; - default: - dev_err(card->dev, "Invalid maxim_part_id %#x\n", maxim_part_id); - return -EINVAL; - } - return 0; -} diff --git a/sound/soc/intel/boards/sof_sdw_rt5682.c b/sound/soc/intel/boards/sof_sdw_rt5682.c deleted file mode 100644 index 6b008a5a343b..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt5682.c +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2020 Intel Corporation - -/* - * sof_sdw_rt5682 - Helpers to handle RT5682 from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/input.h> -#include <linux/soundwire/sdw.h> -#include <linux/soundwire/sdw_type.h> -#include <sound/control.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/soc-dapm.h> -#include <sound/jack.h> -#include "sof_board_helpers.h" -#include "sof_sdw_common.h" - -static const struct snd_soc_dapm_widget rt5682_widgets[] = { - SND_SOC_DAPM_HP("Headphone", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), -}; - -static const struct snd_soc_dapm_route rt5682_map[] = { - /*Headphones*/ - { "Headphone", NULL, "rt5682 HPOL" }, - { "Headphone", NULL, "rt5682 HPOR" }, - { "rt5682 IN1P", NULL, "Headset Mic" }, -}; - -static const struct snd_kcontrol_new rt5682_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), -}; - -static struct snd_soc_jack_pin rt5682_jack_pins[] = { - { - .pin = "Headphone", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, -}; - -static const char * const jack_codecs[] = { - "rt5682" -}; - -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; - struct snd_soc_component *component; - struct snd_soc_jack *jack; - int ret; - - codec_dai = get_codec_dai_by_name(rtd, jack_codecs, ARRAY_SIZE(jack_codecs)); - if (!codec_dai) - return -EINVAL; - - component = codec_dai->component; - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s hs:rt5682", - card->components); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, rt5682_controls, - ARRAY_SIZE(rt5682_controls)); - if (ret) { - dev_err(card->dev, "rt5682 control addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, rt5682_widgets, - ARRAY_SIZE(rt5682_widgets)); - if (ret) { - dev_err(card->dev, "rt5682 widgets addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, rt5682_map, - ARRAY_SIZE(rt5682_map)); - - if (ret) { - dev_err(card->dev, "rt5682 map addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | - SND_JACK_BTN_1 | SND_JACK_BTN_2 | - SND_JACK_BTN_3, - &ctx->sdw_headset, - rt5682_jack_pins, - ARRAY_SIZE(rt5682_jack_pins)); - if (ret) { - dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n", - ret); - return ret; - } - - jack = &ctx->sdw_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); - - if (ret) - dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n", - ret); - - return ret; -} -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); diff --git a/sound/soc/intel/boards/sof_sdw_rt700.c b/sound/soc/intel/boards/sof_sdw_rt700.c deleted file mode 100644 index 88e785a54b16..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt700.c +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2020 Intel Corporation - -/* - * sof_sdw_rt700 - Helpers to handle RT700 from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/input.h> -#include <sound/control.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/soc-dapm.h> -#include <sound/jack.h> -#include "sof_board_helpers.h" -#include "sof_sdw_common.h" - -static const struct snd_soc_dapm_widget rt700_widgets[] = { - SND_SOC_DAPM_HP("Headphones", NULL), - SND_SOC_DAPM_MIC("AMIC", NULL), - SND_SOC_DAPM_SPK("Speaker", NULL), -}; - -static const struct snd_soc_dapm_route rt700_map[] = { - /* Headphones */ - { "Headphones", NULL, "rt700 HP" }, - { "Speaker", NULL, "rt700 SPK" }, - { "rt700 MIC2", NULL, "AMIC" }, -}; - -static const struct snd_kcontrol_new rt700_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphones"), - SOC_DAPM_PIN_SWITCH("AMIC"), - SOC_DAPM_PIN_SWITCH("Speaker"), -}; - -static struct snd_soc_jack_pin rt700_jack_pins[] = { - { - .pin = "Headphones", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "AMIC", - .mask = SND_JACK_MICROPHONE, - }, -}; - -static const char * const jack_codecs[] = { - "rt700" -}; - -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; - struct snd_soc_component *component; - struct snd_soc_jack *jack; - int ret; - - codec_dai = get_codec_dai_by_name(rtd, jack_codecs, ARRAY_SIZE(jack_codecs)); - if (!codec_dai) - return -EINVAL; - - component = codec_dai->component; - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s hs:rt700", - card->components); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, rt700_controls, - ARRAY_SIZE(rt700_controls)); - if (ret) { - dev_err(card->dev, "rt700 controls addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, rt700_widgets, - ARRAY_SIZE(rt700_widgets)); - if (ret) { - dev_err(card->dev, "rt700 widgets addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, rt700_map, - ARRAY_SIZE(rt700_map)); - - if (ret) { - dev_err(card->dev, "rt700 map addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | - SND_JACK_BTN_1 | SND_JACK_BTN_2 | - SND_JACK_BTN_3, - &ctx->sdw_headset, - rt700_jack_pins, - ARRAY_SIZE(rt700_jack_pins)); - if (ret) { - dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n", - ret); - return ret; - } - - jack = &ctx->sdw_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); - if (ret) - dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n", - ret); - - return ret; -} -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c deleted file mode 100644 index cdd1587b246c..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt711.c +++ /dev/null @@ -1,191 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2020 Intel Corporation - -/* - * sof_sdw_rt711 - Helpers to handle RT711 from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/input.h> -#include <linux/soundwire/sdw.h> -#include <linux/soundwire/sdw_type.h> -#include <sound/control.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/soc-dapm.h> -#include <sound/jack.h> -#include "sof_board_helpers.h" -#include "sof_sdw_common.h" - -/* - * Note this MUST be called before snd_soc_register_card(), so that the props - * are in place before the codec component driver's probe function parses them. - */ -static int rt711_add_codec_device_props(struct device *sdw_dev) -{ - struct property_entry props[MAX_NO_PROPS] = {}; - struct fwnode_handle *fwnode; - int ret; - - if (!SOF_JACK_JDSRC(sof_sdw_quirk)) - return 0; - props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_JACK_JDSRC(sof_sdw_quirk)); - - fwnode = fwnode_create_software_node(props, NULL); - if (IS_ERR(fwnode)) - return PTR_ERR(fwnode); - - ret = device_add_software_node(sdw_dev, to_software_node(fwnode)); - - fwnode_handle_put(fwnode); - - return ret; -} - -static const struct snd_soc_dapm_widget rt711_widgets[] = { - SND_SOC_DAPM_HP("Headphone", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), -}; - -static const struct snd_soc_dapm_route rt711_map[] = { - /* Headphones */ - { "Headphone", NULL, "rt711 HP" }, - { "rt711 MIC2", NULL, "Headset Mic" }, -}; - -static const struct snd_kcontrol_new rt711_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), -}; - -static struct snd_soc_jack_pin rt711_jack_pins[] = { - { - .pin = "Headphone", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, -}; - -static const char * const jack_codecs[] = { - "rt711" -}; - -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; - struct snd_soc_component *component; - struct snd_soc_jack *jack; - int ret; - - codec_dai = get_codec_dai_by_name(rtd, jack_codecs, ARRAY_SIZE(jack_codecs)); - if (!codec_dai) - return -EINVAL; - - component = codec_dai->component; - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s hs:rt711", - card->components); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, rt711_controls, - ARRAY_SIZE(rt711_controls)); - if (ret) { - dev_err(card->dev, "rt711 controls addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, rt711_widgets, - ARRAY_SIZE(rt711_widgets)); - if (ret) { - dev_err(card->dev, "rt711 widgets addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, rt711_map, - ARRAY_SIZE(rt711_map)); - - if (ret) { - dev_err(card->dev, "rt711 map addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | - SND_JACK_BTN_1 | SND_JACK_BTN_2 | - SND_JACK_BTN_3, - &ctx->sdw_headset, - rt711_jack_pins, - ARRAY_SIZE(rt711_jack_pins)); - if (ret) { - dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n", - ret); - return ret; - } - - jack = &ctx->sdw_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); - - if (ret) - dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n", - ret); - - return ret; -} - -int sof_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) -{ - struct mc_private *ctx = snd_soc_card_get_drvdata(card); - - if (!ctx->headset_codec_dev) - return 0; - - device_remove_software_node(ctx->headset_codec_dev); - put_device(ctx->headset_codec_dev); - - return 0; -} - -int sof_sdw_rt711_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) -{ - struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct device *sdw_dev; - int ret; - - /* - * headset should be initialized once. - * Do it with dai link for playback. - */ - if (!playback) - return 0; - - sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name); - if (!sdw_dev) - return -EPROBE_DEFER; - - ret = rt711_add_codec_device_props(sdw_dev); - if (ret < 0) { - put_device(sdw_dev); - return ret; - } - ctx->headset_codec_dev = sdw_dev; - - return 0; -} -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); diff --git a/sound/soc/intel/boards/sof_sdw_rt712_sdca.c b/sound/soc/intel/boards/sof_sdw_rt712_sdca.c deleted file mode 100644 index ebb4b58c198b..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt712_sdca.c +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2023 Intel Corporation - -/* - * sof_sdw_rt712_sdca - Helpers to handle RT712-SDCA from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/soundwire/sdw.h> -#include <linux/soundwire/sdw_type.h> -#include <sound/control.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/soc-dapm.h> -#include "sof_board_helpers.h" -#include "sof_sdw_common.h" - -static const struct snd_soc_dapm_widget rt712_spk_widgets[] = { - SND_SOC_DAPM_SPK("Speaker", NULL), -}; - -/* - * dapm routes for rt712 spk will be registered dynamically according - * to the number of rt712 spk used. The first two entries will be registered - * for one codec case, and the last two entries are also registered - * if two rt712s are used. - */ -static const struct snd_soc_dapm_route rt712_spk_map[] = { - { "Speaker", NULL, "rt712 SPOL" }, - { "Speaker", NULL, "rt712 SPOR" }, -}; - -static const struct snd_kcontrol_new rt712_spk_controls[] = { - SOC_DAPM_PIN_SWITCH("Speaker"), -}; - -int rt712_spk_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 spk:rt712", - card->components); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, rt712_spk_controls, - ARRAY_SIZE(rt712_spk_controls)); - if (ret) { - dev_err(card->dev, "rt712 spk controls addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, rt712_spk_widgets, - ARRAY_SIZE(rt712_spk_widgets)); - if (ret) { - dev_err(card->dev, "rt712 spk widgets addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, rt712_spk_map, ARRAY_SIZE(rt712_spk_map)); - if (ret) - dev_err(rtd->dev, "failed to add SPK map: %d\n", ret); - - return ret; -} - -static const char * const dmics[] = { - "rt712-sdca-dmic" -}; - -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; - struct snd_soc_component *component; - - codec_dai = get_codec_dai_by_name(rtd, dmics, ARRAY_SIZE(dmics)); - if (!codec_dai) - return -EINVAL; - - component = codec_dai->component; - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s mic:%s", - card->components, component->name_prefix); - if (!card->components) - return -ENOMEM; - - return 0; -} -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); diff --git a/sound/soc/intel/boards/sof_sdw_rt715.c b/sound/soc/intel/boards/sof_sdw_rt715.c deleted file mode 100644 index b5a886cd595d..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt715.c +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2020 Intel Corporation - -/* - * sof_sdw_rt715 - Helpers to handle RT715 from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include "sof_sdw_common.h" - -int rt715_rtd_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s mic:rt715", - card->components); - if (!card->components) - return -ENOMEM; - - return 0; -} - diff --git a/sound/soc/intel/boards/sof_sdw_rt715_sdca.c b/sound/soc/intel/boards/sof_sdw_rt715_sdca.c deleted file mode 100644 index 4b37a8a6dd2e..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt715_sdca.c +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2020 Intel Corporation - -/* - * sof_sdw_rt715_sdca - Helpers to handle RT715-SDCA from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include "sof_sdw_common.h" - -int rt715_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s mic:rt715-sdca", - card->components); - if (!card->components) - return -ENOMEM; - - return 0; -} - diff --git a/sound/soc/intel/boards/sof_sdw_rt722_sdca.c b/sound/soc/intel/boards/sof_sdw_rt722_sdca.c deleted file mode 100644 index fe3a2bff95bc..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt722_sdca.c +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2023 Intel Corporation - -/* - * sof_sdw_rt722_sdca - Helpers to handle RT722-SDCA from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/soundwire/sdw.h> -#include <linux/soundwire/sdw_type.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 rt722_spk_widgets[] = { - SND_SOC_DAPM_SPK("Speaker", NULL), -}; - -static const struct snd_soc_dapm_route rt722_spk_map[] = { - { "Speaker", NULL, "rt722 SPK" }, -}; - -static const struct snd_kcontrol_new rt722_spk_controls[] = { - SOC_DAPM_PIN_SWITCH("Speaker"), -}; - -static int rt722_spk_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 spk:rt722", - card->components); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, rt722_spk_controls, - ARRAY_SIZE(rt722_spk_controls)); - if (ret) { - dev_err(card->dev, "failed to add rt722 spk controls: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, rt722_spk_widgets, - ARRAY_SIZE(rt722_spk_widgets)); - if (ret) { - dev_err(card->dev, "failed to add rt722 spk widgets: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, rt722_spk_map, ARRAY_SIZE(rt722_spk_map)); - if (ret) - dev_err(rtd->dev, "failed to add rt722 spk map: %d\n", ret); - - return ret; -} - -int sof_sdw_rt722_spk_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 = rt722_spk_init; - - return 0; -} - -static int rt722_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:%s", - card->components, component->name_prefix); - if (!card->components) - return -ENOMEM; - - return 0; -} - -int sof_sdw_rt722_sdca_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 = rt722_sdca_dmic_rtd_init; - - return 0; -} diff --git a/sound/soc/intel/boards/sof_sdw_rt_amp.c b/sound/soc/intel/boards/sof_sdw_rt_amp.c deleted file mode 100644 index 202edab95000..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt_amp.c +++ /dev/null @@ -1,324 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2022 Intel Corporation - -/* - * sof_sdw_rt_amp - Helpers to handle RT1308/RT1316/RT1318 from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <sound/control.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/soc-dapm.h> -#include <linux/soundwire/sdw.h> -#include <linux/soundwire/sdw_type.h> -#include <linux/dmi.h> -#include "sof_sdw_common.h" -#include "sof_sdw_amp_coeff_tables.h" -#include "../../codecs/rt1308.h" - -#define CODEC_NAME_SIZE 7 - -/* choose a larger value to resolve compatibility issues */ -#define RT_AMP_MAX_BQ_REG RT1316_MAX_BQ_REG - -struct rt_amp_platform_data { - const unsigned char *bq_params; - const unsigned int bq_params_cnt; -}; - -static const struct rt_amp_platform_data dell_0a5d_platform_data = { - .bq_params = dell_0a5d_bq_params, - .bq_params_cnt = ARRAY_SIZE(dell_0a5d_bq_params), -}; - -static const struct rt_amp_platform_data dell_0b00_platform_data = { - .bq_params = dell_0b00_bq_params, - .bq_params_cnt = ARRAY_SIZE(dell_0b00_bq_params), -}; - -static const struct dmi_system_id dmi_platform_data[] = { - /* CometLake devices */ - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990") - }, - .driver_data = (void *)&dell_0a5d_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F") - }, - .driver_data = (void *)&dell_0a5d_platform_data, - }, - /* TigerLake devices */ - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5D") - }, - .driver_data = (void *)&dell_0a5d_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") - }, - .driver_data = (void *)&dell_0a5d_platform_data, - }, - /* AlderLake devices */ - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00") - }, - .driver_data = (void *)&dell_0b00_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01") - }, - .driver_data = (void *)&dell_0b00_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFF") - }, - .driver_data = (void *)&dell_0b00_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFE") - }, - .driver_data = (void *)&dell_0b00_platform_data, - }, - {}, -}; - -static int rt_amp_add_device_props(struct device *sdw_dev) -{ - struct property_entry props[3] = {}; - struct fwnode_handle *fwnode; - const struct dmi_system_id *dmi_data; - const struct rt_amp_platform_data *pdata; - unsigned char params[RT_AMP_MAX_BQ_REG]; - int ret; - - dmi_data = dmi_first_match(dmi_platform_data); - if (!dmi_data) - return 0; - - pdata = dmi_data->driver_data; - memcpy(¶ms, pdata->bq_params, sizeof(unsigned char) * pdata->bq_params_cnt); - - props[0] = PROPERTY_ENTRY_U8_ARRAY("realtek,bq-params", params); - props[1] = PROPERTY_ENTRY_U32("realtek,bq-params-cnt", pdata->bq_params_cnt); - - fwnode = fwnode_create_software_node(props, NULL); - if (IS_ERR(fwnode)) - return PTR_ERR(fwnode); - - ret = device_add_software_node(sdw_dev, to_software_node(fwnode)); - - fwnode_handle_put(fwnode); - - return ret; -} - -static const struct snd_kcontrol_new rt_amp_controls[] = { - SOC_DAPM_PIN_SWITCH("Speaker"), -}; - -static const struct snd_soc_dapm_widget rt_amp_widgets[] = { - SND_SOC_DAPM_SPK("Speaker", NULL), -}; - -/* - * dapm routes for rt1308/rt1316/rt1318 will be registered dynamically - * according to the number of rt1308/rt1316/rt1318 used. The first two - * entries will be registered for one codec case, and the last two entries - * are also registered if two 1308s/1316s/1318s are used. - */ -static const struct snd_soc_dapm_route rt1308_map[] = { - { "Speaker", NULL, "rt1308-1 SPOL" }, - { "Speaker", NULL, "rt1308-1 SPOR" }, - { "Speaker", NULL, "rt1308-2 SPOL" }, - { "Speaker", NULL, "rt1308-2 SPOR" }, -}; - -static const struct snd_soc_dapm_route rt1316_map[] = { - { "Speaker", NULL, "rt1316-1 SPOL" }, - { "Speaker", NULL, "rt1316-1 SPOR" }, - { "Speaker", NULL, "rt1316-2 SPOL" }, - { "Speaker", NULL, "rt1316-2 SPOR" }, -}; - -static const struct snd_soc_dapm_route rt1318_map[] = { - { "Speaker", NULL, "rt1318-1 SPOL" }, - { "Speaker", NULL, "rt1318-1 SPOR" }, - { "Speaker", NULL, "rt1318-2 SPOL" }, - { "Speaker", NULL, "rt1318-2 SPOR" }, -}; - -static const struct snd_soc_dapm_route *get_codec_name_and_route(struct snd_soc_pcm_runtime *rtd, - char *codec_name) -{ - const char *dai_name; - - dai_name = rtd->dai_link->codecs->dai_name; - - /* get the codec name */ - snprintf(codec_name, CODEC_NAME_SIZE, "%s", dai_name); - - /* choose the right codec's map */ - if (strcmp(codec_name, "rt1308") == 0) - return rt1308_map; - else if (strcmp(codec_name, "rt1316") == 0) - return rt1316_map; - else - return rt1318_map; -} - -int rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - const struct snd_soc_dapm_route *rt_amp_map; - char codec_name[CODEC_NAME_SIZE]; - struct snd_soc_dai *dai; - int ret; - int i; - - rt_amp_map = get_codec_name_and_route(rtd, codec_name); - - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s spk:%s", - card->components, codec_name); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, rt_amp_controls, - ARRAY_SIZE(rt_amp_controls)); - if (ret) { - dev_err(card->dev, "%s controls addition failed: %d\n", codec_name, ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, rt_amp_widgets, - ARRAY_SIZE(rt_amp_widgets)); - if (ret) { - dev_err(card->dev, "%s widgets addition failed: %d\n", codec_name, ret); - return ret; - } - - for_each_rtd_codec_dais(rtd, i, dai) { - if (strstr(dai->component->name_prefix, "-1")) - ret = snd_soc_dapm_add_routes(&card->dapm, rt_amp_map, 2); - else if (strstr(dai->component->name_prefix, "-2")) - ret = snd_soc_dapm_add_routes(&card->dapm, rt_amp_map + 2, 2); - } - - return ret; -} - -static int rt1308_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - 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 = snd_soc_rtd_to_codec(rtd, 0); - int clk_id, clk_freq, pll_out; - int err; - - clk_id = RT1308_PLL_S_MCLK; - clk_freq = 38400000; - - pll_out = params_rate(params) * 512; - - /* Set rt1308 pll */ - err = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out); - if (err < 0) { - dev_err(card->dev, "Failed to set RT1308 PLL: %d\n", err); - return err; - } - - /* Set rt1308 sysclk */ - err = snd_soc_dai_set_sysclk(codec_dai, RT1308_FS_SYS_S_PLL, pll_out, - SND_SOC_CLOCK_IN); - if (err < 0) { - dev_err(card->dev, "Failed to set RT1308 SYSCLK: %d\n", err); - return err; - } - - return 0; -} - -/* machine stream operations */ -struct snd_soc_ops sof_sdw_rt1308_i2s_ops = { - .hw_params = rt1308_i2s_hw_params, -}; - -int sof_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) -{ - struct mc_private *ctx = snd_soc_card_get_drvdata(card); - - if (ctx->amp_dev1) { - device_remove_software_node(ctx->amp_dev1); - put_device(ctx->amp_dev1); - } - - if (ctx->amp_dev2) { - device_remove_software_node(ctx->amp_dev2); - put_device(ctx->amp_dev2); - } - - return 0; -} - -int sof_sdw_rt_amp_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) -{ - struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct device *sdw_dev1, *sdw_dev2; - int ret; - - /* Count amp number and do init on playback link only. */ - if (!playback) - return 0; - - info->amp_num++; - - if (info->amp_num == 2) { - sdw_dev1 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name); - if (!sdw_dev1) - return -EPROBE_DEFER; - - ret = rt_amp_add_device_props(sdw_dev1); - if (ret < 0) { - put_device(sdw_dev1); - return ret; - } - ctx->amp_dev1 = sdw_dev1; - - sdw_dev2 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[1].name); - if (!sdw_dev2) - return -EPROBE_DEFER; - - ret = rt_amp_add_device_props(sdw_dev2); - if (ret < 0) { - put_device(sdw_dev2); - return ret; - } - ctx->amp_dev2 = sdw_dev2; - } - - return 0; -} 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 deleted file mode 100644 index 5253d8332780..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2020 Intel Corporation - -/* - * sof_sdw_rt711_sdca - Helpers to handle RT711-SDCA from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/input.h> -#include <linux/soundwire/sdw.h> -#include <linux/soundwire/sdw_type.h> -#include <sound/control.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/soc-dapm.h> -#include <sound/jack.h> -#include "sof_board_helpers.h" -#include "sof_sdw_common.h" - -/* - * Note this MUST be called before snd_soc_register_card(), so that the props - * are in place before the codec component driver's probe function parses them. - */ -static int rt_sdca_jack_add_codec_device_props(struct device *sdw_dev) -{ - struct property_entry props[MAX_NO_PROPS] = {}; - struct fwnode_handle *fwnode; - int ret; - - if (!SOF_JACK_JDSRC(sof_sdw_quirk)) - return 0; - - props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_JACK_JDSRC(sof_sdw_quirk)); - - fwnode = fwnode_create_software_node(props, NULL); - if (IS_ERR(fwnode)) - return PTR_ERR(fwnode); - - ret = device_add_software_node(sdw_dev, to_software_node(fwnode)); - - fwnode_handle_put(fwnode); - - return ret; -} - -static const struct snd_soc_dapm_widget rt_sdca_jack_widgets[] = { - SND_SOC_DAPM_HP("Headphone", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), -}; - -static const struct snd_soc_dapm_route rt711_sdca_map[] = { - { "Headphone", NULL, "rt711 HP" }, - { "rt711 MIC2", NULL, "Headset Mic" }, -}; - -static const struct snd_soc_dapm_route rt712_sdca_map[] = { - { "Headphone", NULL, "rt712 HP" }, - { "rt712 MIC2", NULL, "Headset Mic" }, -}; - -static const struct snd_soc_dapm_route rt713_sdca_map[] = { - { "Headphone", NULL, "rt713 HP" }, - { "rt713 MIC2", NULL, "Headset Mic" }, -}; - -static const struct snd_soc_dapm_route rt722_sdca_map[] = { - { "Headphone", NULL, "rt722 HP" }, - { "rt722 MIC2", NULL, "Headset Mic" }, -}; - -static const struct snd_kcontrol_new rt_sdca_jack_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), -}; - -static struct snd_soc_jack_pin rt_sdca_jack_pins[] = { - { - .pin = "Headphone", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, -}; - -static const char * const jack_codecs[] = { - "rt711", "rt712", "rt713" -}; - -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; - struct snd_soc_component *component; - struct snd_soc_jack *jack; - int ret; - - codec_dai = get_codec_dai_by_name(rtd, jack_codecs, ARRAY_SIZE(jack_codecs)); - if (!codec_dai) - return -EINVAL; - - component = codec_dai->component; - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s hs:%s-sdca", - card->components, component->name_prefix); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, rt_sdca_jack_controls, - ARRAY_SIZE(rt_sdca_jack_controls)); - if (ret) { - dev_err(card->dev, "rt sdca jack controls addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, rt_sdca_jack_widgets, - ARRAY_SIZE(rt_sdca_jack_widgets)); - if (ret) { - dev_err(card->dev, "rt sdca jack widgets addition failed: %d\n", ret); - return ret; - } - - if (strstr(component->name_prefix, "rt711")) { - ret = snd_soc_dapm_add_routes(&card->dapm, rt711_sdca_map, - ARRAY_SIZE(rt711_sdca_map)); - } else if (strstr(component->name_prefix, "rt712")) { - ret = snd_soc_dapm_add_routes(&card->dapm, rt712_sdca_map, - ARRAY_SIZE(rt712_sdca_map)); - } else if (strstr(component->name_prefix, "rt713")) { - ret = snd_soc_dapm_add_routes(&card->dapm, rt713_sdca_map, - ARRAY_SIZE(rt713_sdca_map)); - } else if (strstr(component->name_prefix, "rt722")) { - ret = snd_soc_dapm_add_routes(&card->dapm, rt722_sdca_map, - ARRAY_SIZE(rt722_sdca_map)); - } else { - dev_err(card->dev, "%s is not supported\n", component->name_prefix); - return -EINVAL; - } - - if (ret) { - dev_err(card->dev, "rt sdca jack map addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | - SND_JACK_BTN_1 | SND_JACK_BTN_2 | - SND_JACK_BTN_3, - &ctx->sdw_headset, - rt_sdca_jack_pins, - ARRAY_SIZE(rt_sdca_jack_pins)); - if (ret) { - dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n", - ret); - return ret; - } - - jack = &ctx->sdw_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); - - if (ret) - dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n", - ret); - - return ret; -} - -int sof_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) -{ - struct mc_private *ctx = snd_soc_card_get_drvdata(card); - - if (!ctx->headset_codec_dev) - return 0; - - if (!SOF_JACK_JDSRC(sof_sdw_quirk)) - return 0; - - device_remove_software_node(ctx->headset_codec_dev); - put_device(ctx->headset_codec_dev); - ctx->headset_codec_dev = NULL; - - return 0; -} - -int sof_sdw_rt_sdca_jack_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) -{ - struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct device *sdw_dev; - int ret; - - /* - * Jack detection should be only initialized once for headsets since - * the playback/capture is sharing the same jack - */ - if (ctx->headset_codec_dev) - return 0; - - sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name); - if (!sdw_dev) - return -EPROBE_DEFER; - - ret = rt_sdca_jack_add_codec_device_props(sdw_dev); - if (ret < 0) { - put_device(sdw_dev); - return ret; - } - ctx->headset_codec_dev = sdw_dev; - - return 0; -} -MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); diff --git a/sound/soc/intel/boards/sof_ssp_amp.c b/sound/soc/intel/boards/sof_ssp_amp.c index ee2e813bf4c0..48ee5353bdf1 100644 --- a/sound/soc/intel/boards/sof_ssp_amp.c +++ b/sound/soc/intel/boards/sof_ssp_amp.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only // -// Copyright(c) 2022 Intel Corporation. All rights reserved. +// Copyright(c) 2022 Intel Corporation /* * sof_ssp_amp.c - ASoc Machine driver for Intel platforms @@ -20,34 +20,12 @@ #include "sof_board_helpers.h" #include "sof_realtek_common.h" #include "sof_cirrus_common.h" -#include "sof_ssp_common.h" - -/* SSP port ID for speaker amplifier */ -#define SOF_AMPLIFIER_SSP(quirk) ((quirk) & GENMASK(3, 0)) -#define SOF_AMPLIFIER_SSP_MASK (GENMASK(3, 0)) - -/* HDMI capture*/ -#define SOF_HDMI_CAPTURE_SSP_MASK_SHIFT 4 -#define SOF_HDMI_CAPTURE_SSP_MASK_MASK (GENMASK(9, 4)) -#define SOF_HDMI_CAPTURE_SSP_MASK(quirk) \ - (((quirk) << SOF_HDMI_CAPTURE_SSP_MASK_SHIFT) & SOF_HDMI_CAPTURE_SSP_MASK_MASK) - -/* HDMI playback */ -#define SOF_HDMI_PLAYBACK_PRESENT BIT(13) -#define SOF_NO_OF_HDMI_PLAYBACK_SHIFT 14 -#define SOF_NO_OF_HDMI_PLAYBACK_MASK (GENMASK(16, 14)) -#define SOF_NO_OF_HDMI_PLAYBACK(quirk) \ - (((quirk) << SOF_NO_OF_HDMI_PLAYBACK_SHIFT) & SOF_NO_OF_HDMI_PLAYBACK_MASK) - -/* BT audio offload */ -#define SOF_SSP_BT_OFFLOAD_PRESENT BIT(17) -#define SOF_BT_OFFLOAD_SSP_SHIFT 18 -#define SOF_BT_OFFLOAD_SSP_MASK (GENMASK(20, 18)) -#define SOF_BT_OFFLOAD_SSP(quirk) \ - (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK) + +/* Driver-specific board quirks: from bit 0 to 7 */ +#define SOF_HDMI_PLAYBACK_PRESENT BIT(0) /* Default: SSP2 */ -static unsigned long sof_ssp_amp_quirk = SOF_AMPLIFIER_SSP(2); +static unsigned long sof_ssp_amp_quirk = SOF_SSP_PORT_AMP(2); static const struct dmi_system_id chromebook_platforms[] = { { @@ -75,197 +53,107 @@ static struct snd_soc_card sof_ssp_amp_card = { #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_amp, int dmic_be_num, int hdmi_num, - bool idisp_codec) +/* extra BE links to support no-hdmi-in boards */ +#define DMIC16K_BE_ID 4 +#define BT_OFFLOAD_BE_ID 8 + +#define SSP_AMP_LINK_ORDER SOF_LINK_ORDER(SOF_LINK_HDMI_IN, \ + SOF_LINK_AMP, \ + SOF_LINK_DMIC01, \ + SOF_LINK_DMIC16K, \ + SOF_LINK_IDISP_HDMI, \ + SOF_LINK_BT_OFFLOAD, \ + SOF_LINK_NONE) + +#define SSP_AMP_LINK_IDS SOF_LINK_ORDER(HDMI_IN_BE_ID, \ + SPK_BE_ID, \ + DMIC01_BE_ID, \ + DMIC16K_BE_ID, \ + INTEL_HDMI_BE_ID, \ + BT_OFFLOAD_BE_ID, \ + 0) + +static int +sof_card_dai_links_create(struct device *dev, struct snd_soc_card *card, + struct sof_card_private *ctx) { - struct snd_soc_dai_link *links; - int i; - int id = 0; int ret; - bool fixed_be = false; - int be_id; - unsigned long ssp_mask_hdmi_in; - - links = devm_kcalloc(dev, sof_ssp_amp_card.num_links, - sizeof(struct snd_soc_dai_link), GFP_KERNEL); - if (!links) - return NULL; - - /* HDMI-In SSP */ - ssp_mask_hdmi_in = (sof_ssp_amp_quirk & SOF_HDMI_CAPTURE_SSP_MASK_MASK) >> - SOF_HDMI_CAPTURE_SSP_MASK_SHIFT; - - if (ssp_mask_hdmi_in) { - int port = 0; - - /* the topology supports HDMI-IN uses fixed BE ID for DAI links */ - fixed_be = true; - - be_id = HDMI_IN_BE_ID; - for_each_set_bit(port, &ssp_mask_hdmi_in, 32) { - ret = sof_intel_board_set_hdmi_in_link(dev, &links[id], - be_id, port); - if (ret) - return NULL; - - id++; - be_id++; - } - } - - /* codec SSP */ - if (amp_type != CODEC_NONE) { - be_id = fixed_be ? SPK_BE_ID : id; - ret = sof_intel_board_set_ssp_amp_link(dev, &links[id], be_id, - amp_type, ssp_amp); - if (ret) - return NULL; - - /* codec-specific fields */ - 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; - } - id++; - } - - /* dmic */ - if (dmic_be_num > 0) { - /* at least we have dmic01 */ - 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++; - } - - 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++; - } + ret = sof_intel_board_set_dai_link(dev, card, ctx); + if (ret) + return ret; - /* HDMI playback */ - 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; + if (ctx->amp_type == CODEC_NONE) + return 0; - id++; + if (!ctx->amp_link) { + dev_err(dev, "amp link not available"); + return -EINVAL; } - /* BT audio offload */ - if (sof_ssp_amp_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) { - int port = (sof_ssp_amp_quirk & SOF_BT_OFFLOAD_SSP_MASK) >> - SOF_BT_OFFLOAD_SSP_SHIFT; - - ret = sof_intel_board_set_bt_link(dev, &links[id], id, port); - if (ret) - return NULL; - - id++; + /* codec-specific fields for speaker amplifier */ + switch (ctx->amp_type) { + case CODEC_CS35L41: + cs35l41_set_dai_link(ctx->amp_link); + break; + case CODEC_RT1308: + sof_rt1308_dai_link(ctx->amp_link); + break; + default: + dev_err(dev, "invalid amp type %d\n", ctx->amp_type); + return -EINVAL; } - return links; + return 0; } 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 sof_card_private *ctx; int ret; - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - if (pdev->id_entry && pdev->id_entry->driver_data) sof_ssp_amp_quirk = (unsigned long)pdev->id_entry->driver_data; - ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); - - if (dmi_check_system(chromebook_platforms) || mach->mach_params.dmic_num > 0) - ctx->dmic_be_num = 2; - else - ctx->dmic_be_num = 0; - - /* port number/mask of peripherals attached to ssp interface */ - ctx->ssp_mask_hdmi_in = (sof_ssp_amp_quirk & SOF_HDMI_CAPTURE_SSP_MASK_MASK) >> - SOF_HDMI_CAPTURE_SSP_MASK_SHIFT; - - ctx->ssp_bt = (sof_ssp_amp_quirk & SOF_BT_OFFLOAD_SSP_MASK) >> - SOF_BT_OFFLOAD_SSP_SHIFT; - - ctx->ssp_amp = sof_ssp_amp_quirk & SOF_AMPLIFIER_SSP_MASK; - - /* set number of dai links */ - sof_ssp_amp_card.num_links = ctx->dmic_be_num; + dev_dbg(&pdev->dev, "sof_ssp_amp_quirk = %lx\n", sof_ssp_amp_quirk); - if (ctx->amp_type != CODEC_NONE) - sof_ssp_amp_card.num_links++; + /* initialize ctx with board quirk */ + ctx = sof_intel_board_get_ctx(&pdev->dev, sof_ssp_amp_quirk); + if (!ctx) + return -ENOMEM; - if (ctx->ssp_mask_hdmi_in) - sof_ssp_amp_card.num_links += hweight32(ctx->ssp_mask_hdmi_in); + if (!dmi_check_system(chromebook_platforms) && + (mach->mach_params.dmic_num == 0)) + ctx->dmic_be_num = 0; if (sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT) { - 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 (!ctx->hdmi_num) - ctx->hdmi_num = 3; - if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) ctx->hdmi.idisp_codec = true; - - sof_ssp_amp_card.num_links += ctx->hdmi_num; } else { ctx->hdmi_num = 0; } - if (sof_ssp_amp_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) { - ctx->bt_offload_present = true; - sof_ssp_amp_card.num_links++; - } + ctx->link_order_overwrite = SSP_AMP_LINK_ORDER; - dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type, - ctx->ssp_amp, ctx->dmic_be_num, - ctx->hdmi_num, - ctx->hdmi.idisp_codec); - if (!dai_links) - return -ENOMEM; + if (ctx->ssp_mask_hdmi_in) { + /* the topology supports HDMI-IN uses fixed BE ID for DAI links */ + ctx->link_id_overwrite = SSP_AMP_LINK_IDS; + } - sof_ssp_amp_card.dai_link = dai_links; + /* update dai_link */ + ret = sof_card_dai_links_create(&pdev->dev, &sof_ssp_amp_card, ctx); + if (ret) + return ret; /* update codec_conf */ switch (ctx->amp_type) { case CODEC_CS35L41: cs35l41_set_codec_conf(&sof_ssp_amp_card); break; - case CODEC_NONE: case CODEC_RT1308: + case CODEC_NONE: /* no codec conf required */ break; default: @@ -292,38 +180,41 @@ static const struct platform_device_id board_ids[] = { }, { .name = "tgl_rt1308_hdmi_ssp", - .driver_data = (kernel_ulong_t)(SOF_AMPLIFIER_SSP(2) | - SOF_HDMI_CAPTURE_SSP_MASK(0x22)), + .driver_data = (kernel_ulong_t)(SOF_SSP_PORT_AMP(2) | + SOF_SSP_MASK_HDMI_CAPTURE(0x22)), /* SSP 1 and SSP 5 are used for HDMI IN */ }, { .name = "adl_cs35l41", - .driver_data = (kernel_ulong_t)(SOF_AMPLIFIER_SSP(1) | - SOF_NO_OF_HDMI_PLAYBACK(4) | + .driver_data = (kernel_ulong_t)(SOF_SSP_PORT_AMP(1) | + SOF_NUM_IDISP_HDMI(4) | SOF_HDMI_PLAYBACK_PRESENT | - SOF_BT_OFFLOAD_SSP(2) | - SOF_SSP_BT_OFFLOAD_PRESENT), + SOF_SSP_PORT_BT_OFFLOAD(2) | + SOF_BT_OFFLOAD_PRESENT), }, { .name = "adl_lt6911_hdmi_ssp", - .driver_data = (kernel_ulong_t)(SOF_HDMI_CAPTURE_SSP_MASK(0x5) | + .driver_data = (kernel_ulong_t)(SOF_SSP_MASK_HDMI_CAPTURE(0x5) | /* SSP 0 and SSP 2 are used for HDMI IN */ - SOF_NO_OF_HDMI_PLAYBACK(3) | SOF_HDMI_PLAYBACK_PRESENT), }, { .name = "rpl_lt6911_hdmi_ssp", - .driver_data = (kernel_ulong_t)(SOF_HDMI_CAPTURE_SSP_MASK(0x5) | + .driver_data = (kernel_ulong_t)(SOF_SSP_MASK_HDMI_CAPTURE(0x5) | /* SSP 0 and SSP 2 are used for HDMI IN */ - SOF_NO_OF_HDMI_PLAYBACK(3) | SOF_HDMI_PLAYBACK_PRESENT), }, { .name = "mtl_lt6911_hdmi_ssp", - .driver_data = (kernel_ulong_t)(SOF_HDMI_CAPTURE_SSP_MASK(0x5) | - /* SSP 0 and SSP 2 are used for HDMI IN */ - SOF_NO_OF_HDMI_PLAYBACK(3) | - SOF_HDMI_PLAYBACK_PRESENT), + .driver_data = (kernel_ulong_t)(SOF_SSP_MASK_HDMI_CAPTURE(0x5) | + /* SSP 0 and SSP 2 are used for HDMI IN */ + SOF_HDMI_PLAYBACK_PRESENT), + }, + { + .name = "arl_lt6911_hdmi_ssp", + .driver_data = (kernel_ulong_t)(SOF_SSP_MASK_HDMI_CAPTURE(0x5) | + /* SSP 0 and SSP 2 are used for HDMI IN */ + SOF_HDMI_PLAYBACK_PRESENT), }, { } }; @@ -343,7 +234,6 @@ 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_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); +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"); diff --git a/sound/soc/intel/boards/sof_ssp_common.c b/sound/soc/intel/boards/sof_ssp_common.c deleted file mode 100644 index 96072790e9c0..000000000000 --- a/sound/soc/intel/boards/sof_ssp_common.c +++ /dev/null @@ -1,122 +0,0 @@ -// 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); - -const char *sof_ssp_get_codec_name(enum sof_ssp_codec codec_type) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(codecs); i++) { - if (codecs[i].codec_type != codec_type) - continue; - - return codecs[i].name; - } - for (i = 0; i < ARRAY_SIZE(amps); i++) { - if (amps[i].codec_type != codec_type) - continue; - - return amps[i].name; - } - - return NULL; -} -EXPORT_SYMBOL_NS(sof_ssp_get_codec_name, 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 deleted file mode 100644 index d24888bc99fd..000000000000 --- a/sound/soc/intel/boards/sof_ssp_common.h +++ /dev/null @@ -1,80 +0,0 @@ -/* 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); - -#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SOF_SSP_COMMON) -const char *sof_ssp_get_codec_name(enum sof_ssp_codec codec_type); -#else -static inline const char *sof_ssp_get_codec_name(enum sof_ssp_codec codec_type) -{ - return NULL; -} -#endif - -#endif /* __SOF_SSP_COMMON_H */ diff --git a/sound/soc/intel/boards/sof_wm8804.c b/sound/soc/intel/boards/sof_wm8804.c index 4cb0d463bf40..51922347409f 100644 --- a/sound/soc/intel/boards/sof_wm8804.c +++ b/sound/soc/intel/boards/sof_wm8804.c @@ -148,7 +148,7 @@ static int sof_wm8804_hw_params(struct snd_pcm_substream *substream, } /* machine stream operations */ -static struct snd_soc_ops sof_wm8804_ops = { +static const struct snd_soc_ops sof_wm8804_ops = { .hw_params = sof_wm8804_hw_params, }; @@ -167,8 +167,6 @@ static struct snd_soc_dai_link dailink[] = { .name = "SSP5-Codec", .id = 0, .no_pcm = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, .ops = &sof_wm8804_ops, SND_SOC_DAILINK_REG(ssp5_pin, ssp5_codec, platform), }, @@ -270,7 +268,11 @@ static int sof_wm8804_probe(struct platform_device *pdev) snprintf(codec_name, sizeof(codec_name), "%s%s", "i2c-", acpi_dev_name(adev)); dailink[dai_index].codecs->name = codec_name; + } else { + dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id); + return -ENOENT; } + acpi_dev_put(adev); snd_soc_card_set_drvdata(card, ctx); @@ -290,7 +292,7 @@ static struct platform_driver sof_wm8804_driver = { .pm = &snd_soc_pm_ops, }, .probe = sof_wm8804_probe, - .remove_new = sof_wm8804_remove, + .remove = sof_wm8804_remove, }; module_platform_driver(sof_wm8804_driver); |