summaryrefslogtreecommitdiff
path: root/sound/soc/intel/boards
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/boards')
-rw-r--r--sound/soc/intel/boards/Kconfig77
-rw-r--r--sound/soc/intel/boards/Makefile12
-rw-r--r--sound/soc/intel/boards/bdw-rt5650.c2
-rw-r--r--sound/soc/intel/boards/bdw-rt5677.c2
-rw-r--r--sound/soc/intel/boards/broadwell.c2
-rw-r--r--sound/soc/intel/boards/bxt_da7219_max98357a.c2
-rw-r--r--sound/soc/intel/boards/bxt_rt298.c2
-rw-r--r--sound/soc/intel/boards/bytcht_cx2072x.c2
-rw-r--r--sound/soc/intel/boards/bytcht_da7213.c2
-rw-r--r--sound/soc/intel/boards/bytcht_es8316.c4
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c2
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c2
-rw-r--r--sound/soc/intel/boards/bytcr_wm5102.c2
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c4
-rw-r--r--sound/soc/intel/boards/cht_bsw_nau8824.c4
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c2
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c2
-rw-r--r--sound/soc/intel/boards/glk_rt5682_max98357a.c2
-rw-r--r--sound/soc/intel/boards/haswell.c2
-rw-r--r--sound/soc/intel/boards/sof_cirrus_common.c163
-rw-r--r--sound/soc/intel/boards/sof_cirrus_common.h25
-rw-r--r--sound/soc/intel/boards/sof_es8336.c134
-rw-r--r--sound/soc/intel/boards/sof_realtek_common.c107
-rw-r--r--sound/soc/intel/boards/sof_realtek_common.h4
-rw-r--r--sound/soc/intel/boards/sof_rt5682.c56
-rw-r--r--sound/soc/intel/boards/sof_sdw.c2
-rw-r--r--sound/soc/intel/boards/sof_ssp_amp.c483
27 files changed, 1016 insertions, 87 deletions
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index 34ccefcc30c7..f3873b5bea87 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -32,6 +32,12 @@ config SND_SOC_INTEL_HDA_DSP_COMMON
config SND_SOC_INTEL_SOF_MAXIM_COMMON
tristate
+config SND_SOC_INTEL_SOF_REALTEK_COMMON
+ tristate
+
+config SND_SOC_INTEL_SOF_CIRRUS_COMMON
+ tristate
+
if SND_SOC_INTEL_CATPT
config SND_SOC_INTEL_HASWELL_MACH
@@ -97,6 +103,7 @@ config SND_SOC_INTEL_BYTCR_RT5640_MACH
tristate "Baytrail and Baytrail-CR with RT5640 codec"
depends on I2C && ACPI
depends on X86_INTEL_LPSS || COMPILE_TEST
+ depends on GPIOLIB || COMPILE_TEST
select SND_SOC_ACPI
select SND_SOC_RT5640
help
@@ -109,6 +116,7 @@ config SND_SOC_INTEL_BYTCR_RT5651_MACH
tristate "Baytrail and Baytrail-CR with RT5651 codec"
depends on I2C && ACPI
depends on X86_INTEL_LPSS || COMPILE_TEST
+ depends on GPIOLIB || COMPILE_TEST
select SND_SOC_ACPI
select SND_SOC_RT5651
help
@@ -121,6 +129,7 @@ config SND_SOC_INTEL_BYTCR_WM5102_MACH
tristate "Baytrail and Baytrail-CR with WM5102 codec"
depends on MFD_ARIZONA && MFD_WM5102 && SPI_MASTER && ACPI
depends on X86_INTEL_LPSS || COMPILE_TEST
+ depends on GPIOLIB || COMPILE_TEST
select SND_SOC_ACPI
select SND_SOC_WM5102
help
@@ -133,6 +142,7 @@ config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
tristate "Cherrytrail & Braswell with RT5672 codec"
depends on I2C && ACPI
depends on X86_INTEL_LPSS || COMPILE_TEST
+ depends on GPIOLIB || COMPILE_TEST
select SND_SOC_ACPI
select SND_SOC_RT5670
help
@@ -157,6 +167,7 @@ config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
tristate "Cherrytrail & Braswell with MAX98090 & TI codec"
depends on I2C && ACPI
depends on X86_INTEL_LPSS || COMPILE_TEST
+ depends on GPIOLIB || COMPILE_TEST
select SND_SOC_MAX98090
select SND_SOC_TS3A227E
help
@@ -181,6 +192,7 @@ config SND_SOC_INTEL_BYT_CHT_CX2072X_MACH
tristate "Baytrail & Cherrytrail with CX2072X codec"
depends on I2C && ACPI
depends on X86_INTEL_LPSS || COMPILE_TEST
+ depends on GPIOLIB || COMPILE_TEST
select SND_SOC_ACPI
select SND_SOC_CX2072X
help
@@ -205,6 +217,7 @@ config SND_SOC_INTEL_BYT_CHT_ES8316_MACH
tristate "Baytrail & Cherrytrail with ES8316 codec"
depends on I2C && ACPI
depends on X86_INTEL_LPSS || COMPILE_TEST
+ depends on GPIOLIB || COMPILE_TEST
select SND_SOC_ACPI
select SND_SOC_ES8316
help
@@ -236,7 +249,7 @@ if SND_SOC_INTEL_SKL
config SND_SOC_INTEL_SKL_RT286_MACH
tristate "SKL with RT286 I2S mode"
- depends on I2C && ACPI && GPIOLIB
+ depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
select SND_SOC_RT286
select SND_SOC_DMIC
@@ -249,7 +262,7 @@ config SND_SOC_INTEL_SKL_RT286_MACH
config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH
tristate "SKL with NAU88L25 and SSM4567 in I2S Mode"
- depends on I2C && ACPI && GPIOLIB
+ depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
select SND_SOC_NAU8825
select SND_SOC_SSM4567
@@ -263,7 +276,7 @@ config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH
config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
tristate "SKL with NAU88L25 and MAX98357A in I2S Mode"
- depends on I2C && ACPI && GPIOLIB
+ depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
select SND_SOC_NAU8825
select SND_SOC_MAX98357A
@@ -294,7 +307,7 @@ 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 && GPIOLIB
+ 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
@@ -306,7 +319,7 @@ config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH
config SND_SOC_INTEL_BXT_RT298_MACH
tristate "Broxton with RT298 I2S mode"
- depends on I2C && ACPI && GPIOLIB
+ depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
select SND_SOC_RT298
select SND_SOC_DMIC
@@ -326,6 +339,7 @@ config SND_SOC_INTEL_SOF_WM8804_MACH
tristate "SOF with Wolfson/Cirrus WM8804 codec"
depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
+ depends on GPIOLIB || COMPILE_TEST
select SND_SOC_WM8804_I2C
help
This adds support for ASoC machine driver for Intel platforms
@@ -339,7 +353,7 @@ 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 && GPIOLIB
+ depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
select SND_SOC_RT5663
select SND_SOC_MAX98927
@@ -371,7 +385,7 @@ config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH
config SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH
tristate "KBL with DA7219 and MAX98357A in I2S Mode"
- depends on I2C && ACPI && GPIOLIB
+ depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC
help
@@ -381,7 +395,7 @@ config SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH
config SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH
tristate "KBL with DA7219 and MAX98927 in I2S Mode"
- depends on I2C && ACPI && GPIOLIB
+ depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
select SND_SOC_DA7219
select SND_SOC_MAX98927
@@ -398,6 +412,7 @@ 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
@@ -411,7 +426,7 @@ 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 && GPIOLIB
+ 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
@@ -423,7 +438,7 @@ config SND_SOC_INTEL_GLK_DA7219_MAX98357A_MACH
config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH
tristate "GLK with RT5682 and MAX98357A in I2S Mode"
- depends on I2C && ACPI && GPIOLIB
+ 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
@@ -445,7 +460,6 @@ if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC || 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
- depends on GPIOLIB
select SND_SOC_HDAC_HDMI
select SND_SOC_INTEL_HDA_DSP_COMMON
select SND_SOC_DMIC
@@ -462,7 +476,7 @@ endif ## SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC || SND_SOC_SOF_HDA_AUDIO_CODEC
if SND_SOC_SOF_HDA_LINK || SND_SOC_SOF_BAYTRAIL
config SND_SOC_INTEL_SOF_RT5682_MACH
tristate "SOF with rt5682 codec in I2S Mode"
- depends on I2C && ACPI && GPIOLIB
+ depends on I2C && ACPI
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))
@@ -477,6 +491,7 @@ config SND_SOC_INTEL_SOF_RT5682_MACH
select SND_SOC_HDAC_HDMI
select SND_SOC_INTEL_HDA_DSP_COMMON
select SND_SOC_INTEL_SOF_MAXIM_COMMON
+ select SND_SOC_INTEL_SOF_REALTEK_COMMON
help
This adds support for ASoC machine driver for SOF platforms
with rt5682 codec.
@@ -515,11 +530,13 @@ config SND_SOC_INTEL_SOF_PCM512x_MACH
If unsure select "N".
config SND_SOC_INTEL_SOF_ES8336_MACH
- tristate "SOF with ES8336 codec in I2S mode"
- depends on I2C && ACPI && GPIOLIB
+ tristate "SOF with ES8336 or ES8326 codec in I2S mode"
+ depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
+ depends on GPIOLIB || COMPILE_TEST
depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC
select SND_SOC_ES8316
+ select SND_SOC_ES8326
select SND_SOC_DMIC
select SND_SOC_INTEL_HDA_DSP_COMMON
help
@@ -530,7 +547,7 @@ config SND_SOC_INTEL_SOF_ES8336_MACH
config SND_SOC_INTEL_SOF_NAU8825_MACH
tristate "SOF with nau8825 codec in I2S Mode"
- depends on I2C && ACPI && GPIOLIB
+ depends on I2C && ACPI
depends on ((SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC) &&\
(MFD_INTEL_LPSS || COMPILE_TEST))
select SND_SOC_NAU8825
@@ -553,7 +570,7 @@ 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 && GPIOLIB
+ depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON
help
@@ -564,7 +581,7 @@ config SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH
config SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH
tristate "CML with RT1011 and RT5682 in I2S Mode"
- depends on I2C && ACPI && GPIOLIB
+ 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
@@ -584,7 +601,7 @@ if SND_SOC_SOF_JASPERLAKE
config SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH
tristate "SOF with DA7219 and MAX98373/MAX98360A in I2S Mode"
- depends on I2C && ACPI && GPIOLIB
+ depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC
select SND_SOC_INTEL_HDA_DSP_COMMON
@@ -599,11 +616,31 @@ config SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH
endif ## SND_SOC_SOF_JASPERLAKE
+if SND_SOC_SOF_HDA_LINK
+
+config SND_SOC_INTEL_SOF_SSP_AMP_MACH
+ tristate "SOF with amplifiers in I2S Mode"
+ depends on I2C && ACPI
+ depends on MFD_INTEL_LPSS || COMPILE_TEST
+ select SND_SOC_RT1308
+ select SND_SOC_CS35L41_I2C
+ select SND_SOC_DMIC
+ select SND_SOC_HDAC_HDMI
+ select SND_SOC_INTEL_HDA_DSP_COMMON
+ select SND_SOC_INTEL_SOF_REALTEK_COMMON
+ select SND_SOC_INTEL_SOF_CIRRUS_COMMON
+ help
+ This adds support for ASoC machine driver for SOF platforms
+ with RT1308/CS35L41 I2S audio codec.
+ Say Y if you have such a device.
+ If unsure select "N".
+endif ## SND_SOC_SOF_HDA_LINK
+
if SND_SOC_SOF_ELKHARTLAKE
config SND_SOC_INTEL_EHL_RT5660_MACH
tristate "EHL with RT5660 in I2S mode"
- depends on I2C && ACPI && GPIOLIB
+ 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_RT5660
@@ -619,7 +656,7 @@ if SND_SOC_SOF_INTEL_SOUNDWIRE
config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
tristate "SoundWire generic machine driver"
- depends on I2C && ACPI && GPIOLIB
+ depends on I2C && ACPI
depends on MFD_INTEL_LPSS || COMPILE_TEST
depends on SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES || COMPILE_TEST
depends on SOUNDWIRE
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index 3ea273d27168..40c0c3d1c500 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -19,10 +19,10 @@ 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 sof_realtek_common.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 sof_realtek_common.o
+snd-soc-sof_nau8825-objs := sof_nau8825.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
@@ -35,6 +35,7 @@ snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o
snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o
snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o
snd-soc-ehl-rt5660-objs := ehl_rt5660.o
+snd-soc-sof-ssp-amp-objs := sof_ssp_amp.o
snd-soc-sof-sdw-objs += sof_sdw.o \
sof_sdw_max98373.o \
sof_sdw_rt1308.o sof_sdw_rt1316.o \
@@ -79,6 +80,7 @@ obj-$(CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH) += snd-soc-skl_hda_dsp.o
obj-$(CONFIG_SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH) += snd-soc-sof_da7219_max98373.o
obj-$(CONFIG_SND_SOC_INTEL_EHL_RT5660_MACH) += snd-soc-ehl-rt5660.o
obj-$(CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH) += snd-soc-sof-sdw.o
+obj-$(CONFIG_SND_SOC_INTEL_SOF_SSP_AMP_MACH) += snd-soc-sof-ssp-amp.o
# common modules
snd-soc-intel-hda-dsp-common-objs := hda_dsp_common.o
@@ -86,3 +88,9 @@ 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
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
+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
+obj-$(CONFIG_SND_SOC_INTEL_SOF_CIRRUS_COMMON) += snd-soc-intel-sof-cirrus-common.o
diff --git a/sound/soc/intel/boards/bdw-rt5650.c b/sound/soc/intel/boards/bdw-rt5650.c
index 6cba5552f7a2..bc0eab1c304a 100644
--- a/sound/soc/intel/boards/bdw-rt5650.c
+++ b/sound/soc/intel/boards/bdw-rt5650.c
@@ -299,7 +299,7 @@ static int bdw_rt5650_probe(struct platform_device *pdev)
if (!bdw_rt5650)
return -ENOMEM;
- /* override plaform name, if required */
+ /* override platform name, if required */
mach = pdev->dev.platform_data;
ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5650_card,
mach->mach_params.platform);
diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c
index 119c441f4c10..071557fada29 100644
--- a/sound/soc/intel/boards/bdw-rt5677.c
+++ b/sound/soc/intel/boards/bdw-rt5677.c
@@ -426,7 +426,7 @@ static int bdw_rt5677_probe(struct platform_device *pdev)
if (!bdw_rt5677)
return -ENOMEM;
- /* override plaform name, if required */
+ /* override platform name, if required */
mach = pdev->dev.platform_data;
ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5677_card,
mach->mach_params.platform);
diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c
index 618d0645ed8d..d37c74fd1a3c 100644
--- a/sound/soc/intel/boards/broadwell.c
+++ b/sound/soc/intel/boards/broadwell.c
@@ -292,7 +292,7 @@ static int broadwell_audio_probe(struct platform_device *pdev)
broadwell_rt286.dev = &pdev->dev;
- /* override plaform name, if required */
+ /* override platform name, if required */
mach = pdev->dev.platform_data;
ret = snd_soc_fixup_dai_links_platform_name(&broadwell_rt286,
mach->mach_params.platform);
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
index b768d9b8ec02..9bc7b88e346b 100644
--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
@@ -825,7 +825,7 @@ static int broxton_audio_probe(struct platform_device *pdev)
}
}
- /* override plaform name, if required */
+ /* override platform name, if required */
mach = pdev->dev.platform_data;
platform_name = mach->mach_params.platform;
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
index 920e575b4314..05e833076499 100644
--- a/sound/soc/intel/boards/bxt_rt298.c
+++ b/sound/soc/intel/boards/bxt_rt298.c
@@ -628,7 +628,7 @@ static int broxton_audio_probe(struct platform_device *pdev)
card->dev = &pdev->dev;
snd_soc_card_set_drvdata(card, ctx);
- /* override plaform name, if required */
+ /* override platform name, if required */
mach = pdev->dev.platform_data;
platform_name = mach->mach_params.platform;
diff --git a/sound/soc/intel/boards/bytcht_cx2072x.c b/sound/soc/intel/boards/bytcht_cx2072x.c
index ffd497a5b5a5..96d3201efbbd 100644
--- a/sound/soc/intel/boards/bytcht_cx2072x.c
+++ b/sound/soc/intel/boards/bytcht_cx2072x.c
@@ -257,7 +257,7 @@ static int snd_byt_cht_cx2072x_probe(struct platform_device *pdev)
byt_cht_cx2072x_dais[dai_index].codecs->name = codec_name;
}
- /* override plaform name, if required */
+ /* override platform name, if required */
ret = snd_soc_fixup_dai_links_platform_name(&byt_cht_cx2072x_card,
mach->mach_params.platform);
if (ret)
diff --git a/sound/soc/intel/boards/bytcht_da7213.c b/sound/soc/intel/boards/bytcht_da7213.c
index fae1e7e785b0..eb19bf16afad 100644
--- a/sound/soc/intel/boards/bytcht_da7213.c
+++ b/sound/soc/intel/boards/bytcht_da7213.c
@@ -260,7 +260,7 @@ static int bytcht_da7213_probe(struct platform_device *pdev)
dailink[dai_index].codecs->name = codec_name;
}
- /* override plaform name, if required */
+ /* override platform name, if required */
platform_name = mach->mach_params.platform;
ret_val = snd_soc_fixup_dai_links_platform_name(card, platform_name);
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 9d86fea51a7d..e18371b5a771 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -497,7 +497,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
return -ENXIO;
}
- /* override plaform name, if required */
+ /* override platform name, if required */
byt_cht_es8316_card.dev = dev;
platform_name = mach->mach_params.platform;
@@ -535,7 +535,6 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
if (IS_ERR(priv->mclk))
return dev_err_probe(dev, PTR_ERR(priv->mclk), "clk_get pmc_plt_clk_3 failed\n");
- /* get speaker enable GPIO */
codec_dev = acpi_get_first_physical_node(adev);
if (!codec_dev)
return -EPROBE_DEFER;
@@ -561,6 +560,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
}
}
+ /* get speaker enable GPIO */
devm_acpi_dev_add_driver_gpios(codec_dev, byt_cht_es8316_gpios);
priv->speaker_en_gpio =
gpiod_get_optional(codec_dev, "speaker-enable",
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 2ace32c03ec9..d76a505052fb 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -1764,7 +1764,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
byt_rt5640_card.long_name = byt_rt5640_long_name;
#endif
- /* override plaform name, if required */
+ /* override platform name, if required */
platform_name = mach->mach_params.platform;
ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5640_card,
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
index 5e9c53dadbc7..39348d2b242f 100644
--- a/sound/soc/intel/boards/bytcr_rt5651.c
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -1088,7 +1088,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
byt_rt5651_card.long_name = byt_rt5651_long_name;
#endif
- /* override plaform name, if required */
+ /* override platform name, if required */
platform_name = mach->mach_params.platform;
ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5651_card,
diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c
index 504ef4cab111..8d8e96e3cd2d 100644
--- a/sound/soc/intel/boards/bytcr_wm5102.c
+++ b/sound/soc/intel/boards/bytcr_wm5102.c
@@ -389,7 +389,7 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev)
bool sof_parent;
int ret;
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_ATOMIC);
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index 1bc21434c9de..b3d7a0725ef2 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -296,7 +296,7 @@ static int cht_max98090_headset_init(struct snd_soc_component *component)
int ret;
/*
- * TI supports 4 butons headset detection
+ * TI supports 4 buttons headset detection
* KEY_MEDIA
* KEY_VOICECOMMAND
* KEY_VOLUMEUP
@@ -558,7 +558,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
dev_dbg(dev, "Unable to add GPIO mapping table\n");
}
- /* override plaform name, if required */
+ /* override platform name, if required */
snd_soc_card_cht.dev = &pdev->dev;
mach = pdev->dev.platform_data;
platform_name = mach->mach_params.platform;
diff --git a/sound/soc/intel/boards/cht_bsw_nau8824.c b/sound/soc/intel/boards/cht_bsw_nau8824.c
index bad32d2bdf89..da6c659de266 100644
--- a/sound/soc/intel/boards/cht_bsw_nau8824.c
+++ b/sound/soc/intel/boards/cht_bsw_nau8824.c
@@ -100,7 +100,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
struct snd_soc_component *component = codec_dai->component;
int ret, jack_type;
- /* NAU88L24 supports 4 butons headset detection
+ /* NAU88L24 supports 4 buttons headset detection
* KEY_PLAYPAUSE
* KEY_VOICECOMMAND
* KEY_VOLUMEUP
@@ -257,7 +257,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
return -ENOMEM;
snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
- /* override plaform name, if required */
+ /* override platform name, if required */
snd_soc_card_cht.dev = &pdev->dev;
mach = pdev->dev.platform_data;
platform_name = mach->mach_params.platform;
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index e182012d0c60..c21561c6a464 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -653,7 +653,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
(cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2))
cht_dailink[dai_index].cpus->dai_name = "ssp0-port";
- /* override plaform name, if required */
+ /* override platform name, if required */
platform_name = mach->mach_params.platform;
ret_val = snd_soc_fixup_dai_links_platform_name(card,
diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c
index 26eb8ad0d262..9882aeb24d33 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5672.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5672.c
@@ -483,7 +483,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
drv->use_ssp0 = true;
}
- /* override plaform name, if required */
+ /* override platform name, if required */
snd_soc_card_cht.dev = &pdev->dev;
platform_name = mach->mach_params.platform;
diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c b/sound/soc/intel/boards/glk_rt5682_max98357a.c
index bad3829e52ca..e4bfb0fe5f12 100644
--- a/sound/soc/intel/boards/glk_rt5682_max98357a.c
+++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c
@@ -638,7 +638,7 @@ static int geminilake_audio_probe(struct platform_device *pdev)
card->dev = &pdev->dev;
snd_soc_card_set_drvdata(card, ctx);
- /* override plaform name, if required */
+ /* override platform name, if required */
mach = pdev->dev.platform_data;
platform_name = mach->mach_params.platform;
diff --git a/sound/soc/intel/boards/haswell.c b/sound/soc/intel/boards/haswell.c
index 36e136acbef5..aa61e101f793 100644
--- a/sound/soc/intel/boards/haswell.c
+++ b/sound/soc/intel/boards/haswell.c
@@ -175,7 +175,7 @@ static int haswell_audio_probe(struct platform_device *pdev)
haswell_rt5640.dev = &pdev->dev;
- /* override plaform name, if required */
+ /* override platform name, if required */
mach = pdev->dev.platform_data;
ret = snd_soc_fixup_dai_links_platform_name(&haswell_rt5640,
mach->mach_params.platform);
diff --git a/sound/soc/intel/boards/sof_cirrus_common.c b/sound/soc/intel/boards/sof_cirrus_common.c
new file mode 100644
index 000000000000..e71d74ec1b0b
--- /dev/null
+++ b/sound/soc/intel/boards/sof_cirrus_common.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This file defines data structures and functions used in Machine
+ * Driver for Intel platforms with Cirrus Logic Codecs.
+ *
+ * Copyright 2022 Intel Corporation.
+ */
+#include <linux/module.h>
+#include <sound/sof.h>
+#include "../../codecs/cs35l41.h"
+#include "sof_cirrus_common.h"
+
+/*
+ * Cirrus Logic CS35L41/CS35L53
+ */
+static const struct snd_kcontrol_new cs35l41_kcontrols[] = {
+ SOC_DAPM_PIN_SWITCH("WL Spk"),
+ SOC_DAPM_PIN_SWITCH("WR Spk"),
+ SOC_DAPM_PIN_SWITCH("TL Spk"),
+ SOC_DAPM_PIN_SWITCH("TR Spk"),
+};
+
+static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = {
+ SND_SOC_DAPM_SPK("WL Spk", NULL),
+ SND_SOC_DAPM_SPK("WR Spk", NULL),
+ SND_SOC_DAPM_SPK("TL Spk", NULL),
+ SND_SOC_DAPM_SPK("TR Spk", NULL),
+};
+
+static const struct snd_soc_dapm_route cs35l41_dapm_routes[] = {
+ /* speaker */
+ {"WL Spk", NULL, "WL SPK"},
+ {"WR Spk", NULL, "WR SPK"},
+ {"TL Spk", NULL, "TL SPK"},
+ {"TR Spk", NULL, "TR SPK"},
+};
+
+static struct snd_soc_dai_link_component cs35l41_components[] = {
+ {
+ .name = CS35L41_DEV0_NAME,
+ .dai_name = CS35L41_CODEC_DAI,
+ },
+ {
+ .name = CS35L41_DEV1_NAME,
+ .dai_name = CS35L41_CODEC_DAI,
+ },
+ {
+ .name = CS35L41_DEV2_NAME,
+ .dai_name = CS35L41_CODEC_DAI,
+ },
+ {
+ .name = CS35L41_DEV3_NAME,
+ .dai_name = CS35L41_CODEC_DAI,
+ },
+};
+
+static struct snd_soc_codec_conf cs35l41_codec_conf[] = {
+ {
+ .dlc = COMP_CODEC_CONF(CS35L41_DEV0_NAME),
+ .name_prefix = "WL",
+ },
+ {
+ .dlc = COMP_CODEC_CONF(CS35L41_DEV1_NAME),
+ .name_prefix = "WR",
+ },
+ {
+ .dlc = COMP_CODEC_CONF(CS35L41_DEV2_NAME),
+ .name_prefix = "TL",
+ },
+ {
+ .dlc = COMP_CODEC_CONF(CS35L41_DEV3_NAME),
+ .name_prefix = "TR",
+ },
+};
+
+static int cs35l41_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ int ret;
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, cs35l41_dapm_widgets,
+ ARRAY_SIZE(cs35l41_dapm_widgets));
+ if (ret) {
+ dev_err(rtd->dev, "fail to add dapm controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_add_card_controls(card, cs35l41_kcontrols,
+ ARRAY_SIZE(cs35l41_kcontrols));
+ if (ret) {
+ dev_err(rtd->dev, "fail to add card controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_add_routes(&card->dapm, cs35l41_dapm_routes,
+ ARRAY_SIZE(cs35l41_dapm_routes));
+
+ if (ret)
+ dev_err(rtd->dev, "fail to add dapm routes, ret %d\n", ret);
+
+ return ret;
+}
+
+static int cs35l41_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_dai *codec_dai;
+ int clk_freq, i, ret;
+
+ clk_freq = sof_dai_get_bclk(rtd); /* BCLK freq */
+
+ if (clk_freq <= 0) {
+ dev_err(rtd->dev, "fail to get bclk freq, ret %d\n", clk_freq);
+ return -EINVAL;
+ }
+
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
+ /* call dai driver's set_sysclk() callback */
+ ret = snd_soc_dai_set_sysclk(codec_dai, CS35L41_CLKID_SCLK,
+ clk_freq, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n",
+ ret);
+ return ret;
+ }
+
+ /* call component driver's set_sysclk() callback */
+ ret = snd_soc_component_set_sysclk(codec_dai->component,
+ CS35L41_CLKID_SCLK, 0,
+ clk_freq, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(codec_dai->dev, "fail to set component sysclk, ret %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_ops cs35l41_ops = {
+ .hw_params = cs35l41_hw_params,
+};
+
+void cs35l41_set_dai_link(struct snd_soc_dai_link *link)
+{
+ link->codecs = cs35l41_components;
+ link->num_codecs = ARRAY_SIZE(cs35l41_components);
+ link->init = cs35l41_init;
+ link->ops = &cs35l41_ops;
+}
+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);
+
+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
new file mode 100644
index 000000000000..ca438c12c386
--- /dev/null
+++ b/sound/soc/intel/boards/sof_cirrus_common.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * This file defines data structures used in Machine Driver for Intel
+ * platforms with Cirrus Logic Codecs.
+ *
+ * Copyright 2022 Intel Corporation.
+ */
+#ifndef __SOF_CIRRUS_COMMON_H
+#define __SOF_CIRRUS_COMMON_H
+
+#include <sound/soc.h>
+
+/*
+ * Cirrus Logic CS35L41/CS35L53
+ */
+#define CS35L41_CODEC_DAI "cs35l41-pcm"
+#define CS35L41_DEV0_NAME "i2c-CSC3541:00"
+#define CS35L41_DEV1_NAME "i2c-CSC3541:01"
+#define CS35L41_DEV2_NAME "i2c-CSC3541:02"
+#define CS35L41_DEV3_NAME "i2c-CSC3541:03"
+
+void cs35l41_set_dai_link(struct snd_soc_dai_link *link);
+void cs35l41_set_codec_conf(struct snd_soc_card *card);
+
+#endif /* __SOF_CIRRUS_COMMON_H */
diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
index 20d577eaab6d..5e0529aa4f1d 100644
--- a/sound/soc/intel/boards/sof_es8336.c
+++ b/sound/soc/intel/boards/sof_es8336.c
@@ -21,11 +21,15 @@
#include <sound/soc-acpi.h>
#include "hda_dsp_common.h"
+/* jd-inv + terminating entry */
+#define MAX_NO_PROPS 2
+
#define SOF_ES8336_SSP_CODEC(quirk) ((quirk) & GENMASK(3, 0))
#define SOF_ES8336_SSP_CODEC_MASK (GENMASK(3, 0))
#define SOF_ES8336_TGL_GPIO_QUIRK BIT(4)
#define SOF_ES8336_ENABLE_DMIC BIT(5)
+#define SOF_ES8336_JD_INVERTED BIT(6)
static unsigned long quirk;
@@ -63,7 +67,14 @@ static const struct acpi_gpio_mapping *gpio_mapping = acpi_es8336_gpios;
static void log_quirks(struct device *dev)
{
- dev_info(dev, "quirk SSP%ld", SOF_ES8336_SSP_CODEC(quirk));
+ dev_info(dev, "quirk mask %#lx\n", quirk);
+ dev_info(dev, "quirk SSP%ld\n", SOF_ES8336_SSP_CODEC(quirk));
+ if (quirk & SOF_ES8336_ENABLE_DMIC)
+ dev_info(dev, "quirk DMIC enabled\n");
+ if (quirk & SOF_ES8336_TGL_GPIO_QUIRK)
+ dev_info(dev, "quirk TGL GPIO enabled\n");
+ if (quirk & SOF_ES8336_JD_INVERTED)
+ dev_info(dev, "quirk JD inverted enabled\n");
}
static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
@@ -228,24 +239,25 @@ static int sof_es8336_quirk_cb(const struct dmi_system_id *id)
return 1;
}
+/*
+ * this table should only be used to add GPIO or jack-detection quirks
+ * that cannot be detected from ACPI tables. The SSP and DMIC
+ * information are providing by the platform driver and are aligned
+ * with the topology used.
+ *
+ * If the GPIO support is missing, the quirk parameter can be used to
+ * enable speakers. In that case it's recommended to keep the SSP and DMIC
+ * information consistent, overriding the SSP and DMIC can only be done
+ * if the topology file is modified as well.
+ */
static const struct dmi_system_id sof_es8336_quirk_table[] = {
{
.callback = sof_es8336_quirk_cb,
.matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "CHUWI Innovation And Technology"),
- DMI_MATCH(DMI_BOARD_NAME, "Hi10 X"),
- },
- .driver_data = (void *)SOF_ES8336_SSP_CODEC(2)
- },
- {
- .callback = sof_es8336_quirk_cb,
- .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "IP3 tech"),
DMI_MATCH(DMI_BOARD_NAME, "WN1"),
},
- .driver_data = (void *)(SOF_ES8336_SSP_CODEC(0) |
- SOF_ES8336_TGL_GPIO_QUIRK |
- SOF_ES8336_ENABLE_DMIC)
+ .driver_data = (void *)(SOF_ES8336_TGL_GPIO_QUIRK)
},
{}
};
@@ -280,7 +292,7 @@ static struct snd_soc_dai_link_component platform_component[] = {
}
};
-SND_SOC_DAILINK_DEF(ssp1_codec,
+SND_SOC_DAILINK_DEF(es8336_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ESSX8336:00", "ES8316 HiFi")));
static struct snd_soc_dai_link_component dmic_component[] = {
@@ -344,8 +356,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
goto devm_err;
links[id].id = id;
- links[id].codecs = ssp1_codec;
- links[id].num_codecs = ARRAY_SIZE(ssp1_codec);
+ links[id].codecs = es8336_codec;
+ links[id].num_codecs = ARRAY_SIZE(es8336_codec);
links[id].platforms = platform_component;
links[id].num_platforms = ARRAY_SIZE(platform_component);
links[id].init = sof_es8316_init;
@@ -447,6 +459,8 @@ devm_err:
return NULL;
}
+static char soc_components[30];
+
/* i2c-<HID>:00 with HID being 8 chars */
static char codec_name[SND_ACPI_I2C_ID_LEN];
@@ -455,10 +469,13 @@ static int sof_es8336_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct snd_soc_card *card;
struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
+ struct property_entry props[MAX_NO_PROPS] = {};
struct sof_es8336_private *priv;
+ struct fwnode_handle *fwnode;
struct acpi_device *adev;
struct snd_soc_dai_link *dai_links;
struct device *codec_dev;
+ unsigned int cnt = 0;
int dmic_be_num = 0;
int hdmi_num = 3;
int ret;
@@ -470,11 +487,33 @@ static int sof_es8336_probe(struct platform_device *pdev)
card = &sof_es8336_card;
card->dev = dev;
- if (!dmi_check_system(sof_es8336_quirk_table))
- quirk = SOF_ES8336_SSP_CODEC(2);
+ /* check GPIO DMI quirks */
+ dmi_check_system(sof_es8336_quirk_table);
- if (quirk & SOF_ES8336_ENABLE_DMIC)
- dmic_be_num = 2;
+ if (!mach->mach_params.i2s_link_mask) {
+ dev_warn(dev, "No I2S link information provided, using SSP0. This may need to be modified with the quirk module parameter\n");
+ } else {
+ /*
+ * Set configuration based on platform NHLT.
+ * In this machine driver, we can only support one SSP for the
+ * ES8336 link, the else-if below are intentional.
+ * In some cases multiple SSPs can be reported by NHLT, starting MSB-first
+ * seems to pick the right connection.
+ */
+ unsigned long ssp = 0;
+
+ if (mach->mach_params.i2s_link_mask & BIT(2))
+ ssp = SOF_ES8336_SSP_CODEC(2);
+ else if (mach->mach_params.i2s_link_mask & BIT(1))
+ ssp = SOF_ES8336_SSP_CODEC(1);
+ else if (mach->mach_params.i2s_link_mask & BIT(0))
+ ssp = SOF_ES8336_SSP_CODEC(0);
+
+ quirk |= ssp;
+ }
+
+ if (mach->mach_params.dmic_num)
+ quirk |= SOF_ES8336_ENABLE_DMIC;
if (quirk_override != -1) {
dev_info(dev, "Overriding quirk 0x%lx => 0x%x\n",
@@ -483,6 +522,9 @@ static int sof_es8336_probe(struct platform_device *pdev)
}
log_quirks(dev);
+ if (quirk & SOF_ES8336_ENABLE_DMIC)
+ dmic_be_num = 2;
+
sof_es8336_card.num_links += dmic_be_num + hdmi_num;
dai_links = sof_card_dai_links_create(dev,
SOF_ES8336_SSP_CODEC(quirk),
@@ -499,6 +541,13 @@ static int sof_es8336_probe(struct platform_device *pdev)
"i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
dai_links[0].codecs->name = codec_name;
+
+ /* also fixup codec dai name if relevant */
+ if (!strncmp(mach->id, "ESSX8326", SND_ACPI_I2C_ID_LEN))
+ dai_links[0].codecs->dai_name = "ES8326 HiFi";
+ } else {
+ dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
+ return -ENXIO;
}
ret = snd_soc_fixup_dai_links_platform_name(&sof_es8336_card,
@@ -506,38 +555,64 @@ static int sof_es8336_probe(struct platform_device *pdev)
if (ret)
return ret;
- /* get speaker enable GPIO */
- codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL, codec_name);
+ codec_dev = acpi_get_first_physical_node(adev);
if (!codec_dev)
return -EPROBE_DEFER;
+ priv->codec_dev = get_device(codec_dev);
+
+ if (quirk & SOF_ES8336_JD_INVERTED)
+ props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted");
+
+ if (cnt) {
+ fwnode = fwnode_create_software_node(props, NULL);
+ if (IS_ERR(fwnode)) {
+ put_device(codec_dev);
+ return PTR_ERR(fwnode);
+ }
+
+ ret = device_add_software_node(codec_dev, to_software_node(fwnode));
+ fwnode_handle_put(fwnode);
+
+ if (ret) {
+ put_device(codec_dev);
+ return ret;
+ }
+ }
+
+ /* get speaker enable GPIO */
ret = devm_acpi_dev_add_driver_gpios(codec_dev, gpio_mapping);
if (ret)
dev_warn(codec_dev, "unable to add GPIO mapping table\n");
- priv->gpio_pa = gpiod_get(codec_dev, "pa-enable", GPIOD_OUT_LOW);
+ priv->gpio_pa = gpiod_get_optional(codec_dev, "pa-enable", GPIOD_OUT_LOW);
if (IS_ERR(priv->gpio_pa)) {
- ret = PTR_ERR(priv->gpio_pa);
- dev_err(codec_dev, "%s, could not get pa-enable: %d\n",
- __func__, ret);
- goto err;
+ ret = dev_err_probe(dev, PTR_ERR(priv->gpio_pa),
+ "could not get pa-enable GPIO\n");
+ goto err_put_codec;
}
- priv->codec_dev = codec_dev;
INIT_LIST_HEAD(&priv->hdmi_pcm_list);
snd_soc_card_set_drvdata(card, priv);
+ if (mach->mach_params.dmic_num > 0) {
+ snprintf(soc_components, sizeof(soc_components),
+ "cfg-dmics:%d", mach->mach_params.dmic_num);
+ card->components = soc_components;
+ }
+
ret = devm_snd_soc_register_card(dev, card);
if (ret) {
gpiod_put(priv->gpio_pa);
dev_err(dev, "snd_soc_register_card failed: %d\n", ret);
- goto err;
+ goto err_put_codec;
}
platform_set_drvdata(pdev, &sof_es8336_card);
return 0;
-err:
+err_put_codec:
+ device_remove_software_node(priv->codec_dev);
put_device(codec_dev);
return ret;
}
@@ -548,6 +623,7 @@ static int sof_es8336_remove(struct platform_device *pdev)
struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
gpiod_put(priv->gpio_pa);
+ device_remove_software_node(priv->codec_dev);
put_device(priv->codec_dev);
return 0;
diff --git a/sound/soc/intel/boards/sof_realtek_common.c b/sound/soc/intel/boards/sof_realtek_common.c
index 4cf131310ad3..a2bcbeee0216 100644
--- a/sound/soc/intel/boards/sof_realtek_common.c
+++ b/sound/soc/intel/boards/sof_realtek_common.c
@@ -10,9 +10,11 @@
#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 "../../codecs/rt1011.h"
#include "../../codecs/rt1015.h"
+#include "../../codecs/rt1308.h"
#include "sof_realtek_common.h"
/*
@@ -132,12 +134,14 @@ void sof_rt1011_dai_link(struct snd_soc_dai_link *link)
link->init = rt1011_init;
link->ops = &rt1011_ops;
}
+EXPORT_SYMBOL_NS(sof_rt1011_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
void sof_rt1011_codec_conf(struct snd_soc_card *card)
{
card->codec_conf = rt1011_codec_confs;
card->num_configs = ARRAY_SIZE(rt1011_codec_confs);
}
+EXPORT_SYMBOL_NS(sof_rt1011_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON);
/*
* rt1015: i2c mode driver for ALC1015 and ALC1015Q
@@ -233,6 +237,7 @@ void sof_rt1015p_dai_link(struct snd_soc_dai_link *link)
link->init = rt1015p_init;
link->ops = &rt1015p_ops;
}
+EXPORT_SYMBOL_NS(sof_rt1015p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
void sof_rt1015p_codec_conf(struct snd_soc_card *card)
{
@@ -242,6 +247,7 @@ void sof_rt1015p_codec_conf(struct snd_soc_card *card)
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);
/*
* RT1015 audio amplifier
@@ -343,6 +349,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);
void sof_rt1015_dai_link(struct snd_soc_dai_link *link, unsigned int fs)
{
@@ -354,3 +361,103 @@ void sof_rt1015_dai_link(struct snd_soc_dai_link *link, unsigned int fs)
if (fs == 100)
rt1015_ops.hw_params = rt1015_hw_params_pll_and_tdm;
}
+EXPORT_SYMBOL_NS(sof_rt1015_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
+
+/*
+ * RT1308 audio amplifier
+ */
+static const struct snd_kcontrol_new rt1308_kcontrols[] = {
+ SOC_DAPM_PIN_SWITCH("Speakers"),
+};
+
+static const struct snd_soc_dapm_widget rt1308_dapm_widgets[] = {
+ SND_SOC_DAPM_SPK("Speakers", NULL),
+};
+
+static const struct snd_soc_dapm_route rt1308_dapm_routes[] = {
+ /* speaker */
+ {"Speakers", NULL, "SPOL"},
+ {"Speakers", NULL, "SPOR"},
+};
+
+static struct snd_soc_dai_link_component rt1308_components[] = {
+ {
+ .name = RT1308_DEV0_NAME,
+ .dai_name = RT1308_CODEC_DAI,
+ }
+};
+
+static int rt1308_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ int ret;
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, rt1308_dapm_widgets,
+ ARRAY_SIZE(rt1308_dapm_widgets));
+ if (ret) {
+ dev_err(rtd->dev, "fail to add dapm controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_add_card_controls(card, rt1308_kcontrols,
+ ARRAY_SIZE(rt1308_kcontrols));
+ if (ret) {
+ dev_err(rtd->dev, "fail to add card controls, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_dapm_routes,
+ ARRAY_SIZE(rt1308_dapm_routes));
+
+ if (ret)
+ dev_err(rtd->dev, "fail to add dapm routes, ret %d\n", ret);
+
+ return ret;
+}
+
+static int rt1308_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ int clk_id, clk_freq, pll_out;
+ int ret;
+
+ clk_id = RT1308_PLL_S_MCLK;
+ /* get the tplg configured mclk. */
+ clk_freq = sof_dai_get_mclk(rtd);
+
+ pll_out = params_rate(params) * 512;
+
+ /* Set rt1308 pll */
+ ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out);
+ if (ret < 0) {
+ dev_err(card->dev, "Failed to set RT1308 PLL: %d\n", ret);
+ return ret;
+ }
+
+ /* Set rt1308 sysclk */
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT1308_FS_SYS_S_PLL, pll_out,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ dev_err(card->dev, "Failed to set RT1308 SYSCLK: %d\n", ret);
+
+ return ret;
+}
+
+static const struct snd_soc_ops rt1308_ops = {
+ .hw_params = rt1308_hw_params,
+};
+
+void sof_rt1308_dai_link(struct snd_soc_dai_link *link)
+{
+ link->codecs = rt1308_components;
+ link->num_codecs = ARRAY_SIZE(rt1308_components);
+ link->init = rt1308_init;
+ link->ops = &rt1308_ops;
+}
+EXPORT_SYMBOL_NS(sof_rt1308_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 228ac9c08430..e0a5518e8dd2 100644
--- a/sound/soc/intel/boards/sof_realtek_common.h
+++ b/sound/soc/intel/boards/sof_realtek_common.h
@@ -35,4 +35,8 @@ void sof_rt1015p_codec_conf(struct snd_soc_card *card);
void sof_rt1015_dai_link(struct snd_soc_dai_link *link, unsigned int fs);
void sof_rt1015_codec_conf(struct snd_soc_card *card);
+#define RT1308_CODEC_DAI "rt1308-aif"
+#define RT1308_DEV0_NAME "i2c-10EC1308:00"
+void sof_rt1308_dai_link(struct snd_soc_dai_link *link);
+
#endif /* __SOF_REALTEK_COMMON_H */
diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
index bd6d2e7dea53..ebec4d15edaa 100644
--- a/sound/soc/intel/boards/sof_rt5682.c
+++ b/sound/soc/intel/boards/sof_rt5682.c
@@ -81,6 +81,7 @@ struct sof_card_private {
struct snd_soc_jack sof_headset;
struct list_head hdmi_pcm_list;
bool common_hdmi_codec_drv;
+ bool idisp_codec;
};
static int sof_rt5682_quirk_cb(const struct dmi_system_id *id)
@@ -369,11 +370,16 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
pll_out = params_rate(params) * 512;
- /* Configure pll for codec */
- ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, pll_in,
- pll_out);
- if (ret < 0)
- dev_err(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret);
+ /* when MCLK is 512FS, no need to set PLL configuration additionally. */
+ if (pll_in == pll_out)
+ clk_id = RT5682S_SCLK_S_MCLK;
+ else {
+ /* Configure pll for codec */
+ ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, pll_in,
+ pll_out);
+ if (ret < 0)
+ dev_err(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret);
+ }
/* Configure sysclk for codec */
ret = snd_soc_dai_set_sysclk(codec_dai, clk_id,
@@ -417,7 +423,7 @@ static int sof_card_late_probe(struct snd_soc_card *card)
int i = 0;
/* HDMI is not supported by SOF on Baytrail/CherryTrail */
- if (is_legacy_cpu)
+ if (is_legacy_cpu || !ctx->idisp_codec)
return 0;
if (list_empty(&ctx->hdmi_pcm_list))
@@ -558,11 +564,14 @@ static struct snd_soc_dai_link_component dummy_component[] = {
}
};
+#define IDISP_CODEC_MASK 0x4
+
static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
int ssp_codec,
int ssp_amp,
int dmic_be_num,
- int hdmi_num)
+ int hdmi_num,
+ bool idisp_codec)
{
struct snd_soc_dai_link_component *idisp_components;
struct snd_soc_dai_link_component *cpus;
@@ -676,13 +685,18 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
if (!links[id].cpus->dai_name)
goto devm_err;
- idisp_components[i - 1].name = "ehdaudio0D2";
- idisp_components[i - 1].dai_name = devm_kasprintf(dev,
- GFP_KERNEL,
- "intel-hdmi-hifi%d",
- i);
- if (!idisp_components[i - 1].dai_name)
- goto devm_err;
+ if (idisp_codec) {
+ idisp_components[i - 1].name = "ehdaudio0D2";
+ idisp_components[i - 1].dai_name = devm_kasprintf(dev,
+ GFP_KERNEL,
+ "intel-hdmi-hifi%d",
+ i);
+ if (!idisp_components[i - 1].dai_name)
+ goto devm_err;
+ } else {
+ idisp_components[i - 1].name = "snd-soc-dummy";
+ idisp_components[i - 1].dai_name = "snd-soc-dummy-dai";
+ }
links[id].codecs = &idisp_components[i - 1];
links[id].num_codecs = 1;
@@ -838,6 +852,9 @@ static int sof_audio_probe(struct platform_device *pdev)
/* default number of HDMI DAI's */
if (!hdmi_num)
hdmi_num = 3;
+
+ if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
+ ctx->idisp_codec = true;
}
/* need to get main clock from pmc */
@@ -892,7 +909,7 @@ static int sof_audio_probe(struct platform_device *pdev)
sof_audio_card_rt5682.num_links++;
dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
- dmic_be_num, hdmi_num);
+ dmic_be_num, hdmi_num, ctx->idisp_codec);
if (!dai_links)
return -ENOMEM;
@@ -1033,6 +1050,14 @@ static const struct platform_device_id board_ids[] = {
SOF_BT_OFFLOAD_SSP(2) |
SOF_SSP_BT_OFFLOAD_PRESENT),
},
+ {
+ .name = "adl_rt5682",
+ .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
+ SOF_RT5682_SSP_CODEC(0) |
+ SOF_RT5682_NUM_HDMIDEV(4) |
+ SOF_BT_OFFLOAD_SSP(2) |
+ SOF_SSP_BT_OFFLOAD_PRESENT),
+ },
{ }
};
MODULE_DEVICE_TABLE(platform, board_ids);
@@ -1056,3 +1081,4 @@ MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_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 da515eb1ddbe..1f00679b4240 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -185,7 +185,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
- DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Conv"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
SOF_SDW_PCH_DMIC |
diff --git a/sound/soc/intel/boards/sof_ssp_amp.c b/sound/soc/intel/boards/sof_ssp_amp.c
new file mode 100644
index 000000000000..88530e9de543
--- /dev/null
+++ b/sound/soc/intel/boards/sof_ssp_amp.c
@@ -0,0 +1,483 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright(c) 2022 Intel Corporation. All rights reserved.
+
+/*
+ * sof_ssp_amp.c - ASoc Machine driver for Intel platforms
+ * with RT1308/CS35L41 codec.
+ */
+
+#include <linux/acpi.h>
+#include <linux/delay.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/sof.h>
+#include "../../codecs/hdac_hdmi.h"
+#include "hda_dsp_common.h"
+#include "sof_realtek_common.h"
+#include "sof_cirrus_common.h"
+
+#define NAME_SIZE 32
+
+/* 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_SSP_HDMI_CAPTURE_PRESENT BIT(4)
+#define SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT 5
+#define SOF_NO_OF_HDMI_CAPTURE_SSP_MASK (GENMASK(6, 5))
+#define SOF_NO_OF_HDMI_CAPTURE_SSP(quirk) \
+ (((quirk) << SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT) & SOF_NO_OF_HDMI_CAPTURE_SSP_MASK)
+
+#define SOF_HDMI_CAPTURE_1_SSP_SHIFT 7
+#define SOF_HDMI_CAPTURE_1_SSP_MASK (GENMASK(9, 7))
+#define SOF_HDMI_CAPTURE_1_SSP(quirk) \
+ (((quirk) << SOF_HDMI_CAPTURE_1_SSP_SHIFT) & SOF_HDMI_CAPTURE_1_SSP_MASK)
+
+#define SOF_HDMI_CAPTURE_2_SSP_SHIFT 10
+#define SOF_HDMI_CAPTURE_2_SSP_MASK (GENMASK(12, 10))
+#define SOF_HDMI_CAPTURE_2_SSP(quirk) \
+ (((quirk) << SOF_HDMI_CAPTURE_2_SSP_SHIFT) & SOF_HDMI_CAPTURE_2_SSP_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)
+
+/* Speaker amplifiers */
+#define SOF_RT1308_SPEAKER_AMP_PRESENT BIT(21)
+#define SOF_CS35L41_SPEAKER_AMP_PRESENT BIT(22)
+
+/* Default: SSP2 */
+static unsigned long sof_ssp_amp_quirk = SOF_AMPLIFIER_SSP(2);
+
+struct sof_hdmi_pcm {
+ struct list_head head;
+ struct snd_soc_jack sof_hdmi;
+ struct snd_soc_dai *codec_dai;
+ int device;
+};
+
+struct sof_card_private {
+ struct list_head hdmi_pcm_list;
+ bool common_hdmi_codec_drv;
+ bool idisp_codec;
+};
+
+static const struct snd_soc_dapm_widget sof_ssp_amp_dapm_widgets[] = {
+ SND_SOC_DAPM_MIC("SoC DMIC", NULL),
+};
+
+static const struct snd_soc_dapm_route sof_ssp_amp_dapm_routes[] = {
+ /* digital mics */
+ {"DMic", NULL, "SoC DMIC"},
+};
+
+static int sof_card_late_probe(struct snd_soc_card *card)
+{
+ struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
+ struct snd_soc_component *component = NULL;
+ char jack_name[NAME_SIZE];
+ struct sof_hdmi_pcm *pcm;
+ int err;
+ int i = 0;
+
+ if (!(sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT))
+ return 0;
+
+ /* HDMI is not supported by SOF on Baytrail/CherryTrail */
+ if (!ctx->idisp_codec)
+ return 0;
+
+ if (list_empty(&ctx->hdmi_pcm_list))
+ return -EINVAL;
+
+ if (ctx->common_hdmi_codec_drv) {
+ pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
+ head);
+ component = pcm->codec_dai->component;
+ return hda_dsp_hdmi_build_controls(card, component);
+ }
+
+ list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
+ component = pcm->codec_dai->component;
+ snprintf(jack_name, sizeof(jack_name),
+ "HDMI/DP, pcm=%d Jack", pcm->device);
+ err = snd_soc_card_jack_new(card, jack_name,
+ SND_JACK_AVOUT, &pcm->sof_hdmi,
+ NULL, 0);
+
+ if (err)
+ return err;
+
+ err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
+ &pcm->sof_hdmi);
+ if (err < 0)
+ return err;
+
+ i++;
+ }
+
+ return hdac_hdmi_jack_port_init(component, &card->dapm);
+}
+
+static struct snd_soc_card sof_ssp_amp_card = {
+ .name = "ssp_amp",
+ .owner = THIS_MODULE,
+ .dapm_widgets = sof_ssp_amp_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(sof_ssp_amp_dapm_widgets),
+ .dapm_routes = sof_ssp_amp_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(sof_ssp_amp_dapm_routes),
+ .fully_routed = true,
+ .late_probe = sof_card_late_probe,
+};
+
+static struct snd_soc_dai_link_component platform_component[] = {
+ {
+ /* name might be overridden during probe */
+ .name = "0000:00:1f.3"
+ }
+};
+
+static struct snd_soc_dai_link_component dmic_component[] = {
+ {
+ .name = "dmic-codec",
+ .dai_name = "dmic-hifi",
+ }
+};
+
+static struct snd_soc_dai_link_component dummy_component[] = {
+ {
+ .name = "snd-soc-dummy",
+ .dai_name = "snd-soc-dummy-dai",
+ }
+};
+
+static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
+ struct sof_hdmi_pcm *pcm;
+
+ pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
+ if (!pcm)
+ return -ENOMEM;
+
+ /* dai_link id is 1:1 mapped to the PCM device */
+ pcm->device = rtd->dai_link->id;
+ pcm->codec_dai = dai;
+
+ list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
+
+ return 0;
+}
+
+#define IDISP_CODEC_MASK 0x4
+
+static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
+ int ssp_codec,
+ int dmic_be_num,
+ int hdmi_num,
+ bool idisp_codec)
+{
+ struct snd_soc_dai_link_component *idisp_components;
+ struct snd_soc_dai_link_component *cpus;
+ struct snd_soc_dai_link *links;
+ int i, id = 0;
+
+ links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) *
+ sof_ssp_amp_card.num_links, GFP_KERNEL);
+ cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component) *
+ sof_ssp_amp_card.num_links, GFP_KERNEL);
+ if (!links || !cpus)
+ return NULL;
+
+ /* HDMI-In SSP */
+ if (sof_ssp_amp_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT) {
+ int num_of_hdmi_ssp = (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_CAPTURE_SSP_MASK) >>
+ SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT;
+
+ for (i = 1; i <= num_of_hdmi_ssp; i++) {
+ int port = (i == 1 ? (sof_ssp_amp_quirk & SOF_HDMI_CAPTURE_1_SSP_MASK) >>
+ SOF_HDMI_CAPTURE_1_SSP_SHIFT :
+ (sof_ssp_amp_quirk & SOF_HDMI_CAPTURE_2_SSP_MASK) >>
+ SOF_HDMI_CAPTURE_2_SSP_SHIFT);
+
+ links[id].cpus = &cpus[id];
+ links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
+ "SSP%d Pin", port);
+ if (!links[id].cpus->dai_name)
+ return NULL;
+ links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-HDMI", port);
+ if (!links[id].name)
+ return NULL;
+ links[id].id = id;
+ links[id].codecs = dummy_component;
+ links[id].num_codecs = ARRAY_SIZE(dummy_component);
+ links[id].platforms = platform_component;
+ links[id].num_platforms = ARRAY_SIZE(platform_component);
+ links[id].dpcm_capture = 1;
+ links[id].no_pcm = 1;
+ links[id].num_cpus = 1;
+ id++;
+ }
+ }
+
+ /* codec SSP */
+ links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_codec);
+ if (!links[id].name)
+ return NULL;
+
+ links[id].id = id;
+ if (sof_ssp_amp_quirk & SOF_RT1308_SPEAKER_AMP_PRESENT) {
+ sof_rt1308_dai_link(&links[id]);
+ } else if (sof_ssp_amp_quirk & SOF_CS35L41_SPEAKER_AMP_PRESENT) {
+ cs35l41_set_dai_link(&links[id]);
+ }
+ links[id].platforms = platform_component;
+ links[id].num_platforms = ARRAY_SIZE(platform_component);
+ links[id].dpcm_playback = 1;
+ links[id].no_pcm = 1;
+ links[id].cpus = &cpus[id];
+ links[id].num_cpus = 1;
+ links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_codec);
+ if (!links[id].cpus->dai_name)
+ return NULL;
+
+ id++;
+
+ /* dmic */
+ if (dmic_be_num > 0) {
+ /* at least we have dmic01 */
+ links[id].name = "dmic01";
+ links[id].cpus = &cpus[id];
+ links[id].cpus->dai_name = "DMIC01 Pin";
+ if (dmic_be_num > 1) {
+ /* set up 2 BE links at most */
+ links[id + 1].name = "dmic16k";
+ links[id + 1].cpus = &cpus[id + 1];
+ links[id + 1].cpus->dai_name = "DMIC16k Pin";
+ dmic_be_num = 2;
+ }
+ }
+
+ for (i = 0; i < dmic_be_num; i++) {
+ links[id].id = id;
+ links[id].num_cpus = 1;
+ links[id].codecs = dmic_component;
+ links[id].num_codecs = ARRAY_SIZE(dmic_component);
+ links[id].platforms = platform_component;
+ links[id].num_platforms = ARRAY_SIZE(platform_component);
+ links[id].ignore_suspend = 1;
+ links[id].dpcm_capture = 1;
+ links[id].no_pcm = 1;
+ id++;
+ }
+
+ /* HDMI playback */
+ if (sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT) {
+ /* HDMI */
+ if (hdmi_num > 0) {
+ idisp_components = devm_kzalloc(dev,
+ sizeof(struct snd_soc_dai_link_component) *
+ hdmi_num, GFP_KERNEL);
+ if (!idisp_components)
+ goto devm_err;
+ }
+ for (i = 1; i <= hdmi_num; i++) {
+ links[id].name = devm_kasprintf(dev, GFP_KERNEL,
+ "iDisp%d", i);
+ if (!links[id].name)
+ goto devm_err;
+
+ links[id].id = id;
+ links[id].cpus = &cpus[id];
+ links[id].num_cpus = 1;
+ links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
+ "iDisp%d Pin", i);
+ if (!links[id].cpus->dai_name)
+ goto devm_err;
+
+ if (idisp_codec) {
+ idisp_components[i - 1].name = "ehdaudio0D2";
+ idisp_components[i - 1].dai_name = devm_kasprintf(dev,
+ GFP_KERNEL,
+ "intel-hdmi-hifi%d",
+ i);
+ if (!idisp_components[i - 1].dai_name)
+ goto devm_err;
+ } else {
+ idisp_components[i - 1].name = "snd-soc-dummy";
+ idisp_components[i - 1].dai_name = "snd-soc-dummy-dai";
+ }
+
+ links[id].codecs = &idisp_components[i - 1];
+ links[id].num_codecs = 1;
+ links[id].platforms = platform_component;
+ links[id].num_platforms = ARRAY_SIZE(platform_component);
+ links[id].init = sof_hdmi_init;
+ links[id].dpcm_playback = 1;
+ links[id].no_pcm = 1;
+ id++;
+ }
+ }
+
+ /* 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;
+
+ links[id].id = id;
+ links[id].cpus = &cpus[id];
+ links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
+ "SSP%d Pin", port);
+ if (!links[id].cpus->dai_name)
+ goto devm_err;
+ links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
+ if (!links[id].name)
+ goto devm_err;
+ links[id].codecs = dummy_component;
+ links[id].num_codecs = ARRAY_SIZE(dummy_component);
+ links[id].platforms = platform_component;
+ links[id].num_platforms = ARRAY_SIZE(platform_component);
+ links[id].dpcm_playback = 1;
+ links[id].dpcm_capture = 1;
+ links[id].no_pcm = 1;
+ links[id].num_cpus = 1;
+ id++;
+ }
+
+ return links;
+devm_err:
+ return NULL;
+}
+
+static int sof_ssp_amp_probe(struct platform_device *pdev)
+{
+ struct snd_soc_dai_link *dai_links;
+ struct snd_soc_acpi_mach *mach;
+ struct sof_card_private *ctx;
+ int dmic_be_num, hdmi_num = 0;
+ int ret, ssp_codec;
+
+ 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;
+
+ mach = pdev->dev.platform_data;
+
+ dmic_be_num = mach->mach_params.dmic_num;
+
+ ssp_codec = sof_ssp_amp_quirk & SOF_AMPLIFIER_SSP_MASK;
+
+ /* set number of dai links */
+ sof_ssp_amp_card.num_links = 1 + dmic_be_num;
+
+ if (sof_ssp_amp_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT)
+ sof_ssp_amp_card.num_links += (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_CAPTURE_SSP_MASK) >>
+ SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT;
+
+ if (sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT) {
+ hdmi_num = (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_PLAYBACK_MASK) >>
+ SOF_NO_OF_HDMI_PLAYBACK_SHIFT;
+ /* default number of HDMI DAI's */
+ if (!hdmi_num)
+ hdmi_num = 3;
+
+ if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
+ ctx->idisp_codec = true;
+
+ sof_ssp_amp_card.num_links += hdmi_num;
+ }
+
+ if (sof_ssp_amp_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
+ sof_ssp_amp_card.num_links++;
+
+ dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, dmic_be_num, hdmi_num, ctx->idisp_codec);
+ if (!dai_links)
+ return -ENOMEM;
+
+ sof_ssp_amp_card.dai_link = dai_links;
+
+ /* update codec_conf */
+ if (sof_ssp_amp_quirk & SOF_CS35L41_SPEAKER_AMP_PRESENT) {
+ cs35l41_set_codec_conf(&sof_ssp_amp_card);
+ }
+
+ INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
+
+ sof_ssp_amp_card.dev = &pdev->dev;
+
+ /* set platform name for each dailink */
+ ret = snd_soc_fixup_dai_links_platform_name(&sof_ssp_amp_card,
+ mach->mach_params.platform);
+ if (ret)
+ return ret;
+
+ ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
+
+ snd_soc_card_set_drvdata(&sof_ssp_amp_card, ctx);
+
+ return devm_snd_soc_register_card(&pdev->dev, &sof_ssp_amp_card);
+}
+
+static const struct platform_device_id board_ids[] = {
+ {
+ .name = "sof_ssp_amp",
+ },
+ {
+ .name = "tgl_rt1308_hdmi_ssp",
+ .driver_data = (kernel_ulong_t)(SOF_AMPLIFIER_SSP(2) |
+ SOF_NO_OF_HDMI_CAPTURE_SSP(2) |
+ SOF_HDMI_CAPTURE_1_SSP(1) |
+ SOF_HDMI_CAPTURE_2_SSP(5) |
+ SOF_SSP_HDMI_CAPTURE_PRESENT |
+ SOF_RT1308_SPEAKER_AMP_PRESENT),
+ },
+ {
+ .name = "adl_cs35l41",
+ .driver_data = (kernel_ulong_t)(SOF_AMPLIFIER_SSP(1) |
+ SOF_NO_OF_HDMI_PLAYBACK(4) |
+ SOF_HDMI_PLAYBACK_PRESENT |
+ SOF_BT_OFFLOAD_SSP(2) |
+ SOF_SSP_BT_OFFLOAD_PRESENT |
+ SOF_CS35L41_SPEAKER_AMP_PRESENT),
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, board_ids);
+
+static struct platform_driver sof_ssp_amp_driver = {
+ .probe = sof_ssp_amp_probe,
+ .driver = {
+ .name = "sof_ssp_amp",
+ .pm = &snd_soc_pm_ops,
+ },
+ .id_table = board_ids,
+};
+module_platform_driver(sof_ssp_amp_driver);
+
+MODULE_DESCRIPTION("ASoC Intel(R) SOF Amplifier Machine driver");
+MODULE_AUTHOR("balamurugan.c <balamurugan.c@intel.com>");
+MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
+MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON);
+MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_CIRRUS_COMMON);