summaryrefslogtreecommitdiff
path: root/sound/soc/intel
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel')
-rw-r--r--sound/soc/intel/Kconfig129
-rw-r--r--sound/soc/intel/Makefile1
-rw-r--r--sound/soc/intel/atom/Makefile2
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-pcm.c2
-rw-r--r--sound/soc/intel/atom/sst/Makefile6
-rw-r--r--sound/soc/intel/atom/sst/sst.h6
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c66
-rw-r--r--sound/soc/intel/atom/sst/sst_drv_interface.c24
-rw-r--r--sound/soc/intel/atom/sst/sst_pci.c59
-rw-r--r--sound/soc/intel/atom/sst/sst_pvt.c33
-rw-r--r--sound/soc/intel/avs/Makefile14
-rw-r--r--sound/soc/intel/avs/apl.c25
-rw-r--r--sound/soc/intel/avs/avs.h28
-rw-r--r--sound/soc/intel/avs/board_selection.c191
-rw-r--r--sound/soc/intel/avs/boards/Kconfig18
-rw-r--r--sound/soc/intel/avs/boards/Makefile36
-rw-r--r--sound/soc/intel/avs/boards/da7219.c37
-rw-r--r--sound/soc/intel/avs/boards/dmic.c18
-rw-r--r--sound/soc/intel/avs/boards/es8336.c30
-rw-r--r--sound/soc/intel/avs/boards/hdaudio.c37
-rw-r--r--sound/soc/intel/avs/boards/i2s_test.c98
-rw-r--r--sound/soc/intel/avs/boards/max98357a.c17
-rw-r--r--sound/soc/intel/avs/boards/max98373.c17
-rw-r--r--sound/soc/intel/avs/boards/max98927.c19
-rw-r--r--sound/soc/intel/avs/boards/nau8825.c24
-rw-r--r--sound/soc/intel/avs/boards/pcm3168a.c155
-rw-r--r--sound/soc/intel/avs/boards/probe.c7
-rw-r--r--sound/soc/intel/avs/boards/rt274.c25
-rw-r--r--sound/soc/intel/avs/boards/rt286.c26
-rw-r--r--sound/soc/intel/avs/boards/rt298.c28
-rw-r--r--sound/soc/intel/avs/boards/rt5514.c17
-rw-r--r--sound/soc/intel/avs/boards/rt5663.c20
-rw-r--r--sound/soc/intel/avs/boards/rt5682.c20
-rw-r--r--sound/soc/intel/avs/boards/ssm4567.c22
-rw-r--r--sound/soc/intel/avs/cldma.c46
-rw-r--r--sound/soc/intel/avs/cldma.h3
-rw-r--r--sound/soc/intel/avs/cnl.c94
-rw-r--r--sound/soc/intel/avs/control.c184
-rw-r--r--sound/soc/intel/avs/control.h14
-rw-r--r--sound/soc/intel/avs/core.c228
-rw-r--r--sound/soc/intel/avs/debugfs.c6
-rw-r--r--sound/soc/intel/avs/dsp.c7
-rw-r--r--sound/soc/intel/avs/icl.c19
-rw-r--r--sound/soc/intel/avs/ipc.c75
-rw-r--r--sound/soc/intel/avs/lnl.c27
-rw-r--r--sound/soc/intel/avs/loader.c115
-rw-r--r--sound/soc/intel/avs/messages.c173
-rw-r--r--sound/soc/intel/avs/messages.h132
-rw-r--r--sound/soc/intel/avs/mtl.c200
-rw-r--r--sound/soc/intel/avs/path.c489
-rw-r--r--sound/soc/intel/avs/path.h12
-rw-r--r--sound/soc/intel/avs/pcm.c484
-rw-r--r--sound/soc/intel/avs/pcm.h16
-rw-r--r--sound/soc/intel/avs/probes.c18
-rw-r--r--sound/soc/intel/avs/ptl.c98
-rw-r--r--sound/soc/intel/avs/registers.h89
-rw-r--r--sound/soc/intel/avs/skl.c76
-rw-r--r--sound/soc/intel/avs/sysfs.c2
-rw-r--r--sound/soc/intel/avs/tgl.c38
-rw-r--r--sound/soc/intel/avs/topology.c122
-rw-r--r--sound/soc/intel/avs/topology.h20
-rw-r--r--sound/soc/intel/avs/trace.c2
-rw-r--r--sound/soc/intel/avs/trace.h42
-rw-r--r--sound/soc/intel/avs/utils.c10
-rw-r--r--sound/soc/intel/avs/utils.h18
-rw-r--r--sound/soc/intel/boards/Kconfig233
-rw-r--r--sound/soc/intel/boards/Makefile99
-rw-r--r--sound/soc/intel/boards/bdw-rt5650.c6
-rw-r--r--sound/soc/intel/boards/bdw-rt5677.c4
-rw-r--r--sound/soc/intel/boards/bdw_rt286.c12
-rw-r--r--sound/soc/intel/boards/bxt_da7219_max98357a.c894
-rw-r--r--sound/soc/intel/boards/bxt_rt298.c669
-rw-r--r--sound/soc/intel/boards/bytcht_cx2072x.c12
-rw-r--r--sound/soc/intel/boards/bytcht_da7213.c12
-rw-r--r--sound/soc/intel/boards/bytcht_es8316.c12
-rw-r--r--sound/soc/intel/boards/bytcht_nocodec.c6
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c113
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c12
-rw-r--r--sound/soc/intel/boards/bytcr_wm5102.c10
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c8
-rw-r--r--sound/soc/intel/boards/cht_bsw_nau8824.c6
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c12
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c12
-rw-r--r--sound/soc/intel/boards/cml_rt1011_rt5682.c609
-rw-r--r--sound/soc/intel/boards/ehl_rt5660.c21
-rw-r--r--sound/soc/intel/boards/glk_rt5682_max98357a.c691
-rw-r--r--sound/soc/intel/boards/hda_dsp_common.c4
-rw-r--r--sound/soc/intel/boards/hsw_rt5640.c12
-rw-r--r--sound/soc/intel/boards/kbl_da7219_max98357a.c687
-rw-r--r--sound/soc/intel/boards/kbl_da7219_max98927.c1171
-rw-r--r--sound/soc/intel/boards/kbl_rt5660.c566
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_max98927.c1071
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c868
-rw-r--r--sound/soc/intel/boards/skl_hda_dsp_common.c168
-rw-r--r--sound/soc/intel/boards/skl_hda_dsp_common.h66
-rw-r--r--sound/soc/intel/boards/skl_hda_dsp_generic.c260
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_max98357a.c703
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_ssm4567.c751
-rw-r--r--sound/soc/intel/boards/skl_rt286.c567
-rw-r--r--sound/soc/intel/boards/sof_board_helpers.c332
-rw-r--r--sound/soc/intel/boards/sof_board_helpers.h109
-rw-r--r--sound/soc/intel/boards/sof_cirrus_common.c4
-rw-r--r--sound/soc/intel/boards/sof_cirrus_common.h2
-rw-r--r--sound/soc/intel/boards/sof_cs42l42.c93
-rw-r--r--sound/soc/intel/boards/sof_da7219.c548
-rw-r--r--sound/soc/intel/boards/sof_es8336.c26
-rw-r--r--sound/soc/intel/boards/sof_maxim_common.c261
-rw-r--r--sound/soc/intel/boards/sof_maxim_common.h9
-rw-r--r--sound/soc/intel/boards/sof_nau8825.c116
-rw-r--r--sound/soc/intel/boards/sof_nuvoton_common.c2
-rw-r--r--sound/soc/intel/boards/sof_nuvoton_common.h2
-rw-r--r--sound/soc/intel/boards/sof_pcm512x.c16
-rw-r--r--sound/soc/intel/boards/sof_realtek_common.c348
-rw-r--r--sound/soc/intel/boards/sof_realtek_common.h7
-rw-r--r--sound/soc/intel/boards/sof_rt5682.c448
-rw-r--r--sound/soc/intel/boards/sof_sdw.c2100
-rw-r--r--sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h300
-rw-r--r--sound/soc/intel/boards/sof_sdw_common.h150
-rw-r--r--sound/soc/intel/boards/sof_sdw_cs42l42.c124
-rw-r--r--sound/soc/intel/boards/sof_sdw_cs42l43.c135
-rw-r--r--sound/soc/intel/boards/sof_sdw_cs_amp.c72
-rw-r--r--sound/soc/intel/boards/sof_sdw_dmic.c43
-rw-r--r--sound/soc/intel/boards/sof_sdw_hdmi.c16
-rw-r--r--sound/soc/intel/boards/sof_sdw_maxim.c165
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt5682.c123
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt700.c122
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt711.c191
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt712_sdca.c93
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt715.c26
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt715_sdca.c26
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt722_sdca.c97
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt_amp.c324
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c224
-rw-r--r--sound/soc/intel/boards/sof_ssp_amp.c282
-rw-r--r--sound/soc/intel/boards/sof_ssp_common.c122
-rw-r--r--sound/soc/intel/boards/sof_ssp_common.h80
-rw-r--r--sound/soc/intel/boards/sof_wm8804.c10
-rw-r--r--sound/soc/intel/catpt/Makefile2
-rw-r--r--sound/soc/intel/catpt/core.h2
-rw-r--r--sound/soc/intel/catpt/device.c18
-rw-r--r--sound/soc/intel/catpt/dsp.c4
-rw-r--r--sound/soc/intel/catpt/ipc.c2
-rw-r--r--sound/soc/intel/catpt/loader.c2
-rw-r--r--sound/soc/intel/catpt/messages.c2
-rw-r--r--sound/soc/intel/catpt/messages.h2
-rw-r--r--sound/soc/intel/catpt/pcm.c2
-rw-r--r--sound/soc/intel/catpt/registers.h2
-rw-r--r--sound/soc/intel/catpt/sysfs.c2
-rw-r--r--sound/soc/intel/catpt/trace.h2
-rw-r--r--sound/soc/intel/common/Makefile13
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-adl-match.c278
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-arl-match.c454
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-cht-match.c1
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-cml-match.c12
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-cnl-match.c6
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-ehl-match.c1
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-glk-match.c4
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-hda-match.c18
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-icl-match.c8
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-jsl-match.c4
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-kbl-match.c11
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-lnl-match.c524
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-mtl-match.c639
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-ptl-match.c683
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-rpl-match.c148
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-sdca-quirks.c42
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-sdca-quirks.h14
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c42
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h1
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-skl-match.c5
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-ssp-common.c168
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-tgl-match.c279
-rw-r--r--sound/soc/intel/common/soc-intel-quirks.h2
-rw-r--r--sound/soc/intel/common/sof-function-topology-lib.c135
-rw-r--r--sound/soc/intel/common/sof-function-topology-lib.h15
-rw-r--r--sound/soc/intel/common/sst-dsp-priv.h101
-rw-r--r--sound/soc/intel/common/sst-dsp.c250
-rw-r--r--sound/soc/intel/common/sst-dsp.h61
-rw-r--r--sound/soc/intel/common/sst-ipc.c294
-rw-r--r--sound/soc/intel/common/sst-ipc.h86
-rw-r--r--sound/soc/intel/keembay/Makefile2
-rw-r--r--sound/soc/intel/keembay/kmb_platform.c3
-rw-r--r--sound/soc/intel/skylake/Makefile15
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c629
-rw-r--r--sound/soc/intel/skylake/cnl-sst-dsp.c266
-rw-r--r--sound/soc/intel/skylake/cnl-sst-dsp.h103
-rw-r--r--sound/soc/intel/skylake/cnl-sst.c508
-rw-r--r--sound/soc/intel/skylake/skl-debug.c248
-rw-r--r--sound/soc/intel/skylake/skl-i2s.h87
-rw-r--r--sound/soc/intel/skylake/skl-messages.c1419
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c269
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c1507
-rw-r--r--sound/soc/intel/skylake/skl-ssp-clk.c428
-rw-r--r--sound/soc/intel/skylake/skl-ssp-clk.h108
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.c373
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.h243
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.c462
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h256
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c1071
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h169
-rw-r--r--sound/soc/intel/skylake/skl-sst-utils.c425
-rw-r--r--sound/soc/intel/skylake/skl-sst.c599
-rw-r--r--sound/soc/intel/skylake/skl-topology.c3774
-rw-r--r--sound/soc/intel/skylake/skl-topology.h524
-rw-r--r--sound/soc/intel/skylake/skl.c1177
-rw-r--r--sound/soc/intel/skylake/skl.h207
206 files changed, 8537 insertions, 32287 deletions
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 4b9e498e3303..2db494b0e3cf 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -15,9 +15,6 @@ config SND_SOC_INTEL_SST_TOPLEVEL
if SND_SOC_INTEL_SST_TOPLEVEL
-config SND_SOC_INTEL_SST
- tristate
-
config SND_SOC_INTEL_CATPT
tristate "Haswell and Broadwell"
depends on ACPI || COMPILE_TEST
@@ -67,126 +64,6 @@ config SND_SST_ATOM_HIFI2_PLATFORM_ACPI
Baytrail/Cherrytrail. If you want to enable SOF on
Baytrail/Cherrytrail, you need to deselect this option first.
-config SND_SOC_INTEL_SKYLAKE
- tristate "All Skylake/SST Platforms"
- depends on PCI && ACPI
- depends on COMMON_CLK
- select SND_SOC_INTEL_SKL
- select SND_SOC_INTEL_APL
- select SND_SOC_INTEL_KBL
- select SND_SOC_INTEL_GLK
- select SND_SOC_INTEL_CNL
- select SND_SOC_INTEL_CFL
- help
- This is a backwards-compatible option to select all devices
- supported by the Intel SST/Skylake driver. This option is no
- longer recommended and will be deprecated when the SOF
- driver is introduced. Distributions should explicitly
- select which platform uses this driver.
-
-config SND_SOC_INTEL_SKL
- tristate "Skylake Platforms"
- depends on PCI && ACPI
- depends on COMMON_CLK
- select SND_SOC_INTEL_SKYLAKE_FAMILY
- help
- If you have a Intel Skylake platform with the DSP enabled
- in the BIOS then enable this option by saying Y or m.
-
-config SND_SOC_INTEL_APL
- tristate "Broxton/ApolloLake Platforms"
- depends on PCI && ACPI
- depends on COMMON_CLK
- select SND_SOC_INTEL_SKYLAKE_FAMILY
- help
- If you have a Intel Broxton/ApolloLake platform with the DSP
- enabled in the BIOS then enable this option by saying Y or m.
-
-config SND_SOC_INTEL_KBL
- tristate "Kabylake Platforms"
- depends on PCI && ACPI
- depends on COMMON_CLK
- select SND_SOC_INTEL_SKYLAKE_FAMILY
- help
- If you have a Intel Kabylake platform with the DSP
- enabled in the BIOS then enable this option by saying Y or m.
-
-config SND_SOC_INTEL_GLK
- tristate "GeminiLake Platforms"
- depends on PCI && ACPI
- depends on COMMON_CLK
- select SND_SOC_INTEL_SKYLAKE_FAMILY
- help
- If you have a Intel GeminiLake platform with the DSP
- enabled in the BIOS then enable this option by saying Y or m.
-
-config SND_SOC_INTEL_CNL
- tristate "CannonLake/WhiskyLake Platforms"
- depends on PCI && ACPI
- depends on COMMON_CLK
- select SND_SOC_INTEL_SKYLAKE_FAMILY
- help
- If you have a Intel CNL/WHL platform with the DSP
- enabled in the BIOS then enable this option by saying Y or m.
-
-config SND_SOC_INTEL_CFL
- tristate "CoffeeLake Platforms"
- depends on PCI && ACPI
- depends on COMMON_CLK
- select SND_SOC_INTEL_SKYLAKE_FAMILY
- help
- If you have a Intel CoffeeLake platform with the DSP
- enabled in the BIOS then enable this option by saying Y or m.
-
-config SND_SOC_INTEL_CML_H
- tristate "CometLake-H Platforms"
- depends on PCI && ACPI
- depends on COMMON_CLK
- select SND_SOC_INTEL_SKYLAKE_FAMILY
- help
- If you have a Intel CometLake-H platform with the DSP
- enabled in the BIOS then enable this option by saying Y or m.
-
-config SND_SOC_INTEL_CML_LP
- tristate "CometLake-LP Platforms"
- depends on PCI && ACPI
- depends on COMMON_CLK
- select SND_SOC_INTEL_SKYLAKE_FAMILY
- help
- If you have a Intel CometLake-LP platform with the DSP
- enabled in the BIOS then enable this option by saying Y or m.
-
-config SND_SOC_INTEL_SKYLAKE_FAMILY
- tristate
- select SND_SOC_INTEL_SKYLAKE_COMMON
-
-if SND_SOC_INTEL_SKYLAKE_FAMILY
-
-config SND_SOC_INTEL_SKYLAKE_SSP_CLK
- tristate
-
-config SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC
- bool "HDAudio codec support"
- help
- If you have Intel Skylake or Kabylake with HDAudio codec
- and DMIC present then enable this option by saying Y.
-
-config SND_SOC_INTEL_SKYLAKE_COMMON
- tristate
- select SND_HDA_EXT_CORE
- select SND_HDA_DSP_LOADER
- select SND_SOC_TOPOLOGY
- select SND_SOC_INTEL_SST
- select SND_SOC_HDAC_HDA
- select SND_SOC_ACPI_INTEL_MATCH
- select SND_INTEL_DSP_CONFIG
- help
- If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/
- GeminiLake or CannonLake platform with the DSP enabled in the BIOS
- then enable this option by saying Y or m.
-
-endif ## SND_SOC_INTEL_SKYLAKE_FAMILY
-
endif ## SND_SOC_INTEL_SST_TOPLEVEL
if SND_SOC_INTEL_SST_TOPLEVEL || SND_SOC_SOF_INTEL_TOPLEVEL
@@ -194,9 +71,14 @@ if SND_SOC_INTEL_SST_TOPLEVEL || SND_SOC_SOF_INTEL_TOPLEVEL
config SND_SOC_ACPI_INTEL_MATCH
tristate
select SND_SOC_ACPI if ACPI
+ select SND_SOC_ACPI_INTEL_SDCA_QUIRKS
# this option controls the compilation of ACPI matching tables and
# helpers and is not meant to be selected by the user.
+config SND_SOC_ACPI_INTEL_SDCA_QUIRKS
+ tristate
+ select SND_SOC_SDCA if ACPI
+
endif ## SND_SOC_INTEL_SST_TOPLEVEL || SND_SOC_SOF_INTEL_TOPLEVEL
config SND_SOC_INTEL_KEEMBAY
@@ -214,6 +96,7 @@ config SND_SOC_INTEL_AVS
depends on X86 || COMPILE_TEST
depends on PCI
depends on COMMON_CLK
+ select ACPI_NHLT if ACPI
select SND_SOC_ACPI if ACPI
select SND_SOC_TOPOLOGY
select SND_SOC_HDA
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile
index d44b2652c707..8ecc7047d700 100644
--- a/sound/soc/intel/Makefile
+++ b/sound/soc/intel/Makefile
@@ -5,7 +5,6 @@ obj-$(CONFIG_SND_SOC) += common/
# Platform Support
obj-$(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM) += atom/
obj-$(CONFIG_SND_SOC_INTEL_CATPT) += catpt/
-obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON) += skylake/
obj-$(CONFIG_SND_SOC_INTEL_KEEMBAY) += keembay/
obj-$(CONFIG_SND_SOC_INTEL_AVS) += avs/
diff --git a/sound/soc/intel/atom/Makefile b/sound/soc/intel/atom/Makefile
index c66f03f5d8d6..38e4876025c7 100644
--- a/sound/soc/intel/atom/Makefile
+++ b/sound/soc/intel/atom/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-soc-sst-atom-hifi2-platform-objs := sst-mfld-platform-pcm.o \
+snd-soc-sst-atom-hifi2-platform-y := sst-mfld-platform-pcm.o \
sst-mfld-platform-compress.o \
sst-atom-controls.o
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
index 8652b4a20020..373d68b4cf88 100644
--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
@@ -812,7 +812,7 @@ static struct platform_driver sst_platform_driver = {
.pm = &sst_platform_pm,
},
.probe = sst_platform_probe,
- .remove_new = sst_platform_remove,
+ .remove = sst_platform_remove,
};
module_platform_driver(sst_platform_driver);
diff --git a/sound/soc/intel/atom/sst/Makefile b/sound/soc/intel/atom/sst/Makefile
index 5761d30a5f9d..16be0463424d 100644
--- a/sound/soc/intel/atom/sst/Makefile
+++ b/sound/soc/intel/atom/sst/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-intel-sst-core-objs := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o
-snd-intel-sst-pci-objs += sst_pci.o
-snd-intel-sst-acpi-objs += sst_acpi.o
+snd-intel-sst-core-y := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o
+snd-intel-sst-pci-y += sst_pci.o
+snd-intel-sst-acpi-y += sst_acpi.o
obj-$(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM) += snd-intel-sst-core.o
obj-$(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI) += snd-intel-sst-pci.o
diff --git a/sound/soc/intel/atom/sst/sst.h b/sound/soc/intel/atom/sst/sst.h
index 126903e126e4..c43946c5ecee 100644
--- a/sound/soc/intel/atom/sst/sst.h
+++ b/sound/soc/intel/atom/sst/sst.h
@@ -443,9 +443,6 @@ int sst_set_stream_param(int str_id, struct snd_sst_params *str_param);
int sst_set_metadata(int str_id, char *params);
int sst_get_stream(struct intel_sst_drv *ctx,
struct snd_sst_params *str_param);
-int sst_get_stream_allocated(struct intel_sst_drv *ctx,
- struct snd_sst_params *str_param,
- struct snd_sst_lib_download **lib_dnld);
int sst_drain_stream(struct intel_sst_drv *sst_drv_ctx,
int str_id, bool partial_drain);
int sst_post_message_mrfld(struct intel_sst_drv *sst_drv_ctx,
@@ -461,8 +458,6 @@ void sst_post_download_mrfld(struct intel_sst_drv *ctx);
int sst_get_block_stream(struct intel_sst_drv *sst_drv_ctx);
void sst_memcpy_free_resources(struct intel_sst_drv *sst_drv_ctx);
-int sst_wait_interruptible(struct intel_sst_drv *sst_drv_ctx,
- struct sst_block *block);
int sst_wait_timeout(struct intel_sst_drv *sst_drv_ctx,
struct sst_block *block);
int sst_create_ipc_msg(struct ipc_post **arg, bool large);
@@ -470,7 +465,6 @@ int free_stream_context(struct intel_sst_drv *ctx, unsigned int str_id);
void sst_clean_stream(struct stream_info *stream);
int intel_sst_register_compress(struct intel_sst_drv *sst);
int intel_sst_remove_compress(struct intel_sst_drv *sst);
-void sst_cdev_fragment_elapsed(struct intel_sst_drv *ctx, int str_id);
int sst_send_sync_msg(int ipc, int str_id);
int sst_get_num_channel(struct snd_sst_params *str_param);
int sst_get_sfreq(struct snd_sst_params *str_param);
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index 29d44c989e5f..257180630475 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -125,6 +125,28 @@ static const struct sst_res_info bytcr_res_info = {
.acpi_ipc_irq_index = 0
};
+/* For "LPE0F28" ACPI device found on some Android factory OS models */
+static const struct sst_res_info lpe8086_res_info = {
+ .shim_offset = 0x140000,
+ .shim_size = 0x000100,
+ .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR,
+ .ssp0_offset = 0xa0000,
+ .ssp0_size = 0x1000,
+ .dma0_offset = 0x98000,
+ .dma0_size = 0x4000,
+ .dma1_offset = 0x9c000,
+ .dma1_size = 0x4000,
+ .iram_offset = 0x0c0000,
+ .iram_size = 0x14000,
+ .dram_offset = 0x100000,
+ .dram_size = 0x28000,
+ .mbox_offset = 0x144000,
+ .mbox_size = 0x1000,
+ .acpi_lpe_res_index = 1,
+ .acpi_ddr_index = 0,
+ .acpi_ipc_irq_index = 0
+};
+
static struct sst_platform_info byt_rvp_platform_data = {
.probe_data = &byt_fwparse_info,
.ipc_info = &byt_ipc_info,
@@ -268,10 +290,38 @@ static int sst_acpi_probe(struct platform_device *pdev)
mach->pdata = &chv_platform_data;
pdata = mach->pdata;
- ret = kstrtouint(id->id, 16, &dev_id);
- if (ret < 0) {
- dev_err(dev, "Unique device id conversion error: %d\n", ret);
- return ret;
+ if (!strcmp(id->id, "LPE0F28")) {
+ struct resource *rsrc;
+
+ /* Use regular BYT SST PCI VID:PID */
+ dev_id = 0x80860F28;
+ byt_rvp_platform_data.res_info = &lpe8086_res_info;
+
+ /*
+ * The "LPE0F28" ACPI device has separate IO-mem resources for:
+ * DDR, SHIM, MBOX, IRAM, DRAM, CFG
+ * None of which covers the entire LPE base address range.
+ * lpe8086_res_info.acpi_lpe_res_index points to the SHIM.
+ * Patch this to cover the entire base address range as expected
+ * by sst_platform_get_resources().
+ */
+ rsrc = platform_get_resource(pdev, IORESOURCE_MEM,
+ pdata->res_info->acpi_lpe_res_index);
+ if (!rsrc) {
+ dev_err(dev, "Invalid SHIM base\n");
+ return -EIO;
+ }
+ rsrc->start -= pdata->res_info->shim_offset;
+ rsrc->end = rsrc->start + 0x200000 - 1;
+ } else {
+ ret = kstrtouint(id->id, 16, &dev_id);
+ if (ret < 0) {
+ dev_err(dev, "Unique device id conversion error: %d\n", ret);
+ return ret;
+ }
+
+ if (soc_intel_is_byt_cr(pdev))
+ byt_rvp_platform_data.res_info = &bytcr_res_info;
}
dev_dbg(dev, "ACPI device id: %x\n", dev_id);
@@ -280,11 +330,6 @@ static int sst_acpi_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
- if (soc_intel_is_byt_cr(pdev)) {
- /* override resource info */
- byt_rvp_platform_data.res_info = &bytcr_res_info;
- }
-
/* update machine parameters */
mach->mach_params.acpi_ipc_irq_index =
pdata->res_info->acpi_ipc_irq_index;
@@ -344,6 +389,7 @@ static void sst_acpi_remove(struct platform_device *pdev)
}
static const struct acpi_device_id sst_acpi_ids[] = {
+ { "LPE0F28", (unsigned long)&snd_soc_acpi_intel_baytrail_machines},
{ "80860F28", (unsigned long)&snd_soc_acpi_intel_baytrail_machines},
{ "808622A8", (unsigned long)&snd_soc_acpi_intel_cherrytrail_machines},
{ },
@@ -358,7 +404,7 @@ static struct platform_driver sst_acpi_driver = {
.pm = &intel_sst_pm,
},
.probe = sst_acpi_probe,
- .remove_new = sst_acpi_remove,
+ .remove = sst_acpi_remove,
};
module_platform_driver(sst_acpi_driver);
diff --git a/sound/soc/intel/atom/sst/sst_drv_interface.c b/sound/soc/intel/atom/sst/sst_drv_interface.c
index dc31c2c8f54c..8bb27f86eb65 100644
--- a/sound/soc/intel/atom/sst/sst_drv_interface.c
+++ b/sound/soc/intel/atom/sst/sst_drv_interface.c
@@ -55,19 +55,6 @@ int free_stream_context(struct intel_sst_drv *ctx, unsigned int str_id)
return ret;
}
-int sst_get_stream_allocated(struct intel_sst_drv *ctx,
- struct snd_sst_params *str_param,
- struct snd_sst_lib_download **lib_dnld)
-{
- int retval;
-
- retval = ctx->ops->alloc_stream(ctx, str_param);
- if (retval > 0)
- dev_dbg(ctx->dev, "Stream allocated %d\n", retval);
- return retval;
-
-}
-
/*
* sst_get_sfreq - this function returns the frequency of the stream
*
@@ -430,17 +417,6 @@ static int sst_cdev_codec_caps(struct snd_compr_codec_caps *codec)
return 0;
}
-void sst_cdev_fragment_elapsed(struct intel_sst_drv *ctx, int str_id)
-{
- struct stream_info *stream;
-
- dev_dbg(ctx->dev, "fragment elapsed from firmware for str_id %d\n",
- str_id);
- stream = &ctx->streams[str_id];
- if (stream->compr_cb)
- stream->compr_cb(stream->compr_cb_param);
-}
-
/*
* sst_close_pcm_stream - Close PCM interface
*
diff --git a/sound/soc/intel/atom/sst/sst_pci.c b/sound/soc/intel/atom/sst/sst_pci.c
index d1e64c3500be..22ae2d22f121 100644
--- a/sound/soc/intel/atom/sst/sst_pci.c
+++ b/sound/soc/intel/atom/sst/sst_pci.c
@@ -26,7 +26,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
int ddr_base, ret = 0;
struct pci_dev *pci = ctx->pci;
- ret = pci_request_regions(pci, SST_DRV_NAME);
+ ret = pcim_request_all_regions(pci, SST_DRV_NAME);
if (ret)
return ret;
@@ -38,67 +38,57 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
ddr_base = relocate_imr_addr_mrfld(ctx->ddr_base);
if (!ctx->pdata->lib_info) {
dev_err(ctx->dev, "lib_info pointer NULL\n");
- ret = -EINVAL;
- goto do_release_regions;
+ return -EINVAL;
}
if (ddr_base != ctx->pdata->lib_info->mod_base) {
dev_err(ctx->dev,
"FW LSP DDR BASE does not match with IFWI\n");
- ret = -EINVAL;
- goto do_release_regions;
+ return -EINVAL;
}
ctx->ddr_end = pci_resource_end(pci, 0);
- ctx->ddr = pcim_iomap(pci, 0,
- pci_resource_len(pci, 0));
- if (!ctx->ddr) {
- ret = -EINVAL;
- goto do_release_regions;
- }
+ ctx->ddr = pcim_iomap(pci, 0, 0);
+ if (!ctx->ddr)
+ return -ENOMEM;
+
dev_dbg(ctx->dev, "sst: DDR Ptr %p\n", ctx->ddr);
} else {
ctx->ddr = NULL;
}
/* SHIM */
ctx->shim_phy_add = pci_resource_start(pci, 1);
- ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1));
- if (!ctx->shim) {
- ret = -EINVAL;
- goto do_release_regions;
- }
+ ctx->shim = pcim_iomap(pci, 1, 0);
+ if (!ctx->shim)
+ return -ENOMEM;
+
dev_dbg(ctx->dev, "SST Shim Ptr %p\n", ctx->shim);
/* Shared SRAM */
ctx->mailbox_add = pci_resource_start(pci, 2);
- ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2));
- if (!ctx->mailbox) {
- ret = -EINVAL;
- goto do_release_regions;
- }
+ ctx->mailbox = pcim_iomap(pci, 2, 0);
+ if (!ctx->mailbox)
+ return -ENOMEM;
+
dev_dbg(ctx->dev, "SRAM Ptr %p\n", ctx->mailbox);
/* IRAM */
ctx->iram_end = pci_resource_end(pci, 3);
ctx->iram_base = pci_resource_start(pci, 3);
- ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3));
- if (!ctx->iram) {
- ret = -EINVAL;
- goto do_release_regions;
- }
+ ctx->iram = pcim_iomap(pci, 3, 0);
+ if (!ctx->iram)
+ return -ENOMEM;
+
dev_dbg(ctx->dev, "IRAM Ptr %p\n", ctx->iram);
/* DRAM */
ctx->dram_end = pci_resource_end(pci, 4);
ctx->dram_base = pci_resource_start(pci, 4);
- ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4));
- if (!ctx->dram) {
- ret = -EINVAL;
- goto do_release_regions;
- }
+ ctx->dram = pcim_iomap(pci, 4, 0);
+ if (!ctx->dram)
+ return -ENOMEM;
+
dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram);
-do_release_regions:
- pci_release_regions(pci);
- return ret;
+ return 0;
}
/*
@@ -167,7 +157,6 @@ static void intel_sst_remove(struct pci_dev *pci)
sst_context_cleanup(sst_drv_ctx);
pci_dev_put(sst_drv_ctx->pci);
- pci_release_regions(pci);
pci_set_drvdata(pci, NULL);
}
diff --git a/sound/soc/intel/atom/sst/sst_pvt.c b/sound/soc/intel/atom/sst/sst_pvt.c
index e6a5c18a7018..5d08f7d803f9 100644
--- a/sound/soc/intel/atom/sst/sst_pvt.c
+++ b/sound/soc/intel/atom/sst/sst_pvt.c
@@ -70,39 +70,6 @@ void sst_set_fw_state_locked(
}
/*
- * sst_wait_interruptible - wait on event
- *
- * @sst_drv_ctx: Driver context
- * @block: Driver block to wait on
- *
- * This function waits without a timeout (and is interruptable) for a
- * given block event
- */
-int sst_wait_interruptible(struct intel_sst_drv *sst_drv_ctx,
- struct sst_block *block)
-{
- int retval = 0;
-
- if (!wait_event_interruptible(sst_drv_ctx->wait_queue,
- block->condition)) {
- /* event wake */
- if (block->ret_code < 0) {
- dev_err(sst_drv_ctx->dev,
- "stream failed %d\n", block->ret_code);
- retval = -EBUSY;
- } else {
- dev_dbg(sst_drv_ctx->dev, "event up\n");
- retval = 0;
- }
- } else {
- dev_err(sst_drv_ctx->dev, "signal interrupted\n");
- retval = -EINTR;
- }
- return retval;
-
-}
-
-/*
* sst_wait_timeout - wait on event for timeout
*
* @sst_drv_ctx: Driver context
diff --git a/sound/soc/intel/avs/Makefile b/sound/soc/intel/avs/Makefile
index 5480500337f8..576dc0da381d 100644
--- a/sound/soc/intel/avs/Makefile
+++ b/sound/soc/intel/avs/Makefile
@@ -1,17 +1,17 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-soc-avs-objs := dsp.o ipc.o messages.o utils.o core.o loader.o \
- topology.o path.o pcm.o board_selection.o control.o \
- sysfs.o
-snd-soc-avs-objs += cldma.o
-snd-soc-avs-objs += skl.o apl.o cnl.o icl.o tgl.o
+snd-soc-avs-y := dsp.o ipc.o messages.o utils.o core.o loader.o \
+ topology.o path.o pcm.o board_selection.o control.o \
+ sysfs.o
+snd-soc-avs-y += cldma.o
+snd-soc-avs-y += skl.o apl.o cnl.o icl.o tgl.o mtl.o lnl.o ptl.o
-snd-soc-avs-objs += trace.o
+snd-soc-avs-y += trace.o
# tell define_trace.h where to find the trace header
CFLAGS_trace.o := -I$(src)
ifneq ($(CONFIG_DEBUG_FS),)
-snd-soc-avs-objs += probes.o debugfs.o
+snd-soc-avs-y += probes.o debugfs.o
endif
obj-$(CONFIG_SND_SOC_INTEL_AVS) += snd-soc-avs.o
diff --git a/sound/soc/intel/avs/apl.c b/sound/soc/intel/avs/apl.c
index c21ecaef9eba..3dccf0a57a3a 100644
--- a/sound/soc/intel/avs/apl.c
+++ b/sound/soc/intel/avs/apl.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -8,11 +8,29 @@
#include <linux/devcoredump.h>
#include <linux/slab.h>
+#include <sound/hdaudio_ext.h>
#include "avs.h"
#include "messages.h"
#include "path.h"
+#include "registers.h"
#include "topology.h"
+static irqreturn_t avs_apl_dsp_interrupt(struct avs_dev *adev)
+{
+ u32 adspis = snd_hdac_adsp_readl(adev, AVS_ADSP_REG_ADSPIS);
+ irqreturn_t ret = IRQ_NONE;
+
+ if (adspis == UINT_MAX)
+ return ret;
+
+ if (adspis & AVS_ADSP_ADSPIS_IPC) {
+ avs_skl_ipc_interrupt(adev);
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+}
+
#ifdef CONFIG_DEBUG_FS
int avs_apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
u32 fifo_full_period, unsigned long resource_mask, u32 *priorities)
@@ -108,7 +126,7 @@ int avs_apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg)
struct avs_apl_log_buffer_layout layout;
void __iomem *addr, *buf;
size_t dump_size;
- u16 offset = 0;
+ u32 offset = 0;
u8 *dump, *pos;
dump_size = AVS_FW_REGS_SIZE + msg->ext.coredump.stack_dump_size;
@@ -237,8 +255,7 @@ const struct avs_dsp_ops avs_apl_dsp_ops = {
.power = avs_dsp_core_power,
.reset = avs_dsp_core_reset,
.stall = avs_dsp_core_stall,
- .irq_handler = avs_irq_handler,
- .irq_thread = avs_skl_irq_thread,
+ .dsp_interrupt = avs_apl_dsp_interrupt,
.int_control = avs_dsp_interrupt_control,
.load_basefw = avs_hda_load_basefw,
.load_lib = avs_hda_load_library,
diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h
index f80f79415344..4c096afc5848 100644
--- a/sound/soc/intel/avs/avs.h
+++ b/sound/soc/intel/avs/avs.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+ * Copyright(c) 2021-2022 Intel Corporation
*
* Authors: Cezary Rojewski <cezary.rojewski@intel.com>
* Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -46,12 +46,12 @@ struct avs_dsp_ops {
int (* const power)(struct avs_dev *, u32, bool);
int (* const reset)(struct avs_dev *, u32, bool);
int (* const stall)(struct avs_dev *, u32, bool);
- irqreturn_t (* const irq_handler)(struct avs_dev *);
- irqreturn_t (* const irq_thread)(struct avs_dev *);
+ irqreturn_t (* const dsp_interrupt)(struct avs_dev *);
void (* const int_control)(struct avs_dev *, bool);
int (* const load_basefw)(struct avs_dev *, struct firmware *);
int (* const load_lib)(struct avs_dev *, struct firmware *, u32);
int (* const transfer_mods)(struct avs_dev *, bool, struct avs_module_entry *, u32);
+ int (* const config_basefw)(struct avs_dev *);
int (* const enable_logs)(struct avs_dev *, enum avs_log_enable, u32, u32, unsigned long,
u32 *);
int (* const log_buffer_offset)(struct avs_dev *, u32);
@@ -69,9 +69,12 @@ extern const struct avs_dsp_ops avs_apl_dsp_ops;
extern const struct avs_dsp_ops avs_cnl_dsp_ops;
extern const struct avs_dsp_ops avs_icl_dsp_ops;
extern const struct avs_dsp_ops avs_tgl_dsp_ops;
+extern const struct avs_dsp_ops avs_ptl_dsp_ops;
#define AVS_PLATATTR_CLDMA BIT_ULL(0)
#define AVS_PLATATTR_IMR BIT_ULL(1)
+#define AVS_PLATATTR_ACE BIT_ULL(2)
+#define AVS_PLATATTR_ALTHDA BIT_ULL(3)
#define avs_platattr_test(adev, attr) \
((adev)->spec->attributes & AVS_PLATATTR_##attr)
@@ -79,7 +82,6 @@ extern const struct avs_dsp_ops avs_tgl_dsp_ops;
struct avs_sram_spec {
const u32 base_offset;
const u32 window_size;
- const u32 rom_status_offset;
};
struct avs_hipc_spec {
@@ -91,6 +93,7 @@ struct avs_hipc_spec {
const u32 rsp_offset;
const u32 rsp_busy_mask;
const u32 ctl_offset;
+ const u32 sts_offset;
};
/* Platform specific descriptor */
@@ -107,7 +110,7 @@ struct avs_spec {
};
struct avs_fw_entry {
- char *name;
+ const char *name;
const struct firmware *fw;
struct list_head node;
@@ -151,7 +154,6 @@ struct avs_dev {
struct completion fw_ready;
struct work_struct probe_work;
- struct nhlt_acpi_table *nhlt;
struct list_head comp_list;
struct mutex comp_list_mutex;
struct list_head path_list;
@@ -245,7 +247,6 @@ struct avs_ipc {
#define AVS_IPC_RET(ret) \
(((ret) <= 0) ? (ret) : -AVS_EIPC)
-irqreturn_t avs_irq_handler(struct avs_dev *adev);
void avs_dsp_process_response(struct avs_dev *adev, u64 header);
int avs_dsp_send_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request,
struct avs_ipc_msg *reply, int timeout, const char *name);
@@ -267,8 +268,14 @@ void avs_ipc_block(struct avs_ipc *ipc);
int avs_dsp_disable_d0ix(struct avs_dev *adev);
int avs_dsp_enable_d0ix(struct avs_dev *adev);
-irqreturn_t avs_skl_irq_thread(struct avs_dev *adev);
-irqreturn_t avs_cnl_irq_thread(struct avs_dev *adev);
+int avs_mtl_core_power(struct avs_dev *adev, u32 core_mask, bool power);
+int avs_mtl_core_reset(struct avs_dev *adev, u32 core_mask, bool power);
+int avs_mtl_core_stall(struct avs_dev *adev, u32 core_mask, bool stall);
+int avs_lnl_core_stall(struct avs_dev *adev, u32 core_mask, bool stall);
+void avs_mtl_interrupt_control(struct avs_dev *adev, bool enable);
+void avs_skl_ipc_interrupt(struct avs_dev *adev);
+irqreturn_t avs_cnl_dsp_interrupt(struct avs_dev *adev);
+irqreturn_t avs_mtl_dsp_interrupt(struct avs_dev *adev);
int avs_apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
u32 fifo_full_period, unsigned long resource_mask, u32 *priorities);
int avs_icl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
@@ -342,7 +349,7 @@ struct avs_soc_component {
extern const struct snd_soc_dai_ops avs_dai_fe_ops;
int avs_soc_component_register(struct device *dev, const char *name,
- const struct snd_soc_component_driver *drv,
+ struct snd_soc_component_driver *drv,
struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais);
int avs_dmic_platform_register(struct avs_dev *adev, const char *name);
int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask,
@@ -381,6 +388,7 @@ struct avs_apl_log_buffer_layout {
u32 write_ptr;
u8 buffer[];
} __packed;
+static_assert(sizeof(struct avs_apl_log_buffer_layout) == 8);
#define avs_apl_log_payload_size(adev) \
(avs_log_buffer_size(adev) - sizeof(struct avs_apl_log_buffer_layout))
diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c
index 8360ce557401..636315060eb4 100644
--- a/sound/soc/intel/avs/board_selection.c
+++ b/sound/soc/intel/avs/board_selection.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -10,17 +10,22 @@
#include <linux/module.h>
#include <linux/dmi.h>
#include <linux/pci.h>
+#include <acpi/nhlt.h>
#include <linux/platform_device.h>
#include <sound/hda_codec.h>
#include <sound/hda_register.h>
-#include <sound/intel-nhlt.h>
#include <sound/soc-acpi.h>
#include <sound/soc-component.h>
#include "avs.h"
+#include "utils.h"
-static bool i2s_test;
-module_param(i2s_test, bool, 0444);
-MODULE_PARM_DESC(i2s_test, "Probe I2S test-board and skip all other I2S boards");
+static char *i2s_test;
+module_param(i2s_test, charp, 0444);
+MODULE_PARM_DESC(i2s_test, "Use I2S test-board instead of ACPI, i2s_test=ssp0tdm,ssp1tdm,... 0 to ignore port");
+
+bool obsolete_card_names = IS_ENABLED(CONFIG_SND_SOC_INTEL_AVS_CARDNAME_OBSOLETE);
+module_param_named(obsolete_card_names, obsolete_card_names, bool, 0444);
+MODULE_PARM_DESC(obsolete_card_names, "Use obsolete card names 0=no, 1=yes");
static const struct dmi_system_id kbl_dmi_table[] = {
{
@@ -141,7 +146,7 @@ static struct snd_soc_acpi_mach avs_kbl_i2s_machines[] = {
.mach_params = {
.i2s_link_mask = AVS_SSP(0),
},
- .pdata = (unsigned long[]){ 0x2, 0, 0, 0, 0, 0 }, /* SSP0 TDMs */
+ .pdata = (struct avs_mach_pdata[]){ { .tdms = (unsigned long[]){ 0x2 } } },
.tplg_filename = "rt5514-tplg.bin",
},
{
@@ -202,7 +207,9 @@ static struct snd_soc_acpi_mach avs_apl_i2s_machines[] = {
.mach_params = {
.i2s_link_mask = AVS_SSP_RANGE(0, 5),
},
- .pdata = (unsigned long[]){ 0x1, 0x1, 0x14, 0x1, 0x1, 0x1 }, /* SSP2 TDMs */
+ .pdata = (struct avs_mach_pdata[]){ {
+ .tdms = (unsigned long[]){ 0x1, 0x1, 0x14, 0x1, 0x1, 0x1 }
+ } },
.tplg_filename = "tdf8532-tplg.bin",
},
{
@@ -312,50 +319,16 @@ static struct snd_soc_acpi_mach avs_tgl_i2s_machines[] = {
{},
};
-static struct snd_soc_acpi_mach avs_test_i2s_machines[] = {
- {
- .drv_name = "avs_i2s_test",
- .mach_params = {
- .i2s_link_mask = AVS_SSP(0),
- },
- .tplg_filename = "i2s-test-tplg.bin",
- },
- {
- .drv_name = "avs_i2s_test",
- .mach_params = {
- .i2s_link_mask = AVS_SSP(1),
- },
- .tplg_filename = "i2s-test-tplg.bin",
- },
- {
- .drv_name = "avs_i2s_test",
- .mach_params = {
- .i2s_link_mask = AVS_SSP(2),
- },
- .tplg_filename = "i2s-test-tplg.bin",
- },
+static struct snd_soc_acpi_mach avs_mbl_i2s_machines[] = {
{
- .drv_name = "avs_i2s_test",
+ .id = "PCM3168A",
+ .drv_name = "avs_pcm3168a",
.mach_params = {
- .i2s_link_mask = AVS_SSP(3),
+ .i2s_link_mask = AVS_SSP(0) | AVS_SSP(2),
},
- .tplg_filename = "i2s-test-tplg.bin",
+ .tplg_filename = "pcm3168a-tplg.bin",
},
- {
- .drv_name = "avs_i2s_test",
- .mach_params = {
- .i2s_link_mask = AVS_SSP(4),
- },
- .tplg_filename = "i2s-test-tplg.bin",
- },
- {
- .drv_name = "avs_i2s_test",
- .mach_params = {
- .i2s_link_mask = AVS_SSP(5),
- },
- .tplg_filename = "i2s-test-tplg.bin",
- },
- /* no NULL terminator, as we depend on ARRAY SIZE due to .id == NULL */
+ {}
};
struct avs_acpi_boards {
@@ -378,10 +351,12 @@ static const struct avs_acpi_boards i2s_boards[] = {
AVS_MACH_ENTRY(HDA_ICL_LP, avs_icl_i2s_machines),
AVS_MACH_ENTRY(HDA_TGL_LP, avs_tgl_i2s_machines),
AVS_MACH_ENTRY(HDA_EHL_0, avs_tgl_i2s_machines),
+ AVS_MACH_ENTRY(HDA_ADL_N, avs_mbl_i2s_machines),
AVS_MACH_ENTRY(HDA_ADL_P, avs_tgl_i2s_machines),
AVS_MACH_ENTRY(HDA_RPL_P_0, avs_tgl_i2s_machines),
- AVS_MACH_ENTRY(HDA_RPL_M, avs_tgl_i2s_machines),
- {},
+ AVS_MACH_ENTRY(HDA_RPL_M, avs_mbl_i2s_machines),
+ AVS_MACH_ENTRY(HDA_FCL, avs_tgl_i2s_machines),
+ { },
};
static const struct avs_acpi_boards *avs_get_i2s_boards(struct avs_dev *adev)
@@ -432,10 +407,10 @@ static int avs_register_dmic_board(struct avs_dev *adev)
{
struct platform_device *codec, *board;
struct snd_soc_acpi_mach mach = {{0}};
+ struct avs_mach_pdata *pdata;
int ret;
- if (!adev->nhlt ||
- !intel_nhlt_has_endpoint_type(adev->nhlt, NHLT_LINK_DMIC)) {
+ if (!acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1)) {
dev_dbg(adev->dev, "no DMIC endpoints present\n");
return 0;
}
@@ -456,6 +431,11 @@ static int avs_register_dmic_board(struct avs_dev *adev)
if (ret < 0)
return ret;
+ pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+ pdata->obsolete_card_names = obsolete_card_names;
+ mach.pdata = pdata;
mach.tplg_filename = "dmic-tplg.bin";
mach.mach_params.platform = "dmic-platform";
@@ -478,9 +458,11 @@ static int avs_register_dmic_board(struct avs_dev *adev)
static int avs_register_i2s_board(struct avs_dev *adev, struct snd_soc_acpi_mach *mach)
{
struct platform_device *board;
+ struct avs_mach_pdata *pdata;
int num_ssps;
char *name;
int ret;
+ int uid;
num_ssps = adev->hw_cfg.i2s_caps.ctrl_count;
if (fls(mach->mach_params.i2s_link_mask) > num_ssps) {
@@ -490,18 +472,29 @@ static int avs_register_i2s_board(struct avs_dev *adev, struct snd_soc_acpi_mach
return -ENODEV;
}
- name = devm_kasprintf(adev->dev, GFP_KERNEL, "%s.%d-platform", mach->drv_name,
- mach->mach_params.i2s_link_mask);
+ pdata = mach->pdata;
+ if (!pdata)
+ pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+ pdata->obsolete_card_names = obsolete_card_names;
+ mach->pdata = pdata;
+
+ uid = mach->mach_params.i2s_link_mask;
+ if (avs_mach_singular_ssp(mach))
+ uid = (uid << AVS_CHANNELS_MAX) + avs_mach_ssp_tdm(mach, avs_mach_ssp_port(mach));
+
+ name = devm_kasprintf(adev->dev, GFP_KERNEL, "%s.%d-platform", mach->drv_name, uid);
if (!name)
return -ENOMEM;
- ret = avs_i2s_platform_register(adev, name, mach->mach_params.i2s_link_mask, mach->pdata);
+ ret = avs_i2s_platform_register(adev, name, mach->mach_params.i2s_link_mask, pdata->tdms);
if (ret < 0)
return ret;
mach->mach_params.platform = name;
- board = platform_device_register_data(NULL, mach->drv_name, mach->mach_params.i2s_link_mask,
+ board = platform_device_register_data(NULL, mach->drv_name, uid,
(const void *)mach, sizeof(*mach));
if (IS_ERR(board)) {
dev_err(adev->dev, "ssp board register failed\n");
@@ -517,35 +510,82 @@ static int avs_register_i2s_board(struct avs_dev *adev, struct snd_soc_acpi_mach
return 0;
}
-static int avs_register_i2s_boards(struct avs_dev *adev)
+static int avs_register_i2s_test_board(struct avs_dev *adev, int ssp_port, int tdm_slot)
{
- const struct avs_acpi_boards *boards;
struct snd_soc_acpi_mach *mach;
+ int tdm_mask = BIT(tdm_slot);
+ unsigned long *tdm_cfg;
+ char *tplg_name;
int ret;
- if (!adev->nhlt || !intel_nhlt_has_endpoint_type(adev->nhlt, NHLT_LINK_SSP)) {
- dev_dbg(adev->dev, "no I2S endpoints present\n");
- return 0;
+ mach = devm_kzalloc(adev->dev, sizeof(*mach), GFP_KERNEL);
+ tdm_cfg = devm_kcalloc(adev->dev, ssp_port + 1, sizeof(unsigned long), GFP_KERNEL);
+ tplg_name = devm_kasprintf(adev->dev, GFP_KERNEL, AVS_STRING_FMT("i2s", "-test-tplg.bin",
+ ssp_port, tdm_slot));
+ if (!mach || !tdm_cfg || !tplg_name)
+ return -ENOMEM;
+
+ mach->drv_name = "avs_i2s_test";
+ mach->mach_params.i2s_link_mask = AVS_SSP(ssp_port);
+ tdm_cfg[ssp_port] = tdm_mask;
+ mach->pdata = tdm_cfg;
+ mach->tplg_filename = tplg_name;
+
+ ret = avs_register_i2s_board(adev, mach);
+ if (ret < 0) {
+ dev_warn(adev->dev, "register i2s %s failed: %d\n", mach->drv_name, ret);
+ return ret;
}
- if (i2s_test) {
- int i, num_ssps;
+ return 0;
+}
+
+static int avs_register_i2s_test_boards(struct avs_dev *adev)
+{
+ int max_ssps = adev->hw_cfg.i2s_caps.ctrl_count;
+ int ssp_port, tdm_slot, ret;
+ unsigned long tdm_slots;
+ u32 *array, num_elems;
- num_ssps = adev->hw_cfg.i2s_caps.ctrl_count;
- /* constrain just in case FW says there can be more SSPs than possible */
- num_ssps = min_t(int, ARRAY_SIZE(avs_test_i2s_machines), num_ssps);
+ ret = parse_int_array(i2s_test, strlen(i2s_test), (int **)&array);
+ if (ret < 0) {
+ dev_err(adev->dev, "failed to parse i2s_test parameter\n");
+ return ret;
+ }
- mach = avs_test_i2s_machines;
+ num_elems = *array;
+ if (num_elems > max_ssps) {
+ dev_err(adev->dev, "board supports only %d SSP, %d specified\n",
+ max_ssps, num_elems);
+ return -EINVAL;
+ }
- for (i = 0; i < num_ssps; i++) {
- ret = avs_register_i2s_board(adev, &mach[i]);
- if (ret < 0)
- dev_warn(adev->dev, "register i2s %s failed: %d\n", mach->drv_name,
- ret);
+ for (ssp_port = 0; ssp_port < num_elems; ssp_port++) {
+ tdm_slots = array[1 + ssp_port];
+ for_each_set_bit(tdm_slot, &tdm_slots, 16) {
+ ret = avs_register_i2s_test_board(adev, ssp_port, tdm_slot);
+ if (ret)
+ return ret;
}
+ }
+
+ return 0;
+}
+
+static int avs_register_i2s_boards(struct avs_dev *adev)
+{
+ const struct avs_acpi_boards *boards;
+ struct snd_soc_acpi_mach *mach;
+ int ret;
+
+ if (!acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_SSP, -1, -1, -1)) {
+ dev_dbg(adev->dev, "no I2S endpoints present\n");
return 0;
}
+ if (i2s_test)
+ return avs_register_i2s_test_boards(adev);
+
boards = avs_get_i2s_boards(adev);
if (!boards) {
dev_dbg(adev->dev, "no I2S endpoints supported\n");
@@ -572,6 +612,7 @@ static int avs_register_hda_board(struct avs_dev *adev, struct hda_codec *codec)
{
struct snd_soc_acpi_mach mach = {{0}};
struct platform_device *board;
+ struct avs_mach_pdata *pdata;
struct hdac_device *hdev = &codec->core;
char *pname;
int ret, id;
@@ -580,11 +621,17 @@ static int avs_register_hda_board(struct avs_dev *adev, struct hda_codec *codec)
if (!pname)
return -ENOMEM;
+ pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+ pdata->obsolete_card_names = obsolete_card_names;
+ pdata->codec = codec;
+
ret = avs_hda_platform_register(adev, pname);
if (ret < 0)
return ret;
- mach.pdata = codec;
+ mach.pdata = pdata;
mach.mach_params.platform = pname;
mach.tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL, "hda-%08x-tplg.bin",
hdev->vendor_id);
diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig
index 00b0f6c176d6..8b654181004e 100644
--- a/sound/soc/intel/avs/boards/Kconfig
+++ b/sound/soc/intel/avs/boards/Kconfig
@@ -4,6 +4,14 @@ menu "Intel AVS Machine drivers"
comment "Available DSP configurations"
+config SND_SOC_INTEL_AVS_CARDNAME_OBSOLETE
+ bool "Use obsolete card names"
+ default n
+ help
+ Use obsolete names for some of avs cards. This option should be
+ used if your system depends on old card names, for example having
+ not up to date UCM files.
+
config SND_SOC_INTEL_AVS_MACH_DA7219
tristate "da7219 I2S board"
depends on I2C
@@ -87,6 +95,16 @@ config SND_SOC_INTEL_AVS_MACH_NAU8825
Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
+config SND_SOC_INTEL_AVS_MACH_PCM3168A
+ tristate "pcm3168a I2S board"
+ depends on I2C
+ depends on MFD_INTEL_LPSS || COMPILE_TEST
+ select SND_SOC_PCM3168A_I2C
+ help
+ This adds support for AVS with PCM3168A I2C codec configuration.
+ Say Y or m if you have such a device. This is a recommended option.
+ If unsure select "N".
+
config SND_SOC_INTEL_AVS_MACH_PROBE
tristate "Probing (data) board"
depends on DEBUG_FS
diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile
index 0ff21d55be24..a95256b94dc8 100644
--- a/sound/soc/intel/avs/boards/Makefile
+++ b/sound/soc/intel/avs/boards/Makefile
@@ -1,22 +1,23 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-soc-avs-da7219-objs := da7219.o
-snd-soc-avs-dmic-objs := dmic.o
-snd-soc-avs-es8336-objs := es8336.o
-snd-soc-avs-hdaudio-objs := hdaudio.o
-snd-soc-avs-i2s-test-objs := i2s_test.o
-snd-soc-avs-max98927-objs := max98927.o
-snd-soc-avs-max98357a-objs := max98357a.o
-snd-soc-avs-max98373-objs := max98373.o
-snd-soc-avs-nau8825-objs := nau8825.o
-snd-soc-avs-probe-objs := probe.o
-snd-soc-avs-rt274-objs := rt274.o
-snd-soc-avs-rt286-objs := rt286.o
-snd-soc-avs-rt298-objs := rt298.o
-snd-soc-avs-rt5514-objs := rt5514.o
-snd-soc-avs-rt5663-objs := rt5663.o
-snd-soc-avs-rt5682-objs := rt5682.o
-snd-soc-avs-ssm4567-objs := ssm4567.o
+snd-soc-avs-da7219-y := da7219.o
+snd-soc-avs-dmic-y := dmic.o
+snd-soc-avs-es8336-y := es8336.o
+snd-soc-avs-hdaudio-y := hdaudio.o
+snd-soc-avs-i2s-test-y := i2s_test.o
+snd-soc-avs-max98927-y := max98927.o
+snd-soc-avs-max98357a-y := max98357a.o
+snd-soc-avs-max98373-y := max98373.o
+snd-soc-avs-nau8825-y := nau8825.o
+snd-soc-avs-pcm3168a-y := pcm3168a.o
+snd-soc-avs-probe-y := probe.o
+snd-soc-avs-rt274-y := rt274.o
+snd-soc-avs-rt286-y := rt286.o
+snd-soc-avs-rt298-y := rt298.o
+snd-soc-avs-rt5514-y := rt5514.o
+snd-soc-avs-rt5663-y := rt5663.o
+snd-soc-avs-rt5682-y := rt5682.o
+snd-soc-avs-ssm4567-y := ssm4567.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DA7219) += snd-soc-avs-da7219.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o
@@ -27,6 +28,7 @@ obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98927) += snd-soc-avs-max98927.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A) += snd-soc-avs-max98357a.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98373) += snd-soc-avs-max98373.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825) += snd-soc-avs-nau8825.o
+obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_PCM3168A) += snd-soc-avs-pcm3168a.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_PROBE) += snd-soc-avs-probe.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT286) += snd-soc-avs-rt286.o
diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c
index fc072dc58968..3ef0db254142 100644
--- a/sound/soc/intel/avs/boards/da7219.c
+++ b/sound/soc/intel/avs/boards/da7219.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
//
@@ -113,7 +113,8 @@ static int avs_da7219_codec_init(struct snd_soc_pcm_runtime *runtime)
}
num_pins = ARRAY_SIZE(card_headset_pins);
- pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL);
+ pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins,
+ sizeof(card_headset_pins[0]), GFP_KERNEL);
if (!pins)
return -ENOMEM;
@@ -197,39 +198,23 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->platforms = platform;
dl->num_platforms = 1;
dl->id = 0;
- dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
dl->be_hw_params_fixup = avs_da7219_be_fixup;
dl->init = avs_da7219_codec_init;
dl->exit = avs_da7219_codec_exit;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
- dl->dpcm_playback = 1;
*dai_link = dl;
return 0;
}
-static int avs_card_suspend_pre(struct snd_soc_card *card)
-{
- struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, DA7219_DAI_NAME);
-
- return snd_soc_component_set_jack(codec_dai->component, NULL, NULL);
-}
-
-static int avs_card_resume_post(struct snd_soc_card *card)
-{
- struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, DA7219_DAI_NAME);
- struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card);
-
- return snd_soc_component_set_jack(codec_dai->component, jack, NULL);
-}
-
static int avs_da7219_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct snd_soc_jack *jack;
struct device *dev = &pdev->dev;
@@ -238,6 +223,7 @@ static int avs_da7219_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -254,11 +240,14 @@ static int avs_da7219_probe(struct platform_device *pdev)
if (!jack || !card)
return -ENOMEM;
- card->name = "avs_da7219";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_da7219";
+ } else {
+ card->driver_name = "avs_da7219";
+ card->long_name = card->name = "AVS I2S DA7219";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
- card->suspend_pre = avs_card_suspend_pre;
- card->resume_post = avs_card_resume_post;
card->dai_link = dai_link;
card->num_links = 1;
card->controls = card_controls;
@@ -274,7 +263,7 @@ static int avs_da7219_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_da7219_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/dmic.c b/sound/soc/intel/avs/boards/dmic.c
index d9e5e85f5233..a1448a98874d 100644
--- a/sound/soc/intel/avs/boards/dmic.c
+++ b/sound/soc/intel/avs/boards/dmic.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
+#include "../utils.h"
SND_SOC_DAILINK_DEF(dmic_pin, DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin")));
SND_SOC_DAILINK_DEF(dmic_wov_pin, DAILINK_COMP_ARRAY(COMP_CPU("DMIC WoV Pin")));
@@ -22,7 +23,7 @@ static struct snd_soc_dai_link card_dai_links[] = {
{
.name = "DMIC",
.id = 0,
- .dpcm_capture = 1,
+ .capture_only = 1,
.nonatomic = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform),
@@ -30,7 +31,7 @@ static struct snd_soc_dai_link card_dai_links[] = {
{
.name = "DMIC WoV",
.id = 1,
- .dpcm_capture = 1,
+ .capture_only = 1,
.nonatomic = 1,
.no_pcm = 1,
.ignore_suspend = 1,
@@ -49,17 +50,24 @@ static const struct snd_soc_dapm_route card_routes[] = {
static int avs_dmic_probe(struct platform_device *pdev)
{
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
int ret;
mach = dev_get_platdata(dev);
+ pdata = mach->pdata;
card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
if (!card)
return -ENOMEM;
- card->name = "avs_dmic";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_dmic";
+ } else {
+ card->driver_name = "avs_dmic";
+ card->long_name = card->name = "AVS DMIC";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->dai_link = card_dai_links;
@@ -74,7 +82,7 @@ static int avs_dmic_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_dmic_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/es8336.c b/sound/soc/intel/avs/boards/es8336.c
index 5c90a6007577..1955f2d383c5 100644
--- a/sound/soc/intel/avs/boards/es8336.c
+++ b/sound/soc/intel/avs/boards/es8336.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
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -18,7 +18,7 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
-#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
#include "../utils.h"
#define ES8336_CODEC_DAI "ES8316 HiFi"
@@ -85,7 +85,7 @@ static const struct snd_kcontrol_new card_controls[] = {
SOC_DAPM_PIN_SWITCH("Internal Mic"),
};
-static struct snd_soc_jack_pin card_headset_pins[] = {
+static const struct snd_soc_jack_pin card_headset_pins[] = {
{
.pin = "Headphone",
.mask = SND_JACK_HEADPHONE,
@@ -109,11 +109,12 @@ static int avs_es8336_codec_init(struct snd_soc_pcm_runtime *runtime)
data = snd_soc_card_get_drvdata(card);
num_pins = ARRAY_SIZE(card_headset_pins);
- pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL);
+ pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins,
+ sizeof(card_headset_pins[0]), GFP_KERNEL);
if (!pins)
return -ENOMEM;
- ret = snd_soc_card_jack_new_pins(card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0,
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_BTN_0,
&data->jack, pins, num_pins);
if (ret)
return ret;
@@ -153,9 +154,9 @@ static int avs_es8336_hw_params(struct snd_pcm_substream *substream,
int clk_freq;
int ret;
- switch (boot_cpu_data.x86_model) {
- case INTEL_FAM6_KABYLAKE_L:
- case INTEL_FAM6_KABYLAKE:
+ switch (boot_cpu_data.x86_vfm) {
+ case INTEL_KABYLAKE_L:
+ case INTEL_KABYLAKE:
clk_freq = 24000000;
break;
default:
@@ -233,8 +234,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->ops = &avs_es8336_ops;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
- dl->dpcm_playback = 1;
*dai_link = dl;
@@ -260,6 +259,7 @@ static int avs_es8336_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct avs_card_drvdata *data;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
@@ -268,6 +268,7 @@ static int avs_es8336_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -284,7 +285,12 @@ static int avs_es8336_probe(struct platform_device *pdev)
if (!data || !card)
return -ENOMEM;
- card->name = "avs_es8336";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_es8336";
+ } else {
+ card->driver_name = "avs_es8336";
+ card->long_name = card->name = "AVS I2S ES8336";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->suspend_pre = avs_card_suspend_pre;
@@ -304,7 +310,7 @@ static int avs_es8336_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_es8336_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/hdaudio.c b/sound/soc/intel/avs/boards/hdaudio.c
index 79b4aca41333..19b2255a8ac3 100644
--- a/sound/soc/intel/avs/boards/hdaudio.c
+++ b/sound/soc/intel/avs/boards/hdaudio.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -13,6 +13,7 @@
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "../../../codecs/hda.h"
+#include "../utils.h"
static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int pcm_count,
const char *platform_name, struct snd_soc_dai_link **links)
@@ -39,8 +40,6 @@ static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int
dl[i].id = i;
dl[i].nonatomic = 1;
dl[i].no_pcm = 1;
- dl[i].dpcm_playback = 1;
- dl[i].dpcm_capture = 1;
dl[i].platforms = platform;
dl[i].num_platforms = 1;
dl[i].ignore_pmdown_time = 1;
@@ -54,7 +53,7 @@ static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int
if (!dl[i].cpus->dai_name)
return -ENOMEM;
- dl[i].codecs->name = devm_kstrdup(dev, cname, GFP_KERNEL);
+ dl[i].codecs->name = devm_kstrdup_const(dev, cname, GFP_KERNEL);
if (!dl[i].codecs->name)
return -ENOMEM;
@@ -97,7 +96,8 @@ avs_card_hdmi_pcm_at(struct snd_soc_card *card, int hdmi_idx)
static int avs_card_late_probe(struct snd_soc_card *card)
{
struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
- struct hda_codec *codec = mach->pdata;
+ struct avs_mach_pdata *pdata = mach->pdata;
+ struct hda_codec *codec = pdata->codec;
struct hda_pcm *hpcm;
/* Topology pcm indexing is 1-based */
int i = 1;
@@ -126,6 +126,7 @@ static int avs_card_late_probe(struct snd_soc_card *card)
static int avs_probing_link_init(struct snd_soc_pcm_runtime *rtm)
{
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_dai_link *links = NULL;
struct snd_soc_card *card = rtm->card;
struct hda_codec *codec;
@@ -133,7 +134,8 @@ static int avs_probing_link_init(struct snd_soc_pcm_runtime *rtm)
int ret, pcm_count = 0;
mach = dev_get_platdata(card->dev);
- codec = mach->pdata;
+ pdata = mach->pdata;
+ codec = pdata->codec;
if (list_empty(&codec->pcm_list_head))
return -EINVAL;
@@ -155,13 +157,11 @@ static int avs_probing_link_init(struct snd_soc_pcm_runtime *rtm)
return 0;
}
-static struct snd_soc_dai_link probing_link = {
+static const struct snd_soc_dai_link probing_link = {
.name = "probing-LINK",
.id = -1,
.nonatomic = 1,
.no_pcm = 1,
- .dpcm_playback = 1,
- .dpcm_capture = 1,
.cpus = &snd_soc_dummy_dlc,
.num_cpus = 1,
.init = avs_probing_link_init,
@@ -171,12 +171,14 @@ static int avs_hdaudio_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *binder;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
struct hda_codec *codec;
mach = dev_get_platdata(dev);
- codec = mach->pdata;
+ pdata = mach->pdata;
+ codec = pdata->codec;
/* codec may be unloaded before card's probe() fires */
if (!device_is_registered(&codec->core.dev))
@@ -191,7 +193,7 @@ static int avs_hdaudio_probe(struct platform_device *pdev)
if (!binder->platforms || !binder->codecs)
return -ENOMEM;
- binder->codecs->name = devm_kstrdup(dev, dev_name(&codec->core.dev), GFP_KERNEL);
+ binder->codecs->name = devm_kstrdup_const(dev, dev_name(&codec->core.dev), GFP_KERNEL);
if (!binder->codecs->name)
return -ENOMEM;
@@ -204,7 +206,16 @@ static int avs_hdaudio_probe(struct platform_device *pdev)
if (!card)
return -ENOMEM;
- card->name = binder->codecs->name;
+ if (pdata->obsolete_card_names) {
+ card->name = binder->codecs->name;
+ } else {
+ card->driver_name = "avs_hdaudio";
+ if (hda_codec_is_display(codec))
+ card->long_name = card->name = "AVS HDMI";
+ else
+ card->long_name = card->name = "AVS HD-Audio";
+ }
+
card->dev = dev;
card->owner = THIS_MODULE;
card->dai_link = binder;
@@ -213,7 +224,7 @@ static int avs_hdaudio_probe(struct platform_device *pdev)
if (hda_codec_is_display(codec))
card->late_probe = avs_card_late_probe;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_hdaudio_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/i2s_test.c b/sound/soc/intel/avs/boards/i2s_test.c
index 027373d6a16d..f7b6d7715738 100644
--- a/sound/soc/intel/avs/boards/i2s_test.c
+++ b/sound/soc/intel/avs/boards/i2s_test.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -46,88 +46,25 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->id = 0;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
- dl->dpcm_playback = 1;
*dai_link = dl;
return 0;
}
-static int avs_create_dapm_routes(struct device *dev, int ssp_port, int tdm_slot,
- struct snd_soc_dapm_route **routes, int *num_routes)
-{
- struct snd_soc_dapm_route *dr;
- const int num_dr = 2;
-
- dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL);
- if (!dr)
- return -ENOMEM;
-
- dr[0].sink = devm_kasprintf(dev, GFP_KERNEL,
- AVS_STRING_FMT("ssp", "pb", ssp_port, tdm_slot));
- dr[0].source = devm_kasprintf(dev, GFP_KERNEL,
- AVS_STRING_FMT("ssp", " Tx", ssp_port, tdm_slot));
- if (!dr[0].sink || !dr[0].source)
- return -ENOMEM;
-
- dr[1].sink = devm_kasprintf(dev, GFP_KERNEL,
- AVS_STRING_FMT("ssp", " Rx", ssp_port, tdm_slot));
- dr[1].source = devm_kasprintf(dev, GFP_KERNEL,
- AVS_STRING_FMT("ssp", "cp", ssp_port, tdm_slot));
- if (!dr[1].sink || !dr[1].source)
- return -ENOMEM;
-
- *routes = dr;
- *num_routes = num_dr;
-
- return 0;
-}
-
-static int avs_create_dapm_widgets(struct device *dev, int ssp_port, int tdm_slot,
- struct snd_soc_dapm_widget **widgets, int *num_widgets)
-{
- struct snd_soc_dapm_widget *dw;
- const int num_dw = 2;
-
- dw = devm_kcalloc(dev, num_dw, sizeof(*dw), GFP_KERNEL);
- if (!dw)
- return -ENOMEM;
-
- dw[0].id = snd_soc_dapm_hp;
- dw[0].reg = SND_SOC_NOPM;
- dw[0].name = devm_kasprintf(dev, GFP_KERNEL,
- AVS_STRING_FMT("ssp", "pb", ssp_port, tdm_slot));
- if (!dw[0].name)
- return -ENOMEM;
-
- dw[1].id = snd_soc_dapm_mic;
- dw[1].reg = SND_SOC_NOPM;
- dw[1].name = devm_kasprintf(dev, GFP_KERNEL,
- AVS_STRING_FMT("ssp", "cp", ssp_port, tdm_slot));
- if (!dw[1].name)
- return -ENOMEM;
-
- *widgets = dw;
- *num_widgets = num_dw;
-
- return 0;
-}
-
static int avs_i2s_test_probe(struct platform_device *pdev)
{
- struct snd_soc_dapm_widget *widgets;
- struct snd_soc_dapm_route *routes;
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
const char *pname;
- int num_routes, num_widgets;
int ssp_port, tdm_slot, ret;
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
if (!avs_mach_singular_ssp(mach)) {
dev_err(dev, "Invalid SSP configuration\n");
@@ -145,8 +82,15 @@ static int avs_i2s_test_probe(struct platform_device *pdev)
if (!card)
return -ENOMEM;
- card->name = devm_kasprintf(dev, GFP_KERNEL,
- AVS_STRING_FMT("ssp", "-loopback", ssp_port, tdm_slot));
+ if (pdata->obsolete_card_names) {
+ card->name = devm_kasprintf(dev, GFP_KERNEL,
+ AVS_STRING_FMT("ssp", "-loopback", ssp_port, tdm_slot));
+ } else {
+ card->driver_name = "avs_i2s_test";
+ card->long_name = card->name = devm_kasprintf(dev, GFP_KERNEL,
+ AVS_STRING_FMT("AVS I2S TEST-", "",
+ ssp_port, tdm_slot));
+ }
if (!card->name)
return -ENOMEM;
@@ -156,33 +100,17 @@ static int avs_i2s_test_probe(struct platform_device *pdev)
return ret;
}
- ret = avs_create_dapm_routes(dev, ssp_port, tdm_slot, &routes, &num_routes);
- if (ret) {
- dev_err(dev, "Failed to create dapm routes: %d\n", ret);
- return ret;
- }
-
- ret = avs_create_dapm_widgets(dev, ssp_port, tdm_slot, &widgets, &num_widgets);
- if (ret) {
- dev_err(dev, "Failed to create dapm widgets: %d\n", ret);
- return ret;
- }
-
card->dev = dev;
card->owner = THIS_MODULE;
card->dai_link = dai_link;
card->num_links = 1;
- card->dapm_routes = routes;
- card->num_dapm_routes = num_routes;
- card->dapm_widgets = widgets;
- card->num_dapm_widgets = num_widgets;
card->fully_routed = true;
ret = snd_soc_fixup_dai_links_platform_name(card, pname);
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_i2s_test_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/max98357a.c b/sound/soc/intel/avs/boards/max98357a.c
index 1ff85e4d8e16..72053f83e98b 100644
--- a/sound/soc/intel/avs/boards/max98357a.c
+++ b/sound/soc/intel/avs/boards/max98357a.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -78,11 +78,11 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->platforms = platform;
dl->num_platforms = 1;
dl->id = 0;
- dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
dl->be_hw_params_fixup = avs_max98357a_be_fixup;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_playback = 1;
+ dl->playback_only = 1;
*dai_link = dl;
@@ -93,6 +93,7 @@ static int avs_max98357a_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
const char *pname;
@@ -100,6 +101,7 @@ static int avs_max98357a_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -115,7 +117,12 @@ static int avs_max98357a_probe(struct platform_device *pdev)
if (!card)
return -ENOMEM;
- card->name = "avs_max98357a";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_max98357a";
+ } else {
+ card->driver_name = "avs_max98357a";
+ card->long_name = card->name = "AVS I2S MAX98357A";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->dai_link = dai_link;
@@ -132,7 +139,7 @@ static int avs_max98357a_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_max98357a_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/max98373.c b/sound/soc/intel/avs/boards/max98373.c
index 8d31586b73ea..cdba1c3ee20b 100644
--- a/sound/soc/intel/avs/boards/max98373.c
+++ b/sound/soc/intel/avs/boards/max98373.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
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -111,7 +111,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
- dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs) * 2, GFP_KERNEL);
+ dl->codecs = devm_kcalloc(dev, 2, sizeof(*dl->codecs), GFP_KERNEL);
if (!dl->name || !dl->cpus || !dl->codecs)
return -ENOMEM;
@@ -134,8 +134,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->be_hw_params_fixup = avs_max98373_be_fixup;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
- dl->dpcm_playback = 1;
dl->ignore_pmdown_time = 1;
dl->ops = &avs_max98373_ops;
@@ -148,6 +146,7 @@ static int avs_max98373_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
const char *pname;
@@ -155,6 +154,7 @@ static int avs_max98373_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -170,7 +170,12 @@ static int avs_max98373_probe(struct platform_device *pdev)
if (!card)
return -ENOMEM;
- card->name = "avs_max98373";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_max98373";
+ } else {
+ card->driver_name = "avs_max98373";
+ card->long_name = card->name = "AVS I2S MAX98373";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->dai_link = dai_link;
@@ -189,7 +194,7 @@ static int avs_max98373_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_max98373_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/max98927.c b/sound/soc/intel/avs/boards/max98927.c
index 572ec58073d0..a68e227044c5 100644
--- a/sound/soc/intel/avs/boards/max98927.c
+++ b/sound/soc/intel/avs/boards/max98927.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
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -108,7 +108,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
- dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs) * 2, GFP_KERNEL);
+ dl->codecs = devm_kcalloc(dev, 2, sizeof(*dl->codecs), GFP_KERNEL);
if (!dl->name || !dl->cpus || !dl->codecs)
return -ENOMEM;
@@ -127,12 +127,10 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->platforms = platform;
dl->num_platforms = 1;
dl->id = 0;
- dl->dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ dl->dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
dl->be_hw_params_fixup = avs_max98927_be_fixup;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
- dl->dpcm_playback = 1;
dl->ignore_pmdown_time = 1;
dl->ops = &avs_max98927_ops;
@@ -145,6 +143,7 @@ static int avs_max98927_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
const char *pname;
@@ -152,6 +151,7 @@ static int avs_max98927_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -167,7 +167,12 @@ static int avs_max98927_probe(struct platform_device *pdev)
if (!card)
return -ENOMEM;
- card->name = "avs_max98927";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_max98927";
+ } else {
+ card->driver_name = "avs_max98927";
+ card->long_name = card->name = "AVS I2S MAX98927";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->dai_link = dai_link;
@@ -186,7 +191,7 @@ static int avs_max98927_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_max98927_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/nau8825.c b/sound/soc/intel/avs/boards/nau8825.c
index 55db75efae41..3fb1a5d07ae1 100644
--- a/sound/soc/intel/avs/boards/nau8825.c
+++ b/sound/soc/intel/avs/boards/nau8825.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -67,7 +67,7 @@ static const struct snd_soc_dapm_route card_base_routes[] = {
{ "Headset Mic", NULL, "Platform Clock" },
};
-static struct snd_soc_jack_pin card_headset_pins[] = {
+static const struct snd_soc_jack_pin card_headset_pins[] = {
{
.pin = "Headphone Jack",
.mask = SND_JACK_HEADPHONE,
@@ -88,7 +88,8 @@ static int avs_nau8825_codec_init(struct snd_soc_pcm_runtime *runtime)
jack = snd_soc_card_get_drvdata(card);
num_pins = ARRAY_SIZE(card_headset_pins);
- pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL);
+ pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins,
+ sizeof(card_headset_pins[0]), GFP_KERNEL);
if (!pins)
return -ENOMEM;
@@ -96,7 +97,7 @@ static int avs_nau8825_codec_init(struct snd_soc_pcm_runtime *runtime)
* 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(card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0 |
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_BTN_0 |
SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3,
jack, pins, num_pins);
if (ret)
@@ -203,15 +204,13 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->platforms = platform;
dl->num_platforms = 1;
dl->id = 0;
- dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
dl->init = avs_nau8825_codec_init;
dl->exit = avs_nau8825_codec_exit;
dl->be_hw_params_fixup = avs_nau8825_be_fixup;
dl->ops = &avs_nau8825_ops;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
- dl->dpcm_playback = 1;
*dai_link = dl;
@@ -247,6 +246,7 @@ static int avs_nau8825_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct snd_soc_jack *jack;
struct device *dev = &pdev->dev;
@@ -255,6 +255,7 @@ static int avs_nau8825_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -271,7 +272,12 @@ static int avs_nau8825_probe(struct platform_device *pdev)
if (!jack || !card)
return -ENOMEM;
- card->name = "avs_nau8825";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_nau8825";
+ } else {
+ card->driver_name = "avs_nau8825";
+ card->long_name = card->name = "AVS I2S NAU8825";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->suspend_pre = avs_card_suspend_pre;
@@ -291,7 +297,7 @@ static int avs_nau8825_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_nau8825_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/pcm3168a.c b/sound/soc/intel/avs/boards/pcm3168a.c
new file mode 100644
index 000000000000..b5bebadbbcb2
--- /dev/null
+++ b/sound/soc/intel/avs/boards/pcm3168a.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright(c) 2024-2025 Intel Corporation
+//
+// Author: Cezary Rojewski <cezary.rojewski@intel.com>
+//
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
+#include "../utils.h"
+
+static const struct snd_soc_dapm_widget card_widgets[] = {
+ SND_SOC_DAPM_HP("CPB Stereo HP 1", NULL),
+ SND_SOC_DAPM_HP("CPB Stereo HP 2", NULL),
+ SND_SOC_DAPM_HP("CPB Stereo HP 3", NULL),
+ SND_SOC_DAPM_LINE("CPB Line Out", NULL),
+ SND_SOC_DAPM_MIC("CPB Stereo Mic 1", NULL),
+ SND_SOC_DAPM_MIC("CPB Stereo Mic 2", NULL),
+ SND_SOC_DAPM_LINE("CPB Line In", NULL),
+};
+
+static const struct snd_soc_dapm_route card_routes[] = {
+ { "CPB Stereo HP 1", NULL, "AOUT1L" },
+ { "CPB Stereo HP 1", NULL, "AOUT1R" },
+ { "CPB Stereo HP 2", NULL, "AOUT2L" },
+ { "CPB Stereo HP 2", NULL, "AOUT2R" },
+ { "CPB Stereo HP 3", NULL, "AOUT3L" },
+ { "CPB Stereo HP 3", NULL, "AOUT3R" },
+ { "CPB Line Out", NULL, "AOUT4L" },
+ { "CPB Line Out", NULL, "AOUT4R" },
+
+ { "AIN1L", NULL, "CPB Stereo Mic 1" },
+ { "AIN1R", NULL, "CPB Stereo Mic 1" },
+ { "AIN2L", NULL, "CPB Stereo Mic 2" },
+ { "AIN2R", NULL, "CPB Stereo Mic 2" },
+ { "AIN3L", NULL, "CPB Line In" },
+ { "AIN3R", NULL, "CPB Line In" },
+};
+
+static int avs_pcm3168a_be_fixup(struct snd_soc_pcm_runtime *runtime,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+
+ /* Set SSP to 24 bit. */
+ snd_mask_none(fmt);
+ snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
+
+ return 0;
+}
+
+SND_SOC_DAILINK_DEF(pcm3168a_dac,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-PCM3168A:00", "pcm3168a-dac")));
+SND_SOC_DAILINK_DEF(pcm3168a_adc,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-PCM3168A:00", "pcm3168a-adc")));
+SND_SOC_DAILINK_DEF(cpu_ssp0, DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin")));
+SND_SOC_DAILINK_DEF(cpu_ssp2, DAILINK_COMP_ARRAY(COMP_CPU("SSP2 Pin")));
+
+static int avs_create_dai_links(struct device *dev, struct snd_soc_dai_link **links, int *num_links)
+{
+ struct snd_soc_dai_link_component *platform;
+ struct snd_soc_dai_link *dl;
+ const int num_dl = 2;
+
+ dl = devm_kcalloc(dev, num_dl, sizeof(*dl), GFP_KERNEL);
+ platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL);
+ if (!dl || !platform)
+ return -ENOMEM;
+
+ platform->name = dev_name(dev);
+ dl[0].num_cpus = 1;
+ dl[0].num_codecs = 1;
+ dl[0].platforms = platform;
+ dl[0].num_platforms = 1;
+ dl[0].dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
+ dl[0].be_hw_params_fixup = avs_pcm3168a_be_fixup;
+ dl[0].nonatomic = 1;
+ dl[0].no_pcm = 1;
+ memcpy(&dl[1], &dl[0], sizeof(*dl));
+
+ dl[0].name = "SSP0-Codec-dac";
+ dl[0].cpus = cpu_ssp0;
+ dl[0].codecs = pcm3168a_dac;
+ dl[1].name = "SSP2-Codec-adc";
+ dl[1].cpus = cpu_ssp2;
+ dl[1].codecs = pcm3168a_adc;
+
+ *links = dl;
+ *num_links = num_dl;
+ return 0;
+}
+
+static int avs_pcm3168a_probe(struct platform_device *pdev)
+{
+ struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
+ struct device *dev = &pdev->dev;
+ struct snd_soc_card *card;
+ int ret;
+
+ mach = dev_get_platdata(dev);
+ pdata = mach->pdata;
+
+ card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
+ if (!card)
+ return -ENOMEM;
+
+ ret = avs_create_dai_links(dev, &card->dai_link, &card->num_links);
+ if (ret)
+ return ret;
+
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_pcm3168a";
+ } else {
+ card->driver_name = "avs_pcm3168a";
+ card->long_name = card->name = "AVS I2S PCM3168A";
+ }
+ card->dev = dev;
+ card->owner = THIS_MODULE;
+ card->dapm_widgets = card_widgets;
+ card->num_dapm_widgets = ARRAY_SIZE(card_widgets);
+ card->dapm_routes = card_routes;
+ card->num_dapm_routes = ARRAY_SIZE(card_routes);
+ card->fully_routed = true;
+
+ return devm_snd_soc_register_deferrable_card(dev, card);
+}
+
+static const struct platform_device_id avs_pcm3168a_driver_ids[] = {
+ {
+ .name = "avs_pcm3168a",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(platform, avs_pcm3168a_driver_ids);
+
+static struct platform_driver avs_pcm3168a_driver = {
+ .probe = avs_pcm3168a_probe,
+ .driver = {
+ .name = "avs_pcm3168a",
+ .pm = &snd_soc_pm_ops,
+ },
+ .id_table = avs_pcm3168a_driver_ids,
+};
+
+module_platform_driver(avs_pcm3168a_driver);
+
+MODULE_DESCRIPTION("Intel pcm3168a machine driver");
+MODULE_AUTHOR("Cezary Rojewski <cezary.rojewski@intel.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/intel/avs/boards/probe.c b/sound/soc/intel/avs/boards/probe.c
index 8be6887bbc6e..06c1f19f27aa 100644
--- a/sound/soc/intel/avs/boards/probe.c
+++ b/sound/soc/intel/avs/boards/probe.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -36,7 +36,8 @@ static int avs_probe_mb_probe(struct platform_device *pdev)
if (!card)
return -ENOMEM;
- card->name = "avs_probe_mb";
+ card->driver_name = "avs_probe_mb";
+ card->long_name = card->name = "AVS PROBE";
card->dev = dev;
card->owner = THIS_MODULE;
card->dai_link = probe_mb_dai_links;
@@ -47,7 +48,7 @@ static int avs_probe_mb_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_probe_mb_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/rt274.c b/sound/soc/intel/avs/boards/rt274.c
index 1cf524216087..ec5382925157 100644
--- a/sound/soc/intel/avs/boards/rt274.c
+++ b/sound/soc/intel/avs/boards/rt274.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -75,7 +75,7 @@ static const struct snd_soc_dapm_route card_base_routes[] = {
{"MIC", NULL, "Platform Clock"},
};
-static struct snd_soc_jack_pin card_headset_pins[] = {
+static const struct snd_soc_jack_pin card_headset_pins[] = {
{
.pin = "Headphone Jack",
.mask = SND_JACK_HEADPHONE,
@@ -98,11 +98,13 @@ static int avs_rt274_codec_init(struct snd_soc_pcm_runtime *runtime)
jack = snd_soc_card_get_drvdata(card);
num_pins = ARRAY_SIZE(card_headset_pins);
- pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL);
+ pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins,
+ sizeof(card_headset_pins[0]), GFP_KERNEL);
if (!pins)
return -ENOMEM;
- ret = snd_soc_card_jack_new_pins(card, "Headset", SND_JACK_HEADSET, jack, pins, num_pins);
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack", SND_JACK_HEADSET, jack, pins,
+ num_pins);
if (ret)
return ret;
@@ -177,14 +179,12 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->platforms = platform;
dl->num_platforms = 1;
dl->id = 0;
- dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
dl->init = avs_rt274_codec_init;
dl->exit = avs_rt274_codec_exit;
dl->be_hw_params_fixup = avs_rt274_be_fixup;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
- dl->dpcm_playback = 1;
*dai_link = dl;
@@ -210,6 +210,7 @@ static int avs_rt274_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct snd_soc_jack *jack;
struct device *dev = &pdev->dev;
@@ -218,6 +219,7 @@ static int avs_rt274_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -234,7 +236,12 @@ static int avs_rt274_probe(struct platform_device *pdev)
if (!jack || !card)
return -ENOMEM;
- card->name = "avs_rt274";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_rt274";
+ } else {
+ card->driver_name = "avs_rt274";
+ card->long_name = card->name = "AVS I2S ALC274";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->suspend_pre = avs_card_suspend_pre;
@@ -254,7 +261,7 @@ static int avs_rt274_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_rt274_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/rt286.c b/sound/soc/intel/avs/boards/rt286.c
index 4740bba10570..2566e971ce1c 100644
--- a/sound/soc/intel/avs/boards/rt286.c
+++ b/sound/soc/intel/avs/boards/rt286.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -38,7 +38,7 @@ static const struct snd_soc_dapm_route card_base_routes[] = {
{"Speaker", NULL, "SPOL"},
};
-static struct snd_soc_jack_pin card_headset_pins[] = {
+static const struct snd_soc_jack_pin card_headset_pins[] = {
{
.pin = "Headphone Jack",
.mask = SND_JACK_HEADPHONE,
@@ -59,12 +59,13 @@ static int avs_rt286_codec_init(struct snd_soc_pcm_runtime *runtime)
jack = snd_soc_card_get_drvdata(card);
num_pins = ARRAY_SIZE(card_headset_pins);
- pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL);
+ pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins,
+ sizeof(card_headset_pins[0]), GFP_KERNEL);
if (!pins)
return -ENOMEM;
- ret = snd_soc_card_jack_new_pins(card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, jack,
- pins, num_pins);
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_BTN_0,
+ jack, pins, num_pins);
if (ret)
return ret;
@@ -146,15 +147,13 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->platforms = platform;
dl->num_platforms = 1;
dl->id = 0;
- dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
dl->init = avs_rt286_codec_init;
dl->exit = avs_rt286_codec_exit;
dl->be_hw_params_fixup = avs_rt286_be_fixup;
dl->ops = &avs_rt286_ops;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
- dl->dpcm_playback = 1;
*dai_link = dl;
@@ -180,6 +179,7 @@ static int avs_rt286_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct snd_soc_jack *jack;
struct device *dev = &pdev->dev;
@@ -188,6 +188,7 @@ static int avs_rt286_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -205,7 +206,12 @@ static int avs_rt286_probe(struct platform_device *pdev)
if (!jack || !card)
return -ENOMEM;
- card->name = "avs_rt286";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_rt286";
+ } else {
+ card->driver_name = "avs_rt286";
+ card->long_name = card->name = "AVS I2S ALC286";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->suspend_pre = avs_card_suspend_pre;
@@ -225,7 +231,7 @@ static int avs_rt286_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_rt286_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c
index 6e409e29f697..7be34c8ad167 100644
--- a/sound/soc/intel/avs/boards/rt298.c
+++ b/sound/soc/intel/avs/boards/rt298.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -49,7 +49,7 @@ static const struct snd_soc_dapm_route card_base_routes[] = {
{"Speaker", NULL, "SPOL"},
};
-static struct snd_soc_jack_pin card_headset_pins[] = {
+static const struct snd_soc_jack_pin card_headset_pins[] = {
{
.pin = "Headphone Jack",
.mask = SND_JACK_HEADPHONE,
@@ -70,12 +70,13 @@ static int avs_rt298_codec_init(struct snd_soc_pcm_runtime *runtime)
jack = snd_soc_card_get_drvdata(card);
num_pins = ARRAY_SIZE(card_headset_pins);
- pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL);
+ pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins,
+ sizeof(card_headset_pins[0]), GFP_KERNEL);
if (!pins)
return -ENOMEM;
- ret = snd_soc_card_jack_new_pins(card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, jack,
- pins, num_pins);
+ ret = snd_soc_card_jack_new_pins(card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_BTN_0,
+ jack, pins, num_pins);
if (ret)
return ret;
@@ -164,17 +165,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->num_platforms = 1;
dl->id = 0;
if (dmi_first_match(kblr_dmi_table))
- dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
else
- dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
dl->init = avs_rt298_codec_init;
dl->exit = avs_rt298_codec_exit;
dl->be_hw_params_fixup = avs_rt298_be_fixup;
dl->ops = &avs_rt298_ops;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
- dl->dpcm_playback = 1;
*dai_link = dl;
@@ -200,6 +199,7 @@ static int avs_rt298_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct snd_soc_jack *jack;
struct device *dev = &pdev->dev;
@@ -208,6 +208,7 @@ static int avs_rt298_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -224,7 +225,12 @@ static int avs_rt298_probe(struct platform_device *pdev)
if (!jack || !card)
return -ENOMEM;
- card->name = "avs_rt298";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_rt298";
+ } else {
+ card->driver_name = "avs_rt298";
+ card->long_name = card->name = "AVS I2S ALC298";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->suspend_pre = avs_card_suspend_pre;
@@ -244,7 +250,7 @@ static int avs_rt298_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_rt298_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/rt5514.c b/sound/soc/intel/avs/boards/rt5514.c
index 097ae5f73241..45f091f2ce22 100644
--- a/sound/soc/intel/avs/boards/rt5514.c
+++ b/sound/soc/intel/avs/boards/rt5514.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2023 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2023 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -116,12 +116,12 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->platforms = platform;
dl->num_platforms = 1;
dl->id = 0;
- dl->dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ dl->dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
dl->init = avs_rt5514_codec_init;
dl->be_hw_params_fixup = avs_rt5514_be_fixup;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
+ dl->capture_only = 1;
dl->ops = &avs_rt5514_ops;
*dai_link = dl;
@@ -133,6 +133,7 @@ static int avs_rt5514_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
const char *pname;
@@ -140,6 +141,7 @@ static int avs_rt5514_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -155,7 +157,12 @@ static int avs_rt5514_probe(struct platform_device *pdev)
if (!card)
return -ENOMEM;
- card->name = "avs_rt5514";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_rt5514";
+ } else {
+ card->driver_name = "avs_rt5514";
+ card->long_name = card->name = "AVS I2S ALC5514";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->dai_link = dai_link;
@@ -170,7 +177,7 @@ static int avs_rt5514_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_rt5514_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/rt5663.c b/sound/soc/intel/avs/boards/rt5663.c
index 1880c315cc4d..122b6c48fd80 100644
--- a/sound/soc/intel/avs/boards/rt5663.c
+++ b/sound/soc/intel/avs/boards/rt5663.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2022-2023 Intel Corporation. All rights reserved.
+// Copyright(c) 2022-2023 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -43,7 +43,7 @@ static const struct snd_soc_dapm_route card_routes[] = {
{ "IN1N", NULL, "Headset Mic" },
};
-static struct snd_soc_jack_pin card_headset_pins[] = {
+static const struct snd_soc_jack_pin card_headset_pins[] = {
{
.pin = "Headphone Jack",
.mask = SND_JACK_HEADPHONE,
@@ -65,7 +65,8 @@ static int avs_rt5663_codec_init(struct snd_soc_pcm_runtime *runtime)
jack = &priv->jack;
num_pins = ARRAY_SIZE(card_headset_pins);
- pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL);
+ pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins,
+ sizeof(card_headset_pins[0]), GFP_KERNEL);
if (!pins)
return -ENOMEM;
@@ -171,8 +172,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->be_hw_params_fixup = avs_rt5663_be_fixup;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
- dl->dpcm_playback = 1;
dl->ops = &avs_rt5663_ops;
*dai_link = dl;
@@ -199,6 +198,7 @@ static int avs_rt5663_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct rt5663_private *priv;
struct device *dev = &pdev->dev;
@@ -207,6 +207,7 @@ static int avs_rt5663_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -223,7 +224,12 @@ static int avs_rt5663_probe(struct platform_device *pdev)
if (!priv || !card)
return -ENOMEM;
- card->name = "avs_rt5663";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_rt5663";
+ } else {
+ card->driver_name = "avs_rt5663";
+ card->long_name = card->name = "AVS I2S ALC5640";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->suspend_pre = avs_card_suspend_pre;
@@ -243,7 +249,7 @@ static int avs_rt5663_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_rt5663_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/rt5682.c b/sound/soc/intel/avs/boards/rt5682.c
index 594a971ded9e..9677b9ebeff1 100644
--- a/sound/soc/intel/avs/boards/rt5682.c
+++ b/sound/soc/intel/avs/boards/rt5682.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -80,7 +80,7 @@ static const struct snd_soc_dapm_route card_base_routes[] = {
{ "IN1P", NULL, "Headset Mic" },
};
-static struct snd_soc_jack_pin card_jack_pins[] = {
+static const struct snd_soc_jack_pin card_jack_pins[] = {
{
.pin = "Headphone Jack",
.mask = SND_JACK_HEADPHONE,
@@ -102,7 +102,8 @@ static int avs_rt5682_codec_init(struct snd_soc_pcm_runtime *runtime)
jack = snd_soc_card_get_drvdata(card);
num_pins = ARRAY_SIZE(card_jack_pins);
- pins = devm_kmemdup(card->dev, card_jack_pins, sizeof(*pins) * num_pins, GFP_KERNEL);
+ pins = devm_kmemdup_array(card->dev, card_jack_pins, num_pins,
+ sizeof(card_jack_pins[0]), GFP_KERNEL);
if (!pins)
return -ENOMEM;
@@ -242,8 +243,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->ops = &avs_rt5682_ops;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
- dl->dpcm_playback = 1;
*dai_link = dl;
@@ -269,6 +268,7 @@ static int avs_rt5682_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct snd_soc_jack *jack;
struct device *dev = &pdev->dev;
@@ -283,6 +283,7 @@ static int avs_rt5682_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -299,7 +300,12 @@ static int avs_rt5682_probe(struct platform_device *pdev)
if (!jack || !card)
return -ENOMEM;
- card->name = "avs_rt5682";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_rt5682";
+ } else {
+ card->driver_name = "avs_rt5682";
+ card->long_name = card->name = "AVS I2S ALC5682";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->suspend_pre = avs_card_suspend_pre;
@@ -319,7 +325,7 @@ static int avs_rt5682_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_rt5682_driver_ids[] = {
diff --git a/sound/soc/intel/avs/boards/ssm4567.c b/sound/soc/intel/avs/boards/ssm4567.c
index d6f7f046c24e..3786eef8c494 100644
--- a/sound/soc/intel/avs/boards/ssm4567.c
+++ b/sound/soc/intel/avs/boards/ssm4567.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -37,8 +37,6 @@ static const struct snd_kcontrol_new card_controls[] = {
static const struct snd_soc_dapm_widget card_widgets[] = {
SND_SOC_DAPM_SPK("Left Speaker", NULL),
SND_SOC_DAPM_SPK("Right Speaker", NULL),
- SND_SOC_DAPM_SPK("DP1", NULL),
- SND_SOC_DAPM_SPK("DP2", NULL),
};
static const struct snd_soc_dapm_route card_base_routes[] = {
@@ -99,7 +97,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->name = devm_kasprintf(dev, GFP_KERNEL,
AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot));
dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
- dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs) * 2, GFP_KERNEL);
+ dl->codecs = devm_kcalloc(dev, 2, sizeof(*dl->codecs), GFP_KERNEL);
if (!dl->name || !dl->cpus || !dl->codecs)
return -ENOMEM;
@@ -118,13 +116,11 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
dl->platforms = platform;
dl->num_platforms = 1;
dl->id = 0;
- dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBC_CFC;
dl->init = avs_ssm4567_codec_init;
dl->be_hw_params_fixup = avs_ssm4567_be_fixup;
dl->nonatomic = 1;
dl->no_pcm = 1;
- dl->dpcm_capture = 1;
- dl->dpcm_playback = 1;
dl->ignore_pmdown_time = 1;
*dai_link = dl;
@@ -136,6 +132,7 @@ static int avs_ssm4567_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai_link;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
const char *pname;
@@ -143,6 +140,7 @@ static int avs_ssm4567_probe(struct platform_device *pdev)
mach = dev_get_platdata(dev);
pname = mach->mach_params.platform;
+ pdata = mach->pdata;
ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot);
if (ret)
@@ -158,7 +156,12 @@ static int avs_ssm4567_probe(struct platform_device *pdev)
if (!card)
return -ENOMEM;
- card->name = "avs_ssm4567-adi";
+ if (pdata->obsolete_card_names) {
+ card->name = "avs_ssm4567";
+ } else {
+ card->driver_name = "avs_ssm4567";
+ card->long_name = card->name = "AVS I2S SSM4567";
+ }
card->dev = dev;
card->owner = THIS_MODULE;
card->dai_link = dai_link;
@@ -172,13 +175,12 @@ static int avs_ssm4567_probe(struct platform_device *pdev)
card->dapm_routes = card_base_routes;
card->num_dapm_routes = ARRAY_SIZE(card_base_routes);
card->fully_routed = true;
- card->disable_route_checks = true;
ret = snd_soc_fixup_dai_links_platform_name(card, pname);
if (ret)
return ret;
- return devm_snd_soc_register_card(dev, card);
+ return devm_snd_soc_register_deferrable_card(dev, card);
}
static const struct platform_device_id avs_ssm4567_driver_ids[] = {
diff --git a/sound/soc/intel/avs/cldma.c b/sound/soc/intel/avs/cldma.c
index d7a9390b5e48..61326d7059b1 100644
--- a/sound/soc/intel/avs/cldma.c
+++ b/sound/soc/intel/avs/cldma.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
//
@@ -35,7 +35,7 @@ struct hda_cldma {
unsigned int buffer_size;
unsigned int num_periods;
- unsigned int stream_tag;
+ unsigned char stream_tag;
void __iomem *sd_addr;
struct snd_dma_buffer dmab_data;
@@ -248,32 +248,20 @@ void hda_cldma_setup(struct hda_cldma *cl)
snd_hdac_stream_writel(cl, CL_SPBFCTL, 1);
}
-static irqreturn_t cldma_irq_handler(int irq, void *dev_id)
+void hda_cldma_interrupt(struct hda_cldma *cl)
{
- struct hda_cldma *cl = dev_id;
- u32 adspis;
-
- adspis = snd_hdac_adsp_readl(cl, AVS_ADSP_REG_ADSPIS);
- if (adspis == UINT_MAX)
- return IRQ_NONE;
- if (!(adspis & AVS_ADSP_ADSPIS_CLDMA))
- return IRQ_NONE;
-
- cl->sd_status = snd_hdac_stream_readb(cl, SD_STS);
- dev_warn(cl->dev, "%s sd_status: 0x%08x\n", __func__, cl->sd_status);
-
/* disable CLDMA interrupt */
snd_hdac_adsp_updatel(cl, AVS_ADSP_REG_ADSPIC, AVS_ADSP_ADSPIC_CLDMA, 0);
- complete(&cl->completion);
+ cl->sd_status = snd_hdac_stream_readb(cl, SD_STS);
+ dev_dbg(cl->dev, "%s sd_status: 0x%08x\n", __func__, cl->sd_status);
- return IRQ_HANDLED;
+ complete(&cl->completion);
}
int hda_cldma_init(struct hda_cldma *cl, struct hdac_bus *bus, void __iomem *dsp_ba,
unsigned int buffer_size)
{
- struct pci_dev *pci = to_pci_dev(bus->dev);
int ret;
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, bus->dev, buffer_size, &cl->dmab_data);
@@ -281,8 +269,10 @@ int hda_cldma_init(struct hda_cldma *cl, struct hdac_bus *bus, void __iomem *dsp
return ret;
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, bus->dev, BDL_SIZE, &cl->dmab_bdl);
- if (ret < 0)
- goto alloc_err;
+ if (ret < 0) {
+ snd_dma_free_pages(&cl->dmab_data);
+ return ret;
+ }
cl->dev = bus->dev;
cl->bus = bus;
@@ -290,27 +280,11 @@ int hda_cldma_init(struct hda_cldma *cl, struct hdac_bus *bus, void __iomem *dsp
cl->buffer_size = buffer_size;
cl->sd_addr = dsp_ba + AZX_CL_SD_BASE;
- ret = pci_request_irq(pci, 0, cldma_irq_handler, NULL, cl, "CLDMA");
- if (ret < 0) {
- dev_err(cl->dev, "Failed to request CLDMA IRQ handler: %d\n", ret);
- goto req_err;
- }
-
return 0;
-
-req_err:
- snd_dma_free_pages(&cl->dmab_bdl);
-alloc_err:
- snd_dma_free_pages(&cl->dmab_data);
-
- return ret;
}
void hda_cldma_free(struct hda_cldma *cl)
{
- struct pci_dev *pci = to_pci_dev(cl->dev);
-
- pci_free_irq(pci, 0, cl);
snd_dma_free_pages(&cl->dmab_data);
snd_dma_free_pages(&cl->dmab_bdl);
}
diff --git a/sound/soc/intel/avs/cldma.h b/sound/soc/intel/avs/cldma.h
index 223d3431ab81..7f9b2b1c566e 100644
--- a/sound/soc/intel/avs/cldma.h
+++ b/sound/soc/intel/avs/cldma.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+ * Copyright(c) 2021-2022 Intel Corporation
*
* Author: Cezary Rojewski <cezary.rojewski@intel.com>
*/
@@ -24,6 +24,7 @@ int hda_cldma_reset(struct hda_cldma *cl);
void hda_cldma_set_data(struct hda_cldma *cl, void *data, unsigned int size);
void hda_cldma_setup(struct hda_cldma *cl);
+void hda_cldma_interrupt(struct hda_cldma *cl);
int hda_cldma_init(struct hda_cldma *cl, struct hdac_bus *bus, void __iomem *dsp_ba,
unsigned int buffer_size);
void hda_cldma_free(struct hda_cldma *cl);
diff --git a/sound/soc/intel/avs/cnl.c b/sound/soc/intel/avs/cnl.c
index 5423c29ecc4e..03f8fb0dc187 100644
--- a/sound/soc/intel/avs/cnl.c
+++ b/sound/soc/intel/avs/cnl.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2024 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2024 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -9,45 +9,75 @@
#include <sound/hdaudio_ext.h>
#include "avs.h"
#include "messages.h"
+#include "registers.h"
-irqreturn_t avs_cnl_irq_thread(struct avs_dev *adev)
+static void avs_cnl_ipc_interrupt(struct avs_dev *adev)
{
- union avs_reply_msg msg;
- u32 hipctdr, hipctdd, hipctda;
-
- hipctdr = snd_hdac_adsp_readl(adev, CNL_ADSP_REG_HIPCTDR);
- hipctdd = snd_hdac_adsp_readl(adev, CNL_ADSP_REG_HIPCTDD);
-
- /* Ensure DSP sent new response to process. */
- if (!(hipctdr & CNL_ADSP_HIPCTDR_BUSY))
- return IRQ_NONE;
-
- msg.primary = hipctdr;
- msg.ext.val = hipctdd;
- avs_dsp_process_response(adev, msg.val);
-
- /* Tell DSP we accepted its message. */
- snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCTDR,
- CNL_ADSP_HIPCTDR_BUSY, CNL_ADSP_HIPCTDR_BUSY);
- /* Ack this response. */
- snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCTDA,
- CNL_ADSP_HIPCTDA_DONE, CNL_ADSP_HIPCTDA_DONE);
- /* HW might have been clock gated, give some time for change to propagate. */
- snd_hdac_adsp_readl_poll(adev, CNL_ADSP_REG_HIPCTDA, hipctda,
- !(hipctda & CNL_ADSP_HIPCTDA_DONE), 10, 1000);
- /* Unmask busy interrupt. */
- snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCCTL,
- AVS_ADSP_HIPCCTL_BUSY, AVS_ADSP_HIPCCTL_BUSY);
-
- return IRQ_HANDLED;
+ const struct avs_spec *spec = adev->spec;
+ u32 hipc_ack, hipc_rsp;
+
+ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,
+ AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY, 0);
+
+ hipc_ack = snd_hdac_adsp_readl(adev, spec->hipc->ack_offset);
+ hipc_rsp = snd_hdac_adsp_readl(adev, spec->hipc->rsp_offset);
+
+ /* DSP acked host's request. */
+ if (hipc_ack & spec->hipc->ack_done_mask) {
+ complete(&adev->ipc->done_completion);
+
+ /* Tell DSP it has our attention. */
+ snd_hdac_adsp_updatel(adev, spec->hipc->ack_offset, spec->hipc->ack_done_mask,
+ spec->hipc->ack_done_mask);
+ }
+
+ /* DSP sent new response to process. */
+ if (hipc_rsp & spec->hipc->rsp_busy_mask) {
+ union avs_reply_msg msg;
+ u32 hipctda;
+
+ msg.primary = snd_hdac_adsp_readl(adev, CNL_ADSP_REG_HIPCTDR);
+ msg.ext.val = snd_hdac_adsp_readl(adev, CNL_ADSP_REG_HIPCTDD);
+
+ avs_dsp_process_response(adev, msg.val);
+
+ /* Tell DSP we accepted its message. */
+ snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCTDR,
+ CNL_ADSP_HIPCTDR_BUSY, CNL_ADSP_HIPCTDR_BUSY);
+ /* Ack this response. */
+ snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCTDA,
+ CNL_ADSP_HIPCTDA_DONE, CNL_ADSP_HIPCTDA_DONE);
+ /* HW might have been clock gated, give some time for change to propagate. */
+ snd_hdac_adsp_readl_poll(adev, CNL_ADSP_REG_HIPCTDA, hipctda,
+ !(hipctda & CNL_ADSP_HIPCTDA_DONE), 10, 1000);
+ }
+
+ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,
+ AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY,
+ AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY);
+}
+
+irqreturn_t avs_cnl_dsp_interrupt(struct avs_dev *adev)
+{
+ u32 adspis = snd_hdac_adsp_readl(adev, AVS_ADSP_REG_ADSPIS);
+ irqreturn_t ret = IRQ_NONE;
+
+ if (adspis == UINT_MAX)
+ return ret;
+
+ if (adspis & AVS_ADSP_ADSPIS_IPC) {
+ avs_cnl_ipc_interrupt(adev);
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
}
const struct avs_dsp_ops avs_cnl_dsp_ops = {
.power = avs_dsp_core_power,
.reset = avs_dsp_core_reset,
.stall = avs_dsp_core_stall,
- .irq_handler = avs_irq_handler,
- .irq_thread = avs_cnl_irq_thread,
+ .dsp_interrupt = avs_cnl_dsp_interrupt,
.int_control = avs_dsp_interrupt_control,
.load_basefw = avs_hda_load_basefw,
.load_lib = avs_hda_load_library,
diff --git a/sound/soc/intel/avs/control.c b/sound/soc/intel/avs/control.c
index 3dfa2e9816db..2e01dc75a15a 100644
--- a/sound/soc/intel/avs/control.c
+++ b/sound/soc/intel/avs/control.c
@@ -1,11 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
// Cezary Rojewski <cezary.rojewski@intel.com>
//
+#include <linux/cleanup.h>
#include <sound/soc.h>
#include "avs.h"
#include "control.h"
@@ -31,8 +32,11 @@ static struct avs_path_module *avs_get_volume_module(struct avs_dev *adev, u32 i
list_for_each_entry(path, &adev->path_list, node) {
list_for_each_entry(ppl, &path->ppl_list, node) {
list_for_each_entry(mod, &ppl->mod_list, node) {
- if (guid_equal(&mod->template->cfg_ext->type, &AVS_PEAKVOL_MOD_UUID)
- && mod->template->ctl_id == id) {
+ guid_t *type = &mod->template->cfg_ext->type;
+
+ if ((guid_equal(type, &AVS_PEAKVOL_MOD_UUID) ||
+ guid_equal(type, &AVS_GAIN_MOD_UUID)) &&
+ mod->template->ctl_id == id) {
spin_unlock(&adev->path_list_lock);
return mod;
}
@@ -44,70 +48,168 @@ static struct avs_path_module *avs_get_volume_module(struct avs_dev *adev, u32 i
return NULL;
}
-int avs_control_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int avs_control_volume_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl)
{
- struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
- struct avs_control_data *ctl_data = (struct avs_control_data *)mc->dobj.private;
- struct avs_dev *adev = avs_get_kcontrol_adev(kcontrol);
- struct avs_volume_cfg *dspvols = NULL;
+ struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value;
+ struct avs_control_data *ctl_data = mc->dobj.private;
struct avs_path_module *active_module;
+ struct avs_volume_cfg *dspvols;
+ struct avs_dev *adev;
size_t num_dspvols;
- int ret = 0;
+ int ret, i;
+
+ adev = avs_get_kcontrol_adev(kctl);
- /* prevent access to modules while path is being constructed */
- mutex_lock(&adev->path_mutex);
+ /* Prevent access to modules while path is being constructed. */
+ guard(mutex)(&adev->path_mutex);
active_module = avs_get_volume_module(adev, ctl_data->id);
if (active_module) {
ret = avs_ipc_peakvol_get_volume(adev, active_module->module_id,
active_module->instance_id, &dspvols,
&num_dspvols);
- if (!ret)
- ucontrol->value.integer.value[0] = dspvols[0].target_volume;
+ if (ret)
+ return AVS_IPC_RET(ret);
- ret = AVS_IPC_RET(ret);
+ /* Do not copy more than the control can store. */
+ num_dspvols = min_t(u32, num_dspvols, SND_SOC_TPLG_MAX_CHAN);
+ for (i = 0; i < num_dspvols; i++)
+ ctl_data->values[i] = dspvols[i].target_volume;
kfree(dspvols);
- } else {
- ucontrol->value.integer.value[0] = ctl_data->volume;
}
- mutex_unlock(&adev->path_mutex);
- return ret;
+ memcpy(uctl->value.integer.value, ctl_data->values, sizeof(ctl_data->values));
+ return 0;
}
-int avs_control_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int avs_control_volume_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl)
{
- struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
- struct avs_control_data *ctl_data = (struct avs_control_data *)mc->dobj.private;
- struct avs_dev *adev = avs_get_kcontrol_adev(kcontrol);
- long *volume = &ctl_data->volume;
struct avs_path_module *active_module;
- struct avs_volume_cfg dspvol = {0};
- long ctlvol = ucontrol->value.integer.value[0];
- int ret = 0, changed = 0;
+ struct avs_control_data *ctl_data;
+ struct soc_mixer_control *mc;
+ struct avs_dev *adev;
+ long *input;
+ int ret, i;
+
+ mc = (struct soc_mixer_control *)kctl->private_value;
+ ctl_data = mc->dobj.private;
+ adev = avs_get_kcontrol_adev(kctl);
+ input = uctl->value.integer.value;
+ i = 0;
+
+ /* mc->num_channels can be 0. */
+ do {
+ if (input[i] < mc->min || input[i] > mc->max)
+ return -EINVAL;
+ } while (++i < mc->num_channels);
+
+ if (!memcmp(ctl_data->values, input, sizeof(ctl_data->values)))
+ return 0;
+
+ /* Prevent access to modules while path is being constructed. */
+ guard(mutex)(&adev->path_mutex);
- if (ctlvol < 0 || ctlvol > mc->max)
- return -EINVAL;
+ active_module = avs_get_volume_module(adev, ctl_data->id);
+ if (active_module) {
+ ret = avs_peakvol_set_volume(adev, active_module, mc, input);
+ if (ret)
+ return ret;
+ }
- /* prevent access to modules while path is being constructed */
- mutex_lock(&adev->path_mutex);
+ memcpy(ctl_data->values, input, sizeof(ctl_data->values));
+ return 1;
+}
- if (*volume != ctlvol) {
- *volume = ctlvol;
- changed = 1;
- }
+int avs_control_volume_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
+{
+ struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value;
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = max_t(u32, 1, mc->num_channels);
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = mc->max;
+ return 0;
+}
+
+int avs_control_mute_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl)
+{
+ struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value;
+ struct avs_control_data *ctl_data = mc->dobj.private;
+ struct avs_path_module *active_module;
+ struct avs_mute_cfg *dspmutes;
+ struct avs_dev *adev;
+ size_t num_dspmutes;
+ int ret, i;
+
+ adev = avs_get_kcontrol_adev(kctl);
+
+ /* Prevent access to modules while path is being constructed. */
+ guard(mutex)(&adev->path_mutex);
active_module = avs_get_volume_module(adev, ctl_data->id);
if (active_module) {
- dspvol.channel_id = AVS_ALL_CHANNELS_MASK;
- dspvol.target_volume = *volume;
+ ret = avs_ipc_peakvol_get_mute(adev, active_module->module_id,
+ active_module->instance_id, &dspmutes,
+ &num_dspmutes);
+ if (ret)
+ return AVS_IPC_RET(ret);
+
+ /* Do not copy more than the control can store. */
+ num_dspmutes = min_t(u32, num_dspmutes, SND_SOC_TPLG_MAX_CHAN);
+ for (i = 0; i < num_dspmutes; i++)
+ ctl_data->values[i] = !dspmutes[i].mute;
+ kfree(dspmutes);
+ }
- ret = avs_ipc_peakvol_set_volume(adev, active_module->module_id,
- active_module->instance_id, &dspvol);
- ret = AVS_IPC_RET(ret);
+ memcpy(uctl->value.integer.value, ctl_data->values, sizeof(ctl_data->values));
+ return 0;
+}
+
+int avs_control_mute_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl)
+{
+ struct avs_path_module *active_module;
+ struct avs_control_data *ctl_data;
+ struct soc_mixer_control *mc;
+ struct avs_dev *adev;
+ long *input;
+ int ret, i;
+
+ mc = (struct soc_mixer_control *)kctl->private_value;
+ ctl_data = mc->dobj.private;
+ adev = avs_get_kcontrol_adev(kctl);
+ input = uctl->value.integer.value;
+ i = 0;
+
+ /* mc->num_channels can be 0. */
+ do {
+ if (input[i] < mc->min || input[i] > mc->max)
+ return -EINVAL;
+ } while (++i < mc->num_channels);
+
+ if (!memcmp(ctl_data->values, input, sizeof(ctl_data->values)))
+ return 0;
+
+ /* Prevent access to modules while path is being constructed. */
+ guard(mutex)(&adev->path_mutex);
+
+ active_module = avs_get_volume_module(adev, ctl_data->id);
+ if (active_module) {
+ ret = avs_peakvol_set_mute(adev, active_module, mc, input);
+ if (ret)
+ return ret;
}
- mutex_unlock(&adev->path_mutex);
+ memcpy(ctl_data->values, input, sizeof(ctl_data->values));
+ return 1;
+}
+
+int avs_control_mute_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
+{
+ struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value;
- return ret ? ret : changed;
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = max_t(u32, 1, mc->num_channels);
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = mc->max;
+ return 0;
}
diff --git a/sound/soc/intel/avs/control.h b/sound/soc/intel/avs/control.h
index 08631bde13c3..08b2919e4629 100644
--- a/sound/soc/intel/avs/control.h
+++ b/sound/soc/intel/avs/control.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+ * Copyright(c) 2021-2022 Intel Corporation
*
* Authors: Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
* Cezary Rojewski <cezary.rojewski@intel.com>
@@ -10,14 +10,18 @@
#define __SOUND_SOC_INTEL_AVS_CTRL_H
#include <sound/control.h>
+#include <uapi/sound/asoc.h>
struct avs_control_data {
u32 id;
-
- long volume;
+ long values[SND_SOC_TPLG_MAX_CHAN];
};
-int avs_control_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int avs_control_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int avs_control_volume_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl);
+int avs_control_volume_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl);
+int avs_control_volume_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo);
+int avs_control_mute_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl);
+int avs_control_mute_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl);
+int avs_control_mute_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo);
#endif
diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
index d7f8940099ce..485842838025 100644
--- a/sound/soc/intel/avs/core.c
+++ b/sound/soc/intel/avs/core.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -14,19 +14,21 @@
// foundation of this driver
//
+#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <acpi/nhlt.h>
#include <sound/hda_codec.h>
#include <sound/hda_i915.h>
#include <sound/hda_register.h>
#include <sound/hdaudio.h>
#include <sound/hdaudio_ext.h>
#include <sound/intel-dsp-config.h>
-#include <sound/intel-nhlt.h>
#include "../../codecs/hda.h"
#include "avs.h"
#include "cldma.h"
#include "messages.h"
+#include "pcm.h"
static u32 pgctl_mask = AZX_PGCTL_LSRMD_MASK;
module_param(pgctl_mask, uint, 0444);
@@ -52,14 +54,17 @@ void avs_hda_power_gating_enable(struct avs_dev *adev, bool enable)
{
u32 value = enable ? 0 : pgctl_mask;
- avs_hda_update_config_dword(&adev->base.core, AZX_PCIREG_PGCTL, pgctl_mask, value);
+ if (!avs_platattr_test(adev, ACE))
+ avs_hda_update_config_dword(&adev->base.core, AZX_PCIREG_PGCTL, pgctl_mask, value);
}
static void avs_hdac_clock_gating_enable(struct hdac_bus *bus, bool enable)
{
+ struct avs_dev *adev = hdac_to_avs(bus);
u32 value = enable ? cgctl_mask : 0;
- avs_hda_update_config_dword(bus, AZX_PCIREG_CGCTL, cgctl_mask, value);
+ if (!avs_platattr_test(adev, ACE))
+ avs_hda_update_config_dword(bus, AZX_PCIREG_CGCTL, cgctl_mask, value);
}
void avs_hda_clock_gating_enable(struct avs_dev *adev, bool enable)
@@ -69,6 +74,8 @@ void avs_hda_clock_gating_enable(struct avs_dev *adev, bool enable)
void avs_hda_l1sen_enable(struct avs_dev *adev, bool enable)
{
+ if (avs_platattr_test(adev, ACE))
+ return;
if (enable) {
if (atomic_inc_and_test(&adev->l1sen_counter))
snd_hdac_chip_updatel(&adev->base.core, VS_EM2, AZX_VS_EM2_L1SEN,
@@ -97,6 +104,7 @@ static int avs_hdac_bus_init_streams(struct hdac_bus *bus)
static bool avs_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
{
+ struct avs_dev *adev = hdac_to_avs(bus);
struct hdac_ext_link *hlink;
bool ret;
@@ -112,7 +120,8 @@ static bool avs_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
/* Set DUM bit to address incorrect position reporting for capture
* streams. In order to do so, CTRL needs to be out of reset state
*/
- snd_hdac_chip_updatel(bus, VS_EM2, AZX_VS_EM2_DUM, AZX_VS_EM2_DUM);
+ if (!avs_platattr_test(adev, ACE))
+ snd_hdac_chip_updatel(bus, VS_EM2, AZX_VS_EM2_DUM, AZX_VS_EM2_DUM);
return ret;
}
@@ -209,15 +218,13 @@ static void avs_hda_probe_work(struct work_struct *work)
snd_hdac_ext_bus_ppcap_enable(bus, true);
snd_hdac_ext_bus_ppcap_int_enable(bus, true);
+ avs_debugfs_init(adev);
ret = avs_dsp_first_boot_firmware(adev);
if (ret < 0)
return;
- adev->nhlt = intel_nhlt_init(adev->dev);
- if (!adev->nhlt)
- dev_info(bus->dev, "platform has no NHLT\n");
- avs_debugfs_init(adev);
+ acpi_nhlt_get_gbl_table();
avs_register_all_boards(adev);
@@ -248,7 +255,7 @@ static void hdac_stream_update_pos(struct hdac_stream *stream, u64 buffer_size)
static void hdac_update_stream(struct hdac_bus *bus, struct hdac_stream *stream)
{
if (stream->substream) {
- snd_pcm_period_elapsed(stream->substream);
+ avs_period_elapsed(stream->substream);
} else if (stream->cstream) {
u64 buffer_size = stream->cstream->runtime->buffer_size;
@@ -257,67 +264,55 @@ static void hdac_update_stream(struct hdac_bus *bus, struct hdac_stream *stream)
}
}
-static irqreturn_t hdac_bus_irq_handler(int irq, void *context)
+static irqreturn_t avs_hda_interrupt(struct hdac_bus *bus)
{
- struct hdac_bus *bus = context;
- u32 mask, int_enable;
+ irqreturn_t ret = IRQ_NONE;
u32 status;
- int ret = IRQ_NONE;
-
- if (!pm_runtime_active(bus->dev))
- return ret;
-
- spin_lock(&bus->reg_lock);
status = snd_hdac_chip_readl(bus, INTSTS);
- if (status == 0 || status == UINT_MAX) {
- spin_unlock(&bus->reg_lock);
- return ret;
- }
+ if (snd_hdac_bus_handle_stream_irq(bus, status, hdac_update_stream))
+ ret = IRQ_HANDLED;
- /* clear rirb int */
+ spin_lock_irq(&bus->reg_lock);
+ /* Clear RIRB interrupt. */
status = snd_hdac_chip_readb(bus, RIRBSTS);
if (status & RIRB_INT_MASK) {
if (status & RIRB_INT_RESPONSE)
snd_hdac_bus_update_rirb(bus);
snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
- }
-
- mask = (0x1 << bus->num_streams) - 1;
-
- status = snd_hdac_chip_readl(bus, INTSTS);
- status &= mask;
- if (status) {
- /* Disable stream interrupts; Re-enable in bottom half */
- int_enable = snd_hdac_chip_readl(bus, INTCTL);
- snd_hdac_chip_writel(bus, INTCTL, (int_enable & (~mask)));
- ret = IRQ_WAKE_THREAD;
- } else {
ret = IRQ_HANDLED;
}
- spin_unlock(&bus->reg_lock);
+ spin_unlock_irq(&bus->reg_lock);
return ret;
}
-static irqreturn_t hdac_bus_irq_thread(int irq, void *context)
+static irqreturn_t avs_hda_irq_handler(int irq, void *dev_id)
+{
+ struct hdac_bus *bus = dev_id;
+ u32 intsts;
+
+ intsts = snd_hdac_chip_readl(bus, INTSTS);
+ if (intsts == UINT_MAX || !(intsts & AZX_INT_GLOBAL_EN))
+ return IRQ_NONE;
+
+ /* Mask GIE, unmasked in irq_thread(). */
+ snd_hdac_chip_updatel(bus, INTCTL, AZX_INT_GLOBAL_EN, 0);
+
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t avs_hda_irq_thread(int irq, void *dev_id)
{
- struct hdac_bus *bus = context;
+ struct hdac_bus *bus = dev_id;
u32 status;
- u32 int_enable;
- u32 mask;
- unsigned long flags;
status = snd_hdac_chip_readl(bus, INTSTS);
+ if (status & ~AZX_INT_GLOBAL_EN)
+ avs_hda_interrupt(bus);
- snd_hdac_bus_handle_stream_irq(bus, status, hdac_update_stream);
-
- /* Re-enable stream interrupts */
- mask = (0x1 << bus->num_streams) - 1;
- spin_lock_irqsave(&bus->reg_lock, flags);
- int_enable = snd_hdac_chip_readl(bus, INTCTL);
- snd_hdac_chip_writel(bus, INTCTL, (int_enable | mask));
- spin_unlock_irqrestore(&bus->reg_lock, flags);
+ /* Unmask GIE, masked in irq_handler(). */
+ snd_hdac_chip_updatel(bus, INTCTL, AZX_INT_GLOBAL_EN, AZX_INT_GLOBAL_EN);
return IRQ_HANDLED;
}
@@ -326,14 +321,23 @@ static irqreturn_t avs_dsp_irq_handler(int irq, void *dev_id)
{
struct avs_dev *adev = dev_id;
- return avs_dsp_op(adev, irq_handler);
+ return avs_hda_irq_handler(irq, &adev->base.core);
}
static irqreturn_t avs_dsp_irq_thread(int irq, void *dev_id)
{
struct avs_dev *adev = dev_id;
+ struct hdac_bus *bus = &adev->base.core;
+ u32 status;
- return avs_dsp_op(adev, irq_thread);
+ status = readl(bus->ppcap + AZX_REG_PP_PPSTS);
+ if (status & AZX_PPCTL_PIE)
+ avs_dsp_op(adev, dsp_interrupt);
+
+ /* Unmask GIE, masked in irq_handler(). */
+ snd_hdac_chip_updatel(bus, INTCTL, AZX_INT_GLOBAL_EN, AZX_INT_GLOBAL_EN);
+
+ return IRQ_HANDLED;
}
static int avs_hdac_acquire_irq(struct avs_dev *adev)
@@ -343,13 +347,13 @@ static int avs_hdac_acquire_irq(struct avs_dev *adev)
int ret;
/* request one and check that we only got one interrupt */
- ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI | PCI_IRQ_LEGACY);
+ ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI | PCI_IRQ_INTX);
if (ret != 1) {
dev_err(adev->dev, "Failed to allocate IRQ vector: %d\n", ret);
return ret;
}
- ret = pci_request_irq(pci, 0, hdac_bus_irq_handler, hdac_bus_irq_thread, bus,
+ ret = pci_request_irq(pci, 0, avs_hda_irq_handler, avs_hda_irq_thread, bus,
KBUILD_MODNAME);
if (ret < 0) {
dev_err(adev->dev, "Failed to request stream IRQ handler: %d\n", ret);
@@ -426,8 +430,14 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
int ret;
ret = snd_intel_dsp_driver_probe(pci);
- if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_AVS)
+ switch (ret) {
+ case SND_INTEL_DSP_DRIVER_ANY:
+ case SND_INTEL_DSP_DRIVER_SST:
+ case SND_INTEL_DSP_DRIVER_AVS:
+ break;
+ default:
return -ENODEV;
+ }
ret = pcim_enable_device(pci);
if (ret < 0)
@@ -442,7 +452,7 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
return ret;
}
- ret = pci_request_regions(pci, "AVS HDAudio");
+ ret = pcim_request_all_regions(pci, "AVS HDAudio");
if (ret < 0)
return ret;
@@ -451,8 +461,7 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
bus->remap_addr = pci_ioremap_bar(pci, 0);
if (!bus->remap_addr) {
dev_err(bus->dev, "ioremap error\n");
- ret = -ENXIO;
- goto err_remap_bar0;
+ return -ENXIO;
}
adev->dsp_ba = pci_ioremap_bar(pci, 4);
@@ -509,8 +518,6 @@ err_init_streams:
iounmap(adev->dsp_ba);
err_remap_bar4:
iounmap(bus->remap_addr);
-err_remap_bar0:
- pci_release_regions(pci);
return ret;
}
@@ -530,8 +537,6 @@ static void avs_pci_shutdown(struct pci_dev *pci)
snd_hdac_bus_stop_chip(bus);
snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
- if (avs_platattr_test(adev, CLDMA))
- pci_free_irq(pci, 0, &code_loader);
pci_free_irq(pci, 0, adev);
pci_free_irq(pci, 0, bus);
pci_free_irq_vectors(pci);
@@ -548,9 +553,8 @@ static void avs_pci_remove(struct pci_dev *pci)
avs_unregister_all_boards(adev);
+ acpi_nhlt_put_gbl_table();
avs_debugfs_exit(adev);
- if (adev->nhlt)
- intel_nhlt_free(adev->nhlt);
if (avs_platattr_test(adev, CLDMA))
hda_cldma_free(&code_loader);
@@ -584,7 +588,6 @@ static void avs_pci_remove(struct pci_dev *pci)
pci_free_irq_vectors(pci);
iounmap(bus->remap_addr);
iounmap(adev->dsp_ba);
- pci_release_regions(pci);
/* Firmware is not needed anymore */
avs_release_firmwares(adev);
@@ -612,7 +615,7 @@ static int avs_suspend_standby(struct avs_dev *adev)
return 0;
}
-static int __maybe_unused avs_suspend_common(struct avs_dev *adev, bool low_power)
+static int avs_suspend_common(struct avs_dev *adev, bool low_power)
{
struct hdac_bus *bus = &adev->base.core;
int ret;
@@ -673,7 +676,7 @@ static int avs_resume_standby(struct avs_dev *adev)
return 0;
}
-static int __maybe_unused avs_resume_common(struct avs_dev *adev, bool low_power, bool purge)
+static int avs_resume_common(struct avs_dev *adev, bool low_power, bool purge)
{
struct hdac_bus *bus = &adev->base.core;
int ret;
@@ -696,41 +699,41 @@ static int __maybe_unused avs_resume_common(struct avs_dev *adev, bool low_power
return 0;
}
-static int __maybe_unused avs_suspend(struct device *dev)
+static int avs_suspend(struct device *dev)
{
return avs_suspend_common(to_avs_dev(dev), true);
}
-static int __maybe_unused avs_resume(struct device *dev)
+static int avs_resume(struct device *dev)
{
return avs_resume_common(to_avs_dev(dev), true, true);
}
-static int __maybe_unused avs_runtime_suspend(struct device *dev)
+static int avs_runtime_suspend(struct device *dev)
{
return avs_suspend_common(to_avs_dev(dev), true);
}
-static int __maybe_unused avs_runtime_resume(struct device *dev)
+static int avs_runtime_resume(struct device *dev)
{
return avs_resume_common(to_avs_dev(dev), true, false);
}
-static int __maybe_unused avs_freeze(struct device *dev)
+static int avs_freeze(struct device *dev)
{
return avs_suspend_common(to_avs_dev(dev), false);
}
-static int __maybe_unused avs_thaw(struct device *dev)
+static int avs_thaw(struct device *dev)
{
return avs_resume_common(to_avs_dev(dev), false, true);
}
-static int __maybe_unused avs_poweroff(struct device *dev)
+static int avs_poweroff(struct device *dev)
{
return avs_suspend_common(to_avs_dev(dev), false);
}
-static int __maybe_unused avs_restore(struct device *dev)
+static int avs_restore(struct device *dev)
{
return avs_resume_common(to_avs_dev(dev), false, true);
}
@@ -742,19 +745,22 @@ static const struct dev_pm_ops avs_dev_pm = {
.thaw = avs_thaw,
.poweroff = avs_poweroff,
.restore = avs_restore,
- SET_RUNTIME_PM_OPS(avs_runtime_suspend, avs_runtime_resume, NULL)
+ RUNTIME_PM_OPS(avs_runtime_suspend, avs_runtime_resume, NULL)
};
static const struct avs_sram_spec skl_sram_spec = {
.base_offset = SKL_ADSP_SRAM_BASE_OFFSET,
.window_size = SKL_ADSP_SRAM_WINDOW_SIZE,
- .rom_status_offset = SKL_ADSP_SRAM_BASE_OFFSET,
};
static const struct avs_sram_spec apl_sram_spec = {
.base_offset = APL_ADSP_SRAM_BASE_OFFSET,
.window_size = APL_ADSP_SRAM_WINDOW_SIZE,
- .rom_status_offset = APL_ADSP_SRAM_BASE_OFFSET,
+};
+
+static const struct avs_sram_spec mtl_sram_spec = {
+ .base_offset = MTL_ADSP_SRAM_BASE_OFFSET,
+ .window_size = MTL_ADSP_SRAM_WINDOW_SIZE,
};
static const struct avs_hipc_spec skl_hipc_spec = {
@@ -766,6 +772,19 @@ static const struct avs_hipc_spec skl_hipc_spec = {
.rsp_offset = SKL_ADSP_REG_HIPCT,
.rsp_busy_mask = SKL_ADSP_HIPCT_BUSY,
.ctl_offset = SKL_ADSP_REG_HIPCCTL,
+ .sts_offset = SKL_ADSP_SRAM_BASE_OFFSET,
+};
+
+static const struct avs_hipc_spec apl_hipc_spec = {
+ .req_offset = SKL_ADSP_REG_HIPCI,
+ .req_ext_offset = SKL_ADSP_REG_HIPCIE,
+ .req_busy_mask = SKL_ADSP_HIPCI_BUSY,
+ .ack_offset = SKL_ADSP_REG_HIPCIE,
+ .ack_done_mask = SKL_ADSP_HIPCIE_DONE,
+ .rsp_offset = SKL_ADSP_REG_HIPCT,
+ .rsp_busy_mask = SKL_ADSP_HIPCT_BUSY,
+ .ctl_offset = SKL_ADSP_REG_HIPCCTL,
+ .sts_offset = APL_ADSP_SRAM_BASE_OFFSET,
};
static const struct avs_hipc_spec cnl_hipc_spec = {
@@ -777,6 +796,19 @@ static const struct avs_hipc_spec cnl_hipc_spec = {
.rsp_offset = CNL_ADSP_REG_HIPCTDR,
.rsp_busy_mask = CNL_ADSP_HIPCTDR_BUSY,
.ctl_offset = CNL_ADSP_REG_HIPCCTL,
+ .sts_offset = APL_ADSP_SRAM_BASE_OFFSET,
+};
+
+static const struct avs_hipc_spec lnl_hipc_spec = {
+ .req_offset = MTL_REG_HfIPCxIDR,
+ .req_ext_offset = MTL_REG_HfIPCxIDD,
+ .req_busy_mask = MTL_HfIPCxIDR_BUSY,
+ .ack_offset = MTL_REG_HfIPCxIDA,
+ .ack_done_mask = MTL_HfIPCxIDA_DONE,
+ .rsp_offset = MTL_REG_HfIPCxTDR,
+ .rsp_busy_mask = MTL_HfIPCxTDR_BUSY,
+ .ctl_offset = MTL_REG_HfIPCxCTL,
+ .sts_offset = LNL_REG_HfDFR(0),
};
static const struct avs_spec skl_desc = {
@@ -796,7 +828,7 @@ static const struct avs_spec apl_desc = {
.core_init_mask = 3,
.attributes = AVS_PLATATTR_IMR,
.sram = &apl_sram_spec,
- .hipc = &skl_hipc_spec,
+ .hipc = &apl_hipc_spec,
};
static const struct avs_spec cnl_desc = {
@@ -829,10 +861,10 @@ static const struct avs_spec jsl_desc = {
.hipc = &cnl_hipc_spec,
};
-#define AVS_TGL_BASED_SPEC(sname) \
+#define AVS_TGL_BASED_SPEC(sname, min) \
static const struct avs_spec sname##_desc = { \
.name = #sname, \
- .min_fw_version = { 10, 29, 0, 5646 }, \
+ .min_fw_version = { 10, min, 0, 5646 }, \
.dsp_ops = &avs_tgl_dsp_ops, \
.core_init_mask = 1, \
.attributes = AVS_PLATATTR_IMR, \
@@ -840,11 +872,21 @@ static const struct avs_spec sname##_desc = { \
.hipc = &cnl_hipc_spec, \
}
-AVS_TGL_BASED_SPEC(lkf);
-AVS_TGL_BASED_SPEC(tgl);
-AVS_TGL_BASED_SPEC(ehl);
-AVS_TGL_BASED_SPEC(adl);
-AVS_TGL_BASED_SPEC(adl_n);
+AVS_TGL_BASED_SPEC(lkf, 28);
+AVS_TGL_BASED_SPEC(tgl, 29);
+AVS_TGL_BASED_SPEC(ehl, 30);
+AVS_TGL_BASED_SPEC(adl, 35);
+AVS_TGL_BASED_SPEC(adl_n, 35);
+
+static const struct avs_spec fcl_desc = {
+ .name = "fcl",
+ .min_fw_version = { 0 },
+ .dsp_ops = &avs_ptl_dsp_ops,
+ .core_init_mask = 1,
+ .attributes = AVS_PLATATTR_IMR | AVS_PLATATTR_ACE | AVS_PLATATTR_ALTHDA,
+ .sram = &mtl_sram_spec,
+ .hipc = &lnl_hipc_spec,
+};
static const struct pci_device_id avs_ids[] = {
{ PCI_DEVICE_DATA(INTEL, HDA_SKL_LP, &skl_desc) },
@@ -881,6 +923,7 @@ static const struct pci_device_id avs_ids[] = {
{ PCI_DEVICE_DATA(INTEL, HDA_RPL_P_1, &adl_desc) },
{ PCI_DEVICE_DATA(INTEL, HDA_RPL_M, &adl_desc) },
{ PCI_DEVICE_DATA(INTEL, HDA_RPL_PX, &adl_desc) },
+ { PCI_DEVICE_DATA(INTEL, HDA_FCL, &fcl_desc) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, avs_ids);
@@ -893,7 +936,7 @@ static struct pci_driver avs_pci_driver = {
.shutdown = avs_pci_shutdown,
.dev_groups = avs_attr_groups,
.driver = {
- .pm = &avs_dev_pm,
+ .pm = pm_ptr(&avs_dev_pm),
},
};
module_pci_driver(avs_pci_driver);
@@ -902,3 +945,14 @@ MODULE_AUTHOR("Cezary Rojewski <cezary.rojewski@intel.com>");
MODULE_AUTHOR("Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>");
MODULE_DESCRIPTION("Intel cAVS sound driver");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("intel/skl/dsp_basefw.bin");
+MODULE_FIRMWARE("intel/apl/dsp_basefw.bin");
+MODULE_FIRMWARE("intel/cnl/dsp_basefw.bin");
+MODULE_FIRMWARE("intel/icl/dsp_basefw.bin");
+MODULE_FIRMWARE("intel/jsl/dsp_basefw.bin");
+MODULE_FIRMWARE("intel/lkf/dsp_basefw.bin");
+MODULE_FIRMWARE("intel/tgl/dsp_basefw.bin");
+MODULE_FIRMWARE("intel/ehl/dsp_basefw.bin");
+MODULE_FIRMWARE("intel/adl/dsp_basefw.bin");
+MODULE_FIRMWARE("intel/adl_n/dsp_basefw.bin");
+MODULE_FIRMWARE("intel/fcl/dsp_basefw.bin");
diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c
index 4dfbff0ce508..8c4edda97f75 100644
--- a/sound/soc/intel/avs/debugfs.c
+++ b/sound/soc/intel/avs/debugfs.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -10,6 +10,7 @@
#include <linux/kfifo.h>
#include <linux/wait.h>
#include <linux/sched/signal.h>
+#include <linux/string_helpers.h>
#include <sound/soc.h>
#include "avs.h"
#include "messages.h"
@@ -68,7 +69,6 @@ static ssize_t fw_regs_read(struct file *file, char __user *to, size_t count, lo
static const struct file_operations fw_regs_fops = {
.open = simple_open,
.read = fw_regs_read,
- .llseek = no_llseek,
};
static ssize_t debug_window_read(struct file *file, char __user *to, size_t count, loff_t *ppos)
@@ -93,7 +93,6 @@ static ssize_t debug_window_read(struct file *file, char __user *to, size_t coun
static const struct file_operations debug_window_fops = {
.open = simple_open,
.read = debug_window_read,
- .llseek = no_llseek,
};
static ssize_t probe_points_read(struct file *file, char __user *to, size_t count, loff_t *ppos)
@@ -170,7 +169,6 @@ static const struct file_operations probe_points_fops = {
.open = simple_open,
.read = probe_points_read,
.write = probe_points_write,
- .llseek = no_llseek,
};
static ssize_t probe_points_disconnect_write(struct file *file, const char __user *from,
diff --git a/sound/soc/intel/avs/dsp.c b/sound/soc/intel/avs/dsp.c
index aa03af4473e9..464bd6859182 100644
--- a/sound/soc/intel/avs/dsp.c
+++ b/sound/soc/intel/avs/dsp.c
@@ -1,18 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
//
+#include <linux/string_choices.h>
#include <sound/hdaudio_ext.h>
#include "avs.h"
#include "registers.h"
#include "trace.h"
-#define AVS_ADSPCS_INTERVAL_US 500
-#define AVS_ADSPCS_TIMEOUT_US 50000
#define AVS_ADSPCS_DELAY_US 1000
int avs_dsp_core_power(struct avs_dev *adev, u32 core_mask, bool power)
@@ -39,7 +38,7 @@ int avs_dsp_core_power(struct avs_dev *adev, u32 core_mask, bool power)
AVS_ADSPCS_TIMEOUT_US);
if (ret)
dev_err(adev->dev, "core_mask %d power %s failed: %d\n",
- core_mask, power ? "on" : "off", ret);
+ core_mask, str_on_off(power), ret);
return ret;
}
diff --git a/sound/soc/intel/avs/icl.c b/sound/soc/intel/avs/icl.c
index 9d9921e1cd4d..f8d327ea2656 100644
--- a/sound/soc/intel/avs/icl.c
+++ b/sound/soc/intel/avs/icl.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2024 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2024 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -52,22 +52,25 @@ union avs_icl_memwnd2_slot_type {
u32 type:24;
};
} __packed;
+static_assert(sizeof(union avs_icl_memwnd2_slot_type) == 4);
struct avs_icl_memwnd2_desc {
u32 resource_id;
union avs_icl_memwnd2_slot_type slot_id;
u32 vma;
} __packed;
+static_assert(sizeof(struct avs_icl_memwnd2_desc) == 12);
#define AVS_ICL_MEMWND2_SLOTS_COUNT 15
struct avs_icl_memwnd2 {
union {
struct avs_icl_memwnd2_desc slot_desc[AVS_ICL_MEMWND2_SLOTS_COUNT];
- u8 rsvd[PAGE_SIZE];
+ u8 rsvd[SZ_4K];
};
- u8 slot_array[AVS_ICL_MEMWND2_SLOTS_COUNT][PAGE_SIZE];
+ u8 slot_array[AVS_ICL_MEMWND2_SLOTS_COUNT][SZ_4K];
} __packed;
+static_assert(sizeof(struct avs_icl_memwnd2) == 65536);
#define AVS_ICL_SLOT_UNUSED \
((union avs_icl_memwnd2_slot_type) { 0x00000000U })
@@ -89,8 +92,7 @@ static int avs_icl_slot_offset(struct avs_dev *adev, union avs_icl_memwnd2_slot_
for (i = 0; i < AVS_ICL_MEMWND2_SLOTS_COUNT; i++)
if (desc[i].slot_id.val == slot_type.val)
- return offsetof(struct avs_icl_memwnd2, slot_array) +
- avs_skl_log_buffer_offset(adev, i);
+ return offsetof(struct avs_icl_memwnd2, slot_array) + i * SZ_4K;
return -ENXIO;
}
@@ -110,6 +112,10 @@ int avs_icl_log_buffer_offset(struct avs_dev *adev, u32 core)
bool avs_icl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake)
{
+ /* Full-power when starting DMA engines. */
+ if (tx->glb.set_ppl_state.state == AVS_PPL_STATE_RUNNING)
+ return true;
+
/* Payload-less IPCs do not take part in d0ix toggling. */
return tx->size;
}
@@ -182,8 +188,7 @@ const struct avs_dsp_ops avs_icl_dsp_ops = {
.power = avs_dsp_core_power,
.reset = avs_dsp_core_reset,
.stall = avs_dsp_core_stall,
- .irq_handler = avs_irq_handler,
- .irq_thread = avs_cnl_irq_thread,
+ .dsp_interrupt = avs_cnl_dsp_interrupt,
.int_control = avs_dsp_interrupt_control,
.load_basefw = avs_icl_load_basefw,
.load_lib = avs_hda_load_library,
diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c
index ad0e535b3c2e..08ed9d96738a 100644
--- a/sound/soc/intel/avs/ipc.c
+++ b/sound/soc/intel/avs/ipc.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -184,10 +184,11 @@ static void avs_dsp_receive_rx(struct avs_dev *adev, u64 header)
{
struct avs_ipc *ipc = adev->ipc;
union avs_reply_msg msg = AVS_MSG(header);
- u64 reg;
+ u32 sts, lec;
- reg = readq(avs_sram_addr(adev, AVS_FW_REGS_WINDOW));
- trace_avs_ipc_reply_msg(header, reg);
+ sts = snd_hdac_adsp_readl(adev, AVS_FW_REG_STATUS(adev));
+ lec = snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev));
+ trace_avs_ipc_reply_msg(header, sts, lec);
ipc->rx.header = header;
/* Abort copying payload if request processing was unsuccessful. */
@@ -209,10 +210,11 @@ static void avs_dsp_process_notification(struct avs_dev *adev, u64 header)
union avs_notify_msg msg = AVS_MSG(header);
size_t data_size = 0;
void *data = NULL;
- u64 reg;
+ u32 sts, lec;
- reg = readq(avs_sram_addr(adev, AVS_FW_REGS_WINDOW));
- trace_avs_ipc_notify_msg(header, reg);
+ sts = snd_hdac_adsp_readl(adev, AVS_FW_REG_STATUS(adev));
+ lec = snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev));
+ trace_avs_ipc_notify_msg(header, sts, lec);
/* Ignore spurious notifications until handshake is established. */
if (!adev->ipc->ready && msg.notify_msg_type != AVS_NOTIFY_FW_READY) {
@@ -301,54 +303,6 @@ void avs_dsp_process_response(struct avs_dev *adev, u64 header)
complete(&ipc->busy_completion);
}
-irqreturn_t avs_irq_handler(struct avs_dev *adev)
-{
- struct avs_ipc *ipc = adev->ipc;
- const struct avs_spec *const spec = adev->spec;
- u32 adspis, hipc_rsp, hipc_ack;
- irqreturn_t ret = IRQ_NONE;
-
- adspis = snd_hdac_adsp_readl(adev, AVS_ADSP_REG_ADSPIS);
- if (adspis == UINT_MAX || !(adspis & AVS_ADSP_ADSPIS_IPC))
- return ret;
-
- hipc_ack = snd_hdac_adsp_readl(adev, spec->hipc->ack_offset);
- hipc_rsp = snd_hdac_adsp_readl(adev, spec->hipc->rsp_offset);
-
- /* DSP acked host's request */
- if (hipc_ack & spec->hipc->ack_done_mask) {
- /*
- * As an extra precaution, mask done interrupt. Code executed
- * due to complete() found below does not assume any masking.
- */
- snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,
- AVS_ADSP_HIPCCTL_DONE, 0);
-
- complete(&ipc->done_completion);
-
- /* tell DSP it has our attention */
- snd_hdac_adsp_updatel(adev, spec->hipc->ack_offset,
- spec->hipc->ack_done_mask,
- spec->hipc->ack_done_mask);
- /* unmask done interrupt */
- snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,
- AVS_ADSP_HIPCCTL_DONE,
- AVS_ADSP_HIPCCTL_DONE);
- ret = IRQ_HANDLED;
- }
-
- /* DSP sent new response to process */
- if (hipc_rsp & spec->hipc->rsp_busy_mask) {
- /* mask busy interrupt */
- snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,
- AVS_ADSP_HIPCCTL_BUSY, 0);
-
- ret = IRQ_WAKE_THREAD;
- }
-
- return ret;
-}
-
static bool avs_ipc_is_busy(struct avs_ipc *ipc)
{
struct avs_dev *adev = to_avs_dev(ipc->dev);
@@ -415,13 +369,16 @@ static void avs_ipc_msg_init(struct avs_ipc *ipc, struct avs_ipc_msg *reply)
static void avs_dsp_send_tx(struct avs_dev *adev, struct avs_ipc_msg *tx, bool read_fwregs)
{
const struct avs_spec *const spec = adev->spec;
- u64 reg = ULONG_MAX;
+ u32 sts = UINT_MAX;
+ u32 lec = UINT_MAX;
tx->header |= spec->hipc->req_busy_mask;
- if (read_fwregs)
- reg = readq(avs_sram_addr(adev, AVS_FW_REGS_WINDOW));
+ if (read_fwregs) {
+ sts = snd_hdac_adsp_readl(adev, AVS_FW_REG_STATUS(adev));
+ lec = snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev));
+ }
- trace_avs_request(tx, reg);
+ trace_avs_request(tx, sts, lec);
if (tx->size)
memcpy_toio(avs_downlink_addr(adev), tx->data, tx->size);
diff --git a/sound/soc/intel/avs/lnl.c b/sound/soc/intel/avs/lnl.c
new file mode 100644
index 000000000000..03208596dfb1
--- /dev/null
+++ b/sound/soc/intel/avs/lnl.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright(c) 2021-2025 Intel Corporation
+ *
+ * Authors: Cezary Rojewski <cezary.rojewski@intel.com>
+ * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+ */
+
+#include <sound/hdaudio_ext.h>
+#include "avs.h"
+#include "registers.h"
+
+int avs_lnl_core_stall(struct avs_dev *adev, u32 core_mask, bool stall)
+{
+ struct hdac_bus *bus = &adev->base.core;
+ struct hdac_ext_link *hlink;
+ int ret;
+
+ ret = avs_mtl_core_stall(adev, core_mask, stall);
+
+ /* On unstall, route interrupts from the links to the DSP firmware. */
+ if (!ret && !stall)
+ list_for_each_entry(hlink, &bus->hlink_list, list)
+ snd_hdac_updatel(hlink->ml_addr, AZX_REG_ML_LCTL, AZX_ML_LCTL_OFLEN,
+ AZX_ML_LCTL_OFLEN);
+ return ret;
+}
diff --git a/sound/soc/intel/avs/loader.c b/sound/soc/intel/avs/loader.c
index 8e34d3536082..138e4e9de5e3 100644
--- a/sound/soc/intel/avs/loader.c
+++ b/sound/soc/intel/avs/loader.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -56,6 +56,7 @@ struct avs_fw_manifest {
u32 feature_mask;
struct avs_fw_version version;
} __packed;
+static_assert(sizeof(struct avs_fw_manifest) == 36);
struct avs_fw_ext_manifest {
u32 id;
@@ -64,6 +65,7 @@ struct avs_fw_ext_manifest {
u16 version_minor;
u32 entries;
} __packed;
+static_assert(sizeof(struct avs_fw_ext_manifest) == 16);
static int avs_fw_ext_manifest_strip(struct firmware *fw)
{
@@ -165,7 +167,8 @@ int avs_cldma_load_basefw(struct avs_dev *adev, struct firmware *fw)
(reg & AVS_ROM_INIT_DONE) == AVS_ROM_INIT_DONE,
AVS_ROM_INIT_POLLING_US, SKL_ROM_INIT_TIMEOUT_US);
if (ret < 0) {
- dev_err(adev->dev, "rom init timeout: %d\n", ret);
+ dev_err(adev->dev, "rom init failed: %d, status: 0x%08x, lec: 0x%08x\n",
+ ret, reg, snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev)));
avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
return ret;
}
@@ -178,7 +181,8 @@ int avs_cldma_load_basefw(struct avs_dev *adev, struct firmware *fw)
AVS_FW_INIT_POLLING_US, AVS_FW_INIT_TIMEOUT_US);
hda_cldma_stop(cl);
if (ret < 0) {
- dev_err(adev->dev, "transfer fw failed: %d\n", ret);
+ dev_err(adev->dev, "transfer fw failed: %d, status: 0x%08x, lec: 0x%08x\n",
+ ret, reg, snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev)));
avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
return ret;
}
@@ -306,12 +310,13 @@ avs_hda_init_rom(struct avs_dev *adev, unsigned int dma_id, bool purge)
}
/* await ROM init */
- ret = snd_hdac_adsp_readq_poll(adev, spec->sram->rom_status_offset, reg,
+ ret = snd_hdac_adsp_readl_poll(adev, spec->hipc->sts_offset, reg,
(reg & 0xF) == AVS_ROM_INIT_DONE ||
(reg & 0xF) == APL_ROM_FW_ENTERED,
AVS_ROM_INIT_POLLING_US, APL_ROM_INIT_TIMEOUT_US);
if (ret < 0) {
- dev_err(adev->dev, "rom init timeout: %d\n", ret);
+ dev_err(adev->dev, "rom init failed: %d, status: 0x%08x, lec: 0x%08x\n",
+ ret, reg, snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev)));
goto err;
}
@@ -335,15 +340,15 @@ static int avs_imr_load_basefw(struct avs_dev *adev)
/* DMA id ignored when flashing from IMR as no transfer occurs. */
ret = avs_hda_init_rom(adev, 0, false);
- if (ret < 0) {
- dev_err(adev->dev, "rom init failed: %d\n", ret);
+ if (ret < 0)
return ret;
- }
ret = wait_for_completion_timeout(&adev->fw_ready,
msecs_to_jiffies(AVS_FW_INIT_TIMEOUT_MS));
if (!ret) {
- dev_err(adev->dev, "firmware ready timeout\n");
+ dev_err(adev->dev, "firmware ready timeout, status: 0x%08x, lec: 0x%08x\n",
+ snd_hdac_adsp_readl(adev, AVS_FW_REG_STATUS(adev)),
+ snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev)));
avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
return -ETIMEDOUT;
}
@@ -390,7 +395,7 @@ int avs_hda_load_basefw(struct avs_dev *adev, struct firmware *fw)
ret = avs_hda_init_rom(adev, dma_id, true);
if (!ret)
break;
- dev_info(adev->dev, "#%d rom init fail: %d\n", i + 1, ret);
+ dev_info(adev->dev, "#%d rom init failed: %d\n", i + 1, ret);
}
if (ret < 0)
goto cleanup_resources;
@@ -402,7 +407,8 @@ int avs_hda_load_basefw(struct avs_dev *adev, struct firmware *fw)
AVS_FW_INIT_POLLING_US, AVS_FW_INIT_TIMEOUT_US);
snd_hdac_dsp_trigger(hstream, false);
if (ret < 0) {
- dev_err(adev->dev, "transfer fw failed: %d\n", ret);
+ dev_err(adev->dev, "transfer fw failed: %d, status: 0x%08x, lec: 0x%08x\n",
+ ret, reg, snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev)));
avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
}
@@ -535,7 +541,7 @@ int avs_dsp_load_libraries(struct avs_dev *adev, struct avs_tplg_library *libs,
if (ret)
return ret;
- strncpy(adev->lib_names[id], man->name, AVS_LIB_NAME_SIZE);
+ strscpy(adev->lib_names[id], man->name, AVS_LIB_NAME_SIZE);
id++;
next_lib:
i++;
@@ -582,7 +588,9 @@ static int avs_dsp_load_basefw(struct avs_dev *adev)
ret = wait_for_completion_timeout(&adev->fw_ready,
msecs_to_jiffies(AVS_FW_INIT_TIMEOUT_MS));
if (!ret) {
- dev_err(adev->dev, "firmware ready timeout\n");
+ dev_err(adev->dev, "firmware ready timeout, status: 0x%08x, lec: 0x%08x\n",
+ snd_hdac_adsp_readl(adev, AVS_FW_REG_STATUS(adev)),
+ snd_hdac_adsp_readl(adev, AVS_FW_REG_ERROR(adev)));
avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
ret = -ETIMEDOUT;
goto release_fw;
@@ -595,7 +603,7 @@ release_fw:
return ret;
}
-int avs_dsp_boot_firmware(struct avs_dev *adev, bool purge)
+static int avs_load_firmware(struct avs_dev *adev, bool purge)
{
struct avs_soc_component *acomp;
int ret, i;
@@ -649,39 +657,49 @@ reenable_gating:
return 0;
}
-int avs_dsp_first_boot_firmware(struct avs_dev *adev)
+static int avs_config_basefw(struct avs_dev *adev)
{
- int ret, i;
+ int ret;
- if (avs_platattr_test(adev, CLDMA)) {
- ret = hda_cldma_init(&code_loader, &adev->base.core,
- adev->dsp_ba, AVS_CL_DEFAULT_BUFFER_SIZE);
- if (ret < 0) {
- dev_err(adev->dev, "cldma init failed: %d\n", ret);
+ if (adev->spec->dsp_ops->config_basefw) {
+ ret = avs_dsp_op(adev, config_basefw);
+ if (ret)
return ret;
- }
}
- ret = avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
- if (ret < 0)
- return ret;
+ return 0;
+}
- ret = avs_dsp_boot_firmware(adev, true);
- if (ret < 0) {
- dev_err(adev->dev, "firmware boot failed: %d\n", ret);
+int avs_dsp_boot_firmware(struct avs_dev *adev, bool purge)
+{
+ int ret;
+
+ ret = avs_load_firmware(adev, purge);
+ if (ret)
return ret;
- }
+
+ return avs_config_basefw(adev);
+}
+
+static int avs_dsp_alloc_resources(struct avs_dev *adev)
+{
+ struct hdac_ext_link *link;
+ int ret, i;
ret = avs_ipc_get_hw_config(adev, &adev->hw_cfg);
- if (ret) {
- dev_err(adev->dev, "get hw cfg failed: %d\n", ret);
+ if (ret)
return AVS_IPC_RET(ret);
- }
ret = avs_ipc_get_fw_config(adev, &adev->fw_cfg);
- if (ret) {
- dev_err(adev->dev, "get fw cfg failed: %d\n", ret);
+ if (ret)
return AVS_IPC_RET(ret);
+
+ /* If hw allows, read capabilities directly from it. */
+ if (avs_platattr_test(adev, ALTHDA)) {
+ link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core,
+ AZX_REG_ML_LEPTR_ID_INTEL_SSP);
+ if (link)
+ adev->hw_cfg.i2s_caps.ctrl_count = link->slcount;
}
adev->core_refs = devm_kcalloc(adev->dev, adev->hw_cfg.dsp_cores,
@@ -698,9 +716,34 @@ int avs_dsp_first_boot_firmware(struct avs_dev *adev)
}
/* basefw always occupies slot 0 */
- strcpy(&adev->lib_names[0][0], "BASEFW");
+ strscpy(adev->lib_names[0], "BASEFW", AVS_LIB_NAME_SIZE);
ida_init(&adev->ppl_ida);
-
return 0;
}
+
+int avs_dsp_first_boot_firmware(struct avs_dev *adev)
+{
+ int ret;
+
+ if (avs_platattr_test(adev, CLDMA)) {
+ ret = hda_cldma_init(&code_loader, &adev->base.core,
+ adev->dsp_ba, AVS_CL_DEFAULT_BUFFER_SIZE);
+ if (ret < 0) {
+ dev_err(adev->dev, "cldma init failed: %d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK);
+ if (ret < 0)
+ return ret;
+
+ ret = avs_dsp_boot_firmware(adev, true);
+ if (ret < 0) {
+ dev_err(adev->dev, "firmware boot failed: %d\n", ret);
+ return ret;
+ }
+
+ return avs_dsp_alloc_resources(adev);
+}
diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c
index f874e4f0d95f..a5ba27983091 100644
--- a/sound/soc/intel/avs/messages.c
+++ b/sound/soc/intel/avs/messages.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -400,10 +400,12 @@ int avs_ipc_get_fw_config(struct avs_dev *adev, struct avs_fw_cfg *cfg)
AVS_BASEFW_FIRMWARE_CONFIG, NULL, 0,
&payload, &payload_size);
if (ret)
- return ret;
+ goto err;
/* Non-zero payload expected for FIRMWARE_CONFIG. */
- if (!payload_size)
- return -EREMOTEIO;
+ if (!payload_size) {
+ ret = -EREMOTEIO;
+ goto err;
+ }
while (offset < payload_size) {
tlv = (struct avs_tlv *)(payload + offset);
@@ -502,6 +504,47 @@ int avs_ipc_get_fw_config(struct avs_dev *adev, struct avs_fw_cfg *cfg)
/* No longer needed, free it as it's owned by the get_large_config() caller. */
kfree(payload);
+err:
+ if (ret)
+ dev_err(adev->dev, "get fw cfg failed: %d\n", ret);
+ return ret;
+}
+
+int avs_ipc_set_fw_config(struct avs_dev *adev, size_t num_tlvs, ...)
+{
+ struct avs_tlv *tlv;
+ void *payload;
+ size_t offset;
+ va_list args;
+ int ret, i;
+
+ payload = kzalloc(AVS_MAILBOX_SIZE, GFP_KERNEL);
+ if (!payload)
+ return -ENOMEM;
+
+ va_start(args, num_tlvs);
+ for (offset = i = 0; i < num_tlvs && offset < AVS_MAILBOX_SIZE - sizeof(*tlv); i++) {
+ tlv = (struct avs_tlv *)(payload + offset);
+ tlv->type = va_arg(args, u32);
+ tlv->length = va_arg(args, u32);
+
+ offset += sizeof(*tlv) + tlv->length;
+ if (offset > AVS_MAILBOX_SIZE)
+ break;
+
+ memcpy(tlv->value, va_arg(args, u8*), tlv->length);
+ }
+
+ if (i == num_tlvs)
+ ret = avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID,
+ AVS_BASEFW_FIRMWARE_CONFIG, payload, offset);
+ else
+ ret = -ERANGE;
+
+ va_end(args);
+ kfree(payload);
+ if (ret)
+ dev_err(adev->dev, "set fw cfg failed: %d\n", ret);
return ret;
}
@@ -517,10 +560,12 @@ int avs_ipc_get_hw_config(struct avs_dev *adev, struct avs_hw_cfg *cfg)
AVS_BASEFW_HARDWARE_CONFIG, NULL, 0,
&payload, &payload_size);
if (ret)
- return ret;
+ goto err;
/* Non-zero payload expected for HARDWARE_CONFIG. */
- if (!payload_size)
- return -EREMOTEIO;
+ if (!payload_size) {
+ ret = -EREMOTEIO;
+ goto err;
+ }
while (offset < payload_size) {
tlv = (struct avs_tlv *)(payload + offset);
@@ -590,6 +635,9 @@ int avs_ipc_get_hw_config(struct avs_dev *adev, struct avs_hw_cfg *cfg)
exit:
/* No longer needed, free it as it's owned by the get_large_config() caller. */
kfree(payload);
+err:
+ if (ret)
+ dev_err(adev->dev, "get hw cfg failed: %d\n", ret);
return ret;
}
@@ -629,13 +677,6 @@ int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id,
(u8 *)&cpr_fmt, sizeof(cpr_fmt));
}
-int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
- struct avs_volume_cfg *vol)
-{
- return avs_ipc_set_large_config(adev, module_id, instance_id, AVS_PEAKVOL_VOLUME, (u8 *)vol,
- sizeof(*vol));
-}
-
int avs_ipc_peakvol_get_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
struct avs_volume_cfg **vols, size_t *num_vols)
{
@@ -658,6 +699,110 @@ int avs_ipc_peakvol_get_volume(struct avs_dev *adev, u16 module_id, u8 instance_
return 0;
}
+int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_volume_cfg *vol)
+{
+ return avs_ipc_set_large_config(adev, module_id, instance_id, AVS_PEAKVOL_VOLUME,
+ (u8 *)vol, sizeof(*vol));
+}
+
+int avs_ipc_peakvol_set_volumes(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_volume_cfg *vols, size_t num_vols)
+{
+ struct avs_tlv *tlv;
+ size_t offset;
+ size_t size;
+ u8 *payload;
+ int ret, i;
+
+ size = num_vols * sizeof(*vols);
+ size += num_vols * sizeof(*tlv);
+ if (size > AVS_MAILBOX_SIZE)
+ return -EINVAL;
+
+ payload = kzalloc(AVS_MAILBOX_SIZE, GFP_KERNEL);
+ if (!payload)
+ return -ENOMEM;
+
+ for (offset = i = 0; i < num_vols; i++) {
+ tlv = (struct avs_tlv *)(payload + offset);
+
+ tlv->type = AVS_PEAKVOL_VOLUME;
+ tlv->length = sizeof(*vols);
+ memcpy(tlv->value, &vols[i], tlv->length);
+
+ offset += sizeof(*tlv) + tlv->length;
+ }
+
+ ret = avs_ipc_set_large_config(adev, module_id, instance_id, AVS_VENDOR_CONFIG, payload,
+ size);
+ kfree(payload);
+ return ret;
+}
+
+int avs_ipc_peakvol_get_mute(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_mute_cfg **mutes, size_t *num_mutes)
+{
+ size_t payload_size;
+ u8 *payload;
+ int ret;
+
+ ret = avs_ipc_get_large_config(adev, module_id, instance_id, AVS_PEAKVOL_MUTE, NULL, 0,
+ &payload, &payload_size);
+ if (ret)
+ return ret;
+
+ /* Non-zero payload expected for PEAKVOL_MUTE. */
+ if (!payload_size)
+ return -EREMOTEIO;
+
+ *mutes = (struct avs_mute_cfg *)payload;
+ *num_mutes = payload_size / sizeof(**mutes);
+
+ return 0;
+}
+
+int avs_ipc_peakvol_set_mute(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_mute_cfg *mute)
+{
+ return avs_ipc_set_large_config(adev, module_id, instance_id, AVS_PEAKVOL_MUTE,
+ (u8 *)mute, sizeof(*mute));
+}
+
+int avs_ipc_peakvol_set_mutes(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_mute_cfg *mutes, size_t num_mutes)
+{
+ struct avs_tlv *tlv;
+ size_t offset;
+ size_t size;
+ u8 *payload;
+ int ret, i;
+
+ size = num_mutes * sizeof(*mutes);
+ size += num_mutes * sizeof(*tlv);
+ if (size > AVS_MAILBOX_SIZE)
+ return -EINVAL;
+
+ payload = kzalloc(AVS_MAILBOX_SIZE, GFP_KERNEL);
+ if (!payload)
+ return -ENOMEM;
+
+ for (offset = i = 0; i < num_mutes; i++) {
+ tlv = (struct avs_tlv *)(payload + offset);
+
+ tlv->type = AVS_PEAKVOL_MUTE;
+ tlv->length = sizeof(*mutes);
+ memcpy(tlv->value, &mutes[i], tlv->length);
+
+ offset += sizeof(*tlv) + tlv->length;
+ }
+
+ ret = avs_ipc_set_large_config(adev, module_id, instance_id, AVS_VENDOR_CONFIG, payload,
+ size);
+ kfree(payload);
+ return ret;
+}
+
#ifdef CONFIG_DEBUG_FS
int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size)
{
diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h
index 4e609a08863c..55c04b0142ae 100644
--- a/sound/soc/intel/avs/messages.h
+++ b/sound/soc/intel/avs/messages.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+ * Copyright(c) 2021-2022 Intel Corporation
*
* Authors: Cezary Rojewski <cezary.rojewski@intel.com>
* Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -93,12 +93,16 @@ union avs_global_msg {
} ext;
};
} __packed;
+static_assert(sizeof(union avs_global_msg) == 8);
struct avs_tlv {
u32 type;
u32 length;
u32 value[];
} __packed;
+static_assert(sizeof(struct avs_tlv) == 8);
+
+#define avs_tlv_size(tlv) struct_size(tlv, value, (tlv)->length / 4)
enum avs_module_msg_type {
AVS_MOD_INIT_INSTANCE = 0,
@@ -155,6 +159,7 @@ union avs_module_msg {
} ext;
};
} __packed;
+static_assert(sizeof(union avs_module_msg) == 8);
#define AVS_IPC_NOT_SUPPORTED 15
@@ -190,6 +195,7 @@ union avs_reply_msg {
} ext;
};
} __packed;
+static_assert(sizeof(union avs_reply_msg) == 8);
enum avs_notify_msg_type {
AVS_NOTIFY_PHRASE_DETECTED = 4,
@@ -226,6 +232,7 @@ union avs_notify_msg {
} ext;
};
} __packed;
+static_assert(sizeof(union avs_notify_msg) == 8);
#define AVS_MSG(hdr) { .val = hdr }
@@ -264,6 +271,7 @@ struct avs_notify_voice_data {
u16 kpd_score;
u16 reserved;
} __packed;
+static_assert(sizeof(struct avs_notify_voice_data) == 4);
struct avs_notify_res_data {
u32 resource_type;
@@ -272,6 +280,7 @@ struct avs_notify_res_data {
u32 reserved;
u32 data[6];
} __packed;
+static_assert(sizeof(struct avs_notify_res_data) == 40);
struct avs_notify_mod_data {
u32 module_instance_id;
@@ -279,6 +288,7 @@ struct avs_notify_mod_data {
u32 data_size;
u32 data[];
} __packed;
+static_assert(sizeof(struct avs_notify_mod_data) == 12);
/* ROM messages */
enum avs_rom_control_msg_type {
@@ -332,6 +342,7 @@ struct avs_dxstate_info {
u32 core_mask; /* which cores are subject for power transition */
u32 dx_mask; /* bit[n]=1 core n goes to D0, bit[n]=0 it goes to D3 */
} __packed;
+static_assert(sizeof(struct avs_dxstate_info) == 8);
int avs_ipc_set_dx(struct avs_dev *adev, u32 core_mask, bool powerup);
int avs_ipc_set_d0ix(struct avs_dev *adev, bool enable_pg, bool streaming);
@@ -367,11 +378,13 @@ struct avs_skl_log_state {
u32 enable;
u32 min_priority;
} __packed;
+static_assert(sizeof(struct avs_skl_log_state) == 8);
struct avs_skl_log_state_info {
u32 core_mask;
struct avs_skl_log_state logs_core[];
} __packed;
+static_assert(sizeof(struct avs_skl_log_state_info) == 4);
struct avs_apl_log_state_info {
u32 aging_timer_period;
@@ -379,6 +392,7 @@ struct avs_apl_log_state_info {
u32 core_mask;
struct avs_skl_log_state logs_core[];
} __packed;
+static_assert(sizeof(struct avs_apl_log_state_info) == 12);
enum avs_icl_log_priority {
AVS_ICL_LOG_CRITICAL = 0,
@@ -403,6 +417,7 @@ struct avs_icl_log_state_info {
u32 enable;
u32 logs_priorities_mask[];
} __packed;
+static_assert(sizeof(struct avs_icl_log_state_info) == 12);
int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size);
@@ -438,6 +453,8 @@ enum avs_fw_cfg_params {
AVS_FW_CFG_RESERVED,
AVS_FW_CFG_POWER_GATING_POLICY,
AVS_FW_CFG_ASSERT_MODE,
+ AVS_FW_CFG_RESERVED2,
+ AVS_FW_CFG_BUS_HARDWARE_ID,
};
struct avs_fw_cfg {
@@ -462,7 +479,14 @@ struct avs_fw_cfg {
u32 power_gating_policy;
};
+struct avs_bus_hwid {
+ u32 device;
+ u32 subsystem;
+ u8 revision;
+};
+
int avs_ipc_get_fw_config(struct avs_dev *adev, struct avs_fw_cfg *cfg);
+int avs_ipc_set_fw_config(struct avs_dev *adev, size_t num_tlvs, ...);
enum avs_hw_cfg_params {
AVS_HW_CFG_AVS_VER,
@@ -521,6 +545,7 @@ struct avs_module_type {
u32 lib_code:1;
u32 rsvd:24;
} __packed;
+static_assert(sizeof(struct avs_module_type) == 4);
union avs_segment_flags {
u32 ul;
@@ -537,12 +562,14 @@ union avs_segment_flags {
u32 length:16;
};
} __packed;
+static_assert(sizeof(union avs_segment_flags) == 4);
struct avs_segment_desc {
union avs_segment_flags flags;
u32 v_base_addr;
u32 file_offset;
} __packed;
+static_assert(sizeof(struct avs_segment_desc) == 12);
struct avs_module_entry {
u16 module_id;
@@ -559,11 +586,13 @@ struct avs_module_entry {
u16 instance_bss_size;
struct avs_segment_desc segments[3];
} __packed;
+static_assert(sizeof(struct avs_module_entry) == 116);
struct avs_mods_info {
u32 count;
struct avs_module_entry entries[];
} __packed;
+static_assert(sizeof(struct avs_mods_info) == 4);
static inline bool avs_module_entry_is_loaded(struct avs_module_entry *mentry)
{
@@ -577,6 +606,7 @@ struct avs_sys_time {
u32 val_l;
u32 val_u;
} __packed;
+static_assert(sizeof(struct avs_sys_time) == 8);
int avs_ipc_set_system_time(struct avs_dev *adev);
@@ -624,6 +654,9 @@ int avs_ipc_set_system_time(struct avs_dev *adev);
#define AVS_INTELWOV_MOD_UUID \
GUID_INIT(0xEC774FA9, 0x28D3, 0x424A, 0x90, 0xE4, 0x69, 0xF9, 0x84, 0xF1, 0xEE, 0xB7)
+#define AVS_WOVHOSTM_MOD_UUID \
+ GUID_INIT(0xF9ED62B7, 0x092E, 0x4A90, 0x8F, 0x4D, 0x82, 0xDA, 0xA8, 0xB3, 0x8F, 0x3B)
+
/* channel map */
enum avs_channel_index {
AVS_CHANNEL_LEFT = 0,
@@ -666,8 +699,9 @@ enum avs_sample_type {
AVS_SAMPLE_TYPE_FLOAT = 4,
};
-#define AVS_CHANNELS_MAX 8
+#define AVS_COEFF_CHANNELS_MAX 8
#define AVS_ALL_CHANNELS_MASK UINT_MAX
+#define AVS_CHANNELS_MAX 16
struct avs_audio_format {
u32 sampling_freq;
@@ -680,6 +714,7 @@ struct avs_audio_format {
u32 sample_type:8;
u32 reserved:8;
} __packed;
+static_assert(sizeof(struct avs_audio_format) == 24);
struct avs_modcfg_base {
u32 cpc;
@@ -688,12 +723,14 @@ struct avs_modcfg_base {
u32 is_pages;
struct avs_audio_format audio_fmt;
} __packed;
+static_assert(sizeof(struct avs_modcfg_base) == 40);
struct avs_pin_format {
u32 pin_index;
u32 iobs;
struct avs_audio_format audio_fmt;
} __packed;
+static_assert(sizeof(struct avs_pin_format) == 32);
struct avs_modcfg_ext {
struct avs_modcfg_base base;
@@ -703,6 +740,7 @@ struct avs_modcfg_ext {
/* input pin formats followed by output ones */
struct avs_pin_format pin_fmts[];
} __packed;
+static_assert(sizeof(struct avs_modcfg_ext) == 56);
enum avs_dma_type {
AVS_DMA_HDA_HOST_OUTPUT = 0,
@@ -726,6 +764,7 @@ union avs_virtual_index {
u8 instance:3;
} dmic;
} __packed;
+static_assert(sizeof(union avs_virtual_index) == 1);
union avs_connector_node_id {
u32 val;
@@ -735,6 +774,7 @@ union avs_connector_node_id {
u32 rsvd:19;
};
} __packed;
+static_assert(sizeof(union avs_connector_node_id) == 4);
#define INVALID_PIPELINE_ID 0xFF
#define INVALID_NODE_ID \
@@ -747,16 +787,45 @@ union avs_gtw_attributes {
u32 rsvd:31;
};
} __packed;
+static_assert(sizeof(union avs_gtw_attributes) == 4);
+
+#define AVS_GTW_DMA_CONFIG_ID 0x1000
+#define AVS_DMA_METHOD_HDA 1
+
+struct avs_dma_device_stream_channel_map {
+ u32 device_address;
+ u32 channel_map;
+} __packed;
+static_assert(sizeof(struct avs_dma_device_stream_channel_map) == 8);
+
+struct avs_dma_stream_channel_map {
+ u32 device_count;
+ struct avs_dma_device_stream_channel_map map[16];
+} __packed;
+static_assert(sizeof(struct avs_dma_stream_channel_map) == 132);
+
+struct avs_dma_cfg {
+ u8 dma_method;
+ u8 pre_allocated;
+ u16 rsvd;
+ u32 dma_channel_id;
+ u32 stream_id;
+ struct avs_dma_stream_channel_map map;
+ u32 config_size;
+ u8 config[] __counted_by(config_size);
+} __packed;
+static_assert(sizeof(struct avs_dma_cfg) == 148);
struct avs_copier_gtw_cfg {
union avs_connector_node_id node_id;
u32 dma_buffer_size;
u32 config_length;
- struct {
+ union {
union avs_gtw_attributes attrs;
- u32 blob[];
+ DECLARE_FLEX_ARRAY(u32, blob);
} config;
} __packed;
+static_assert(sizeof(struct avs_copier_gtw_cfg) == 16);
struct avs_copier_cfg {
struct avs_modcfg_base base;
@@ -764,6 +833,7 @@ struct avs_copier_cfg {
u32 feature_mask;
struct avs_copier_gtw_cfg gtw_cfg;
} __packed;
+static_assert(sizeof(struct avs_copier_cfg) == 84);
struct avs_volume_cfg {
u32 channel_id;
@@ -772,45 +842,62 @@ struct avs_volume_cfg {
u32 reserved; /* alignment */
u64 curve_duration;
} __packed;
+static_assert(sizeof(struct avs_volume_cfg) == 24);
+
+struct avs_mute_cfg {
+ u32 channel_id;
+ u32 mute;
+ u32 curve_type;
+ u32 reserved; /* alignment */
+ u64 curve_duration;
+} __packed;
+static_assert(sizeof(struct avs_mute_cfg) == 24);
struct avs_peakvol_cfg {
struct avs_modcfg_base base;
struct avs_volume_cfg vols[];
} __packed;
+static_assert(sizeof(struct avs_peakvol_cfg) == 40);
struct avs_micsel_cfg {
struct avs_modcfg_base base;
struct avs_audio_format out_fmt;
} __packed;
+static_assert(sizeof(struct avs_micsel_cfg) == 64);
struct avs_mux_cfg {
struct avs_modcfg_base base;
struct avs_audio_format ref_fmt;
struct avs_audio_format out_fmt;
} __packed;
+static_assert(sizeof(struct avs_mux_cfg) == 88);
struct avs_updown_mixer_cfg {
struct avs_modcfg_base base;
u32 out_channel_config;
u32 coefficients_select;
- s32 coefficients[AVS_CHANNELS_MAX];
+ s32 coefficients[AVS_COEFF_CHANNELS_MAX];
u32 channel_map;
} __packed;
+static_assert(sizeof(struct avs_updown_mixer_cfg) == 84);
struct avs_src_cfg {
struct avs_modcfg_base base;
u32 out_freq;
} __packed;
+static_assert(sizeof(struct avs_src_cfg) == 44);
struct avs_probe_gtw_cfg {
union avs_connector_node_id node_id;
u32 dma_buffer_size;
} __packed;
+static_assert(sizeof(struct avs_probe_gtw_cfg) == 8);
struct avs_probe_cfg {
struct avs_modcfg_base base;
struct avs_probe_gtw_cfg gtw_cfg;
} __packed;
+static_assert(sizeof(struct avs_probe_cfg) == 48);
struct avs_aec_cfg {
struct avs_modcfg_base base;
@@ -818,24 +905,38 @@ struct avs_aec_cfg {
struct avs_audio_format out_fmt;
u32 cpc_lp_mode;
} __packed;
+static_assert(sizeof(struct avs_aec_cfg) == 92);
struct avs_asrc_cfg {
struct avs_modcfg_base base;
u32 out_freq;
- u32 rsvd0:1;
- u32 mode:1;
+ u32 mode:2;
u32 rsvd2:2;
u32 disable_jitter_buffer:1;
u32 rsvd3:27;
} __packed;
+static_assert(sizeof(struct avs_asrc_cfg) == 48);
struct avs_wov_cfg {
struct avs_modcfg_base base;
u32 cpc_lp_mode;
} __packed;
+static_assert(sizeof(struct avs_wov_cfg) == 44);
+
+struct avs_whm_cfg {
+ struct avs_modcfg_base base;
+ /* Audio format for output pin 0 */
+ struct avs_audio_format ref_fmt;
+ struct avs_audio_format out_fmt;
+ u32 wake_tick_period;
+ struct avs_copier_gtw_cfg gtw_cfg;
+} __packed;
+static_assert(sizeof(struct avs_whm_cfg) == 108);
/* Module runtime parameters */
+#define AVS_VENDOR_CONFIG 0xFF
+
enum avs_copier_runtime_param {
AVS_COPIER_SET_SINK_FORMAT = 2,
};
@@ -845,6 +946,7 @@ struct avs_copier_sink_format {
struct avs_audio_format src_fmt;
struct avs_audio_format sink_fmt;
} __packed;
+static_assert(sizeof(struct avs_copier_sink_format) == 52);
int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id,
u8 instance_id, u32 sink_id,
@@ -853,6 +955,7 @@ int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id,
enum avs_peakvol_runtime_param {
AVS_PEAKVOL_VOLUME = 0,
+ AVS_PEAKVOL_MUTE = 3,
};
enum avs_audio_curve_type {
@@ -860,10 +963,18 @@ enum avs_audio_curve_type {
AVS_AUDIO_CURVE_WINDOWS_FADE = 1,
};
-int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
- struct avs_volume_cfg *vol);
int avs_ipc_peakvol_get_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
struct avs_volume_cfg **vols, size_t *num_vols);
+int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_volume_cfg *vol);
+int avs_ipc_peakvol_set_volumes(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_volume_cfg *vols, size_t num_vols);
+int avs_ipc_peakvol_get_mute(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_mute_cfg **mutes, size_t *num_mutes);
+int avs_ipc_peakvol_set_mute(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_mute_cfg *mute);
+int avs_ipc_peakvol_set_mutes(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_mute_cfg *mutes, size_t num_mutes);
#define AVS_PROBE_INST_ID 0
@@ -878,6 +989,7 @@ struct avs_probe_dma {
union avs_connector_node_id node_id;
u32 dma_buffer_size;
} __packed;
+static_assert(sizeof(struct avs_probe_dma) == 8);
enum avs_probe_type {
AVS_PROBE_TYPE_INPUT = 0,
@@ -894,6 +1006,7 @@ union avs_probe_point_id {
u32 index:6;
} id;
} __packed;
+static_assert(sizeof(union avs_probe_point_id) == 4);
enum avs_connection_purpose {
AVS_CONNECTION_PURPOSE_EXTRACT = 0,
@@ -906,6 +1019,7 @@ struct avs_probe_point_desc {
u32 purpose;
union avs_connector_node_id node_id;
} __packed;
+static_assert(sizeof(struct avs_probe_point_desc) == 12);
int avs_ipc_probe_get_dma(struct avs_dev *adev, struct avs_probe_dma **dmas, size_t *num_dmas);
int avs_ipc_probe_attach_dma(struct avs_dev *adev, struct avs_probe_dma *dmas, size_t num_dmas);
diff --git a/sound/soc/intel/avs/mtl.c b/sound/soc/intel/avs/mtl.c
new file mode 100644
index 000000000000..e7b7915b2a82
--- /dev/null
+++ b/sound/soc/intel/avs/mtl.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright(c) 2021-2025 Intel Corporation
+ *
+ * Authors: Cezary Rojewski <cezary.rojewski@intel.com>
+ * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+ */
+
+#include <sound/hdaudio_ext.h>
+#include "avs.h"
+#include "registers.h"
+#include "trace.h"
+
+#define MTL_HfDSSGBL_BASE 0x1000
+#define MTL_REG_HfDSSCS (MTL_HfDSSGBL_BASE + 0x0)
+#define MTL_HfDSSCS_SPA BIT(16)
+#define MTL_HfDSSCS_CPA BIT(24)
+
+#define MTL_DSPCS_BASE 0x178D00
+#define MTL_REG_DSPCCTL (MTL_DSPCS_BASE + 0x4)
+#define MTL_DSPCCTL_SPA BIT(0)
+#define MTL_DSPCCTL_CPA BIT(8)
+#define MTL_DSPCCTL_OSEL GENMASK(25, 24)
+#define MTL_DSPCCTL_OSEL_HOST BIT(25)
+
+#define MTL_HfINT_BASE 0x1100
+#define MTL_REG_HfINTIPPTR (MTL_HfINT_BASE + 0x8)
+#define MTL_REG_HfHIPCIE (MTL_HfINT_BASE + 0x40)
+#define MTL_HfINTIPPTR_PTR GENMASK(20, 0)
+#define MTL_HfHIPCIE_IE BIT(0)
+
+#define MTL_DWICTL_INTENL_IE BIT(0)
+#define MTL_DWICTL_FINALSTATUSL_IPC BIT(0) /* same as ADSPIS_IPC */
+
+static int avs_mtl_core_power_on(struct avs_dev *adev)
+{
+ u32 reg;
+ int ret;
+
+ /* Power up DSP domain. */
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfDSSCS, MTL_HfDSSCS_SPA, MTL_HfDSSCS_SPA);
+ trace_avs_dsp_core_op(1, AVS_MAIN_CORE_MASK, "power dsp", true);
+
+ ret = snd_hdac_adsp_readl_poll(adev, MTL_REG_HfDSSCS, reg,
+ (reg & MTL_HfDSSCS_CPA) == MTL_HfDSSCS_CPA,
+ AVS_ADSPCS_INTERVAL_US, AVS_ADSPCS_TIMEOUT_US);
+ if (ret) {
+ dev_err(adev->dev, "power on domain dsp failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Prevent power gating of DSP domain. */
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfPWRCTL, MTL_HfPWRCTL_WPDSPHPxPG,
+ MTL_HfPWRCTL_WPDSPHPxPG);
+ trace_avs_dsp_core_op(1, AVS_MAIN_CORE_MASK, "prevent dsp PG", true);
+
+ ret = snd_hdac_adsp_readl_poll(adev, MTL_REG_HfPWRSTS, reg,
+ (reg & MTL_HfPWRSTS_DSPHPxPGS) == MTL_HfPWRSTS_DSPHPxPGS,
+ AVS_ADSPCS_INTERVAL_US, AVS_ADSPCS_TIMEOUT_US);
+
+ /* Set ownership to HOST. */
+ snd_hdac_adsp_updatel(adev, MTL_REG_DSPCCTL, MTL_DSPCCTL_OSEL, MTL_DSPCCTL_OSEL_HOST);
+ return ret;
+}
+
+static int avs_mtl_core_power_off(struct avs_dev *adev)
+{
+ u32 reg;
+
+ /* Allow power gating of DSP domain. No STS polling as HOST is only one of its users. */
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfPWRCTL, MTL_HfPWRCTL_WPDSPHPxPG, 0);
+ trace_avs_dsp_core_op(0, AVS_MAIN_CORE_MASK, "allow dsp pg", false);
+
+ /* Power down DSP domain. */
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfDSSCS, MTL_HfDSSCS_SPA, 0);
+ trace_avs_dsp_core_op(0, AVS_MAIN_CORE_MASK, "power dsp", false);
+
+ return snd_hdac_adsp_readl_poll(adev, MTL_REG_HfDSSCS, reg,
+ (reg & MTL_HfDSSCS_CPA) == 0,
+ AVS_ADSPCS_INTERVAL_US, AVS_ADSPCS_TIMEOUT_US);
+}
+
+int avs_mtl_core_power(struct avs_dev *adev, u32 core_mask, bool power)
+{
+ core_mask &= AVS_MAIN_CORE_MASK;
+ if (!core_mask)
+ return 0;
+
+ if (power)
+ return avs_mtl_core_power_on(adev);
+ return avs_mtl_core_power_off(adev);
+}
+
+int avs_mtl_core_reset(struct avs_dev *adev, u32 core_mask, bool power)
+{
+ /* No logical equivalent on ACE 1.x. */
+ return 0;
+}
+
+int avs_mtl_core_stall(struct avs_dev *adev, u32 core_mask, bool stall)
+{
+ u32 value, reg;
+ int ret;
+
+ core_mask &= AVS_MAIN_CORE_MASK;
+ if (!core_mask)
+ return 0;
+
+ value = snd_hdac_adsp_readl(adev, MTL_REG_DSPCCTL);
+ trace_avs_dsp_core_op(value, core_mask, "stall", stall);
+ if (value == UINT_MAX)
+ return 0;
+
+ value = stall ? 0 : MTL_DSPCCTL_SPA;
+ snd_hdac_adsp_updatel(adev, MTL_REG_DSPCCTL, MTL_DSPCCTL_SPA, value);
+
+ value = stall ? 0 : MTL_DSPCCTL_CPA;
+ ret = snd_hdac_adsp_readl_poll(adev, MTL_REG_DSPCCTL,
+ reg, (reg & MTL_DSPCCTL_CPA) == value,
+ AVS_ADSPCS_INTERVAL_US, AVS_ADSPCS_TIMEOUT_US);
+ if (ret)
+ dev_err(adev->dev, "core_mask %d %sstall failed: %d\n",
+ core_mask, stall ? "" : "un", ret);
+ return ret;
+}
+
+static void avs_mtl_ipc_interrupt(struct avs_dev *adev)
+{
+ const struct avs_spec *spec = adev->spec;
+ u32 hipc_ack, hipc_rsp;
+
+ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,
+ AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY, 0);
+
+ hipc_ack = snd_hdac_adsp_readl(adev, spec->hipc->ack_offset);
+ hipc_rsp = snd_hdac_adsp_readl(adev, spec->hipc->rsp_offset);
+
+ /* DSP acked host's request. */
+ if (hipc_ack & spec->hipc->ack_done_mask) {
+ complete(&adev->ipc->done_completion);
+
+ /* Tell DSP it has our attention. */
+ snd_hdac_adsp_updatel(adev, spec->hipc->ack_offset, spec->hipc->ack_done_mask,
+ spec->hipc->ack_done_mask);
+ }
+
+ /* DSP sent new response to process. */
+ if (hipc_rsp & spec->hipc->rsp_busy_mask) {
+ union avs_reply_msg msg;
+
+ msg.primary = snd_hdac_adsp_readl(adev, MTL_REG_HfIPCxTDR);
+ msg.ext.val = snd_hdac_adsp_readl(adev, MTL_REG_HfIPCxTDD);
+
+ avs_dsp_process_response(adev, msg.val);
+
+ /* Tell DSP we accepted its message. */
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfIPCxTDR,
+ MTL_HfIPCxTDR_BUSY, MTL_HfIPCxTDR_BUSY);
+ /* Ack this response. */
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfIPCxTDA, MTL_HfIPCxTDA_BUSY, 0);
+ }
+
+ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,
+ AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY,
+ AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY);
+}
+
+irqreturn_t avs_mtl_dsp_interrupt(struct avs_dev *adev)
+{
+ u32 adspis = snd_hdac_adsp_readl(adev, MTL_DWICTL_REG_FINALSTATUSL);
+ irqreturn_t ret = IRQ_NONE;
+
+ if (adspis == UINT_MAX)
+ return ret;
+
+ if (adspis & MTL_DWICTL_FINALSTATUSL_IPC) {
+ avs_mtl_ipc_interrupt(adev);
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+}
+
+void avs_mtl_interrupt_control(struct avs_dev *adev, bool enable)
+{
+ if (enable) {
+ snd_hdac_adsp_updatel(adev, MTL_DWICTL_REG_INTENL, MTL_DWICTL_INTENL_IE,
+ MTL_DWICTL_INTENL_IE);
+ snd_hdac_adsp_updatew(adev, MTL_REG_HfHIPCIE, MTL_HfHIPCIE_IE, MTL_HfHIPCIE_IE);
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfIPCxCTL, AVS_ADSP_HIPCCTL_DONE,
+ AVS_ADSP_HIPCCTL_DONE);
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfIPCxCTL, AVS_ADSP_HIPCCTL_BUSY,
+ AVS_ADSP_HIPCCTL_BUSY);
+ } else {
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfIPCxCTL, AVS_ADSP_HIPCCTL_BUSY, 0);
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfIPCxCTL, AVS_ADSP_HIPCCTL_DONE, 0);
+ snd_hdac_adsp_updatew(adev, MTL_REG_HfHIPCIE, MTL_HfHIPCIE_IE, 0);
+ snd_hdac_adsp_updatel(adev, MTL_DWICTL_REG_INTENL, MTL_DWICTL_INTENL_IE, 0);
+ }
+}
diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
index e785fc2a7008..ed8f0ea0e10d 100644
--- a/sound/soc/intel/avs/path.c
+++ b/sound/soc/intel/avs/path.c
@@ -1,12 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021 Intel Corporation. All rights reserved.
+// Copyright(c) 2021 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
//
-#include <sound/intel-nhlt.h>
+#include <linux/acpi.h>
+#include <acpi/nhlt.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "avs.h"
@@ -114,157 +115,308 @@ avs_path_find_variant(struct avs_dev *adev,
return NULL;
}
-__maybe_unused
-static bool avs_dma_type_is_host(u32 dma_type)
-{
- return dma_type == AVS_DMA_HDA_HOST_OUTPUT ||
- dma_type == AVS_DMA_HDA_HOST_INPUT;
-}
+static struct acpi_nhlt_config *
+avs_nhlt_config_or_default(struct avs_dev *adev, struct avs_tplg_module *t);
-__maybe_unused
-static bool avs_dma_type_is_link(u32 dma_type)
+int avs_path_set_constraint(struct avs_dev *adev, struct avs_tplg_path_template *template,
+ struct snd_pcm_hw_constraint_list *rate_list,
+ struct snd_pcm_hw_constraint_list *channels_list,
+ struct snd_pcm_hw_constraint_list *sample_bits_list)
{
- return !avs_dma_type_is_host(dma_type);
-}
+ struct avs_tplg_path *path_template;
+ unsigned int *rlist, *clist, *slist;
+ size_t i;
+
+ i = 0;
+ list_for_each_entry(path_template, &template->path_list, node)
+ i++;
+
+ rlist = kcalloc(i, sizeof(*rlist), GFP_KERNEL);
+ clist = kcalloc(i, sizeof(*clist), GFP_KERNEL);
+ slist = kcalloc(i, sizeof(*slist), GFP_KERNEL);
+
+ i = 0;
+ list_for_each_entry(path_template, &template->path_list, node) {
+ struct avs_tplg_pipeline *pipeline_template;
+
+ list_for_each_entry(pipeline_template, &path_template->ppl_list, node) {
+ struct avs_tplg_module *module_template;
+
+ list_for_each_entry(module_template, &pipeline_template->mod_list, node) {
+ const guid_t *type = &module_template->cfg_ext->type;
+ struct acpi_nhlt_config *blob;
+
+ if (!guid_equal(type, &AVS_COPIER_MOD_UUID) &&
+ !guid_equal(type, &AVS_WOVHOSTM_MOD_UUID))
+ continue;
+
+ switch (module_template->cfg_ext->copier.dma_type) {
+ case AVS_DMA_DMIC_LINK_INPUT:
+ case AVS_DMA_I2S_LINK_OUTPUT:
+ case AVS_DMA_I2S_LINK_INPUT:
+ break;
+ default:
+ continue;
+ }
+
+ blob = avs_nhlt_config_or_default(adev, module_template);
+ if (IS_ERR(blob))
+ continue;
+
+ rlist[i] = path_template->fe_fmt->sampling_freq;
+ clist[i] = path_template->fe_fmt->num_channels;
+ slist[i] = path_template->fe_fmt->bit_depth;
+ i++;
+ }
+ }
+ }
-__maybe_unused
-static bool avs_dma_type_is_output(u32 dma_type)
-{
- return dma_type == AVS_DMA_HDA_HOST_OUTPUT ||
- dma_type == AVS_DMA_HDA_LINK_OUTPUT ||
- dma_type == AVS_DMA_I2S_LINK_OUTPUT;
+ if (i) {
+ rate_list->count = i;
+ rate_list->list = rlist;
+ channels_list->count = i;
+ channels_list->list = clist;
+ sample_bits_list->count = i;
+ sample_bits_list->list = slist;
+ } else {
+ kfree(rlist);
+ kfree(clist);
+ kfree(slist);
+ }
+
+ return i;
}
-__maybe_unused
-static bool avs_dma_type_is_input(u32 dma_type)
+static void avs_init_node_id(union avs_connector_node_id *node_id,
+ struct avs_tplg_modcfg_ext *te, u32 dma_id)
{
- return !avs_dma_type_is_output(dma_type);
+ node_id->val = 0;
+ node_id->dma_type = te->copier.dma_type;
+
+ switch (node_id->dma_type) {
+ case AVS_DMA_DMIC_LINK_INPUT:
+ case AVS_DMA_I2S_LINK_OUTPUT:
+ case AVS_DMA_I2S_LINK_INPUT:
+ /* Gateway's virtual index is statically assigned in the topology. */
+ node_id->vindex = te->copier.vindex.val;
+ break;
+
+ case AVS_DMA_HDA_HOST_OUTPUT:
+ case AVS_DMA_HDA_HOST_INPUT:
+ /* Gateway's virtual index is dynamically assigned with DMA ID */
+ node_id->vindex = dma_id;
+ break;
+
+ case AVS_DMA_HDA_LINK_OUTPUT:
+ case AVS_DMA_HDA_LINK_INPUT:
+ node_id->vindex = te->copier.vindex.val | dma_id;
+ break;
+
+ default:
+ *node_id = INVALID_NODE_ID;
+ break;
+ }
}
-static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
-{
- struct nhlt_acpi_table *nhlt = adev->nhlt;
- struct avs_tplg_module *t = mod->template;
- struct avs_copier_cfg *cfg;
- struct nhlt_specific_cfg *ep_blob;
- union avs_connector_node_id node_id = {0};
- size_t cfg_size, data_size = 0;
- void *data = NULL;
- u32 dma_type;
- int ret;
+/* Every BLOB contains at least gateway attributes. */
+static struct acpi_nhlt_config *default_blob = (struct acpi_nhlt_config *)&(u32[2]) {4};
- dma_type = t->cfg_ext->copier.dma_type;
- node_id.dma_type = dma_type;
+static struct acpi_nhlt_config *
+avs_nhlt_config_or_default(struct avs_dev *adev, struct avs_tplg_module *t)
+{
+ struct acpi_nhlt_format_config *fmtcfg;
+ struct avs_tplg_modcfg_ext *te;
+ struct avs_audio_format *fmt;
+ int link_type, dev_type;
+ int bus_id, dir;
- switch (dma_type) {
- struct avs_audio_format *fmt;
- int direction;
+ te = t->cfg_ext;
+ switch (te->copier.dma_type) {
case AVS_DMA_I2S_LINK_OUTPUT:
- case AVS_DMA_I2S_LINK_INPUT:
- if (avs_dma_type_is_input(dma_type))
- direction = SNDRV_PCM_STREAM_CAPTURE;
- else
- direction = SNDRV_PCM_STREAM_PLAYBACK;
-
- if (t->cfg_ext->copier.blob_fmt)
- fmt = t->cfg_ext->copier.blob_fmt;
- else if (direction == SNDRV_PCM_STREAM_CAPTURE)
- fmt = t->in_fmt;
- else
- fmt = t->cfg_ext->copier.out_fmt;
-
- ep_blob = intel_nhlt_get_endpoint_blob(adev->dev,
- nhlt, t->cfg_ext->copier.vindex.i2s.instance,
- NHLT_LINK_SSP, fmt->valid_bit_depth, fmt->bit_depth,
- fmt->num_channels, fmt->sampling_freq, direction,
- NHLT_DEVICE_I2S);
- if (!ep_blob) {
- dev_err(adev->dev, "no I2S ep_blob found\n");
- return -ENOENT;
- }
-
- data = ep_blob->caps;
- data_size = ep_blob->size;
- /* I2S gateway's vindex is statically assigned in topology */
- node_id.vindex = t->cfg_ext->copier.vindex.val;
+ link_type = ACPI_NHLT_LINKTYPE_SSP;
+ dev_type = ACPI_NHLT_DEVICETYPE_CODEC;
+ bus_id = te->copier.vindex.i2s.instance;
+ dir = SNDRV_PCM_STREAM_PLAYBACK;
+ fmt = te->copier.out_fmt;
+ break;
+ case AVS_DMA_I2S_LINK_INPUT:
+ link_type = ACPI_NHLT_LINKTYPE_SSP;
+ dev_type = ACPI_NHLT_DEVICETYPE_CODEC;
+ bus_id = te->copier.vindex.i2s.instance;
+ dir = SNDRV_PCM_STREAM_CAPTURE;
+ fmt = t->in_fmt;
break;
case AVS_DMA_DMIC_LINK_INPUT:
- direction = SNDRV_PCM_STREAM_CAPTURE;
-
- if (t->cfg_ext->copier.blob_fmt)
- fmt = t->cfg_ext->copier.blob_fmt;
- else
- fmt = t->in_fmt;
-
- ep_blob = intel_nhlt_get_endpoint_blob(adev->dev, nhlt, 0,
- NHLT_LINK_DMIC, fmt->valid_bit_depth,
- fmt->bit_depth, fmt->num_channels,
- fmt->sampling_freq, direction, NHLT_DEVICE_DMIC);
- if (!ep_blob) {
- dev_err(adev->dev, "no DMIC ep_blob found\n");
- return -ENOENT;
- }
+ link_type = ACPI_NHLT_LINKTYPE_PDM;
+ dev_type = -1; /* ignored */
+ bus_id = 0;
+ dir = SNDRV_PCM_STREAM_CAPTURE;
+ fmt = t->in_fmt;
+ break;
- data = ep_blob->caps;
- data_size = ep_blob->size;
- /* DMIC gateway's vindex is statically assigned in topology */
- node_id.vindex = t->cfg_ext->copier.vindex.val;
+ default:
+ return default_blob;
+ }
- break;
+ /* Override format selection if necessary. */
+ if (te->copier.blob_fmt)
+ fmt = te->copier.blob_fmt;
+
+ fmtcfg = acpi_nhlt_find_fmtcfg(link_type, dev_type, dir, bus_id,
+ fmt->num_channels, fmt->sampling_freq, fmt->valid_bit_depth,
+ fmt->bit_depth);
+ if (!fmtcfg) {
+ dev_warn(adev->dev, "Endpoint format configuration not found.\n");
+ return ERR_PTR(-ENOENT);
+ }
+
+ if (fmtcfg->config.capabilities_size < default_blob->capabilities_size)
+ return ERR_PTR(-ETOOSMALL);
+ /* The firmware expects the payload to be DWORD-aligned. */
+ if (fmtcfg->config.capabilities_size % sizeof(u32))
+ return ERR_PTR(-EINVAL);
+
+ return &fmtcfg->config;
+}
+
+static int avs_append_dma_cfg(struct avs_dev *adev, struct avs_copier_gtw_cfg *gtw,
+ struct avs_tplg_module *t, u32 dma_id, size_t *cfg_size)
+{
+ u32 dma_type = t->cfg_ext->copier.dma_type;
+ struct avs_dma_cfg *dma;
+ struct avs_tlv *tlv;
+ size_t tlv_size;
+
+ if (!avs_platattr_test(adev, ALTHDA))
+ return 0;
+ switch (dma_type) {
case AVS_DMA_HDA_HOST_OUTPUT:
case AVS_DMA_HDA_HOST_INPUT:
- /* HOST gateway's vindex is dynamically assigned with DMA id */
- node_id.vindex = mod->owner->owner->dma_id;
- break;
-
case AVS_DMA_HDA_LINK_OUTPUT:
case AVS_DMA_HDA_LINK_INPUT:
- node_id.vindex = t->cfg_ext->copier.vindex.val |
- mod->owner->owner->dma_id;
- break;
-
- case INVALID_OBJECT_ID:
+ return 0;
default:
- node_id = INVALID_NODE_ID;
break;
}
- cfg_size = sizeof(*cfg) + data_size;
- /* Every config-BLOB contains gateway attributes. */
- if (data_size)
- cfg_size -= sizeof(cfg->gtw_cfg.config.attrs);
- if (cfg_size > AVS_MAILBOX_SIZE)
- return -EINVAL;
+ tlv_size = sizeof(*tlv) + sizeof(*dma);
+ if (*cfg_size + tlv_size > AVS_MAILBOX_SIZE)
+ return -E2BIG;
+
+ /* DMA config is a TLV tailing the existing payload. */
+ tlv = (struct avs_tlv *)&gtw->config.blob[gtw->config_length];
+ tlv->type = AVS_GTW_DMA_CONFIG_ID;
+ tlv->length = sizeof(*dma);
+
+ dma = (struct avs_dma_cfg *)tlv->value;
+ memset(dma, 0, sizeof(*dma));
+ dma->dma_method = AVS_DMA_METHOD_HDA;
+ dma->pre_allocated = true;
+ dma->dma_channel_id = dma_id;
+ dma->stream_id = dma_id + 1;
+
+ gtw->config_length += tlv_size / sizeof(u32);
+ *cfg_size += tlv_size;
+
+ return 0;
+}
+
+static int avs_fill_gtw_config(struct avs_dev *adev, struct avs_copier_gtw_cfg *gtw,
+ struct avs_tplg_module *t, u32 dma_id, size_t *cfg_size)
+{
+ struct acpi_nhlt_config *blob;
+ size_t gtw_size;
+
+ blob = avs_nhlt_config_or_default(adev, t);
+ if (IS_ERR(blob))
+ return PTR_ERR(blob);
+ gtw_size = blob->capabilities_size;
+ if (*cfg_size + gtw_size > AVS_MAILBOX_SIZE)
+ return -E2BIG;
+
+ gtw->config_length = gtw_size / sizeof(u32);
+ memcpy(gtw->config.blob, blob->capabilities, blob->capabilities_size);
+ *cfg_size += gtw_size;
+
+ return avs_append_dma_cfg(adev, gtw, t, dma_id, cfg_size);
+}
+
+static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
+{
+ struct avs_tplg_module *t = mod->template;
+ struct avs_tplg_modcfg_ext *te;
+ struct avs_copier_cfg *cfg;
+ size_t cfg_size;
+ u32 dma_id;
+ int ret;
+
+ te = t->cfg_ext;
cfg = adev->modcfg_buf;
- memset(cfg, 0, cfg_size);
+ dma_id = mod->owner->owner->dma_id;
+ cfg_size = offsetof(struct avs_copier_cfg, gtw_cfg.config);
+
+ ret = avs_fill_gtw_config(adev, &cfg->gtw_cfg, t, dma_id, &cfg_size);
+ if (ret)
+ return ret;
+
cfg->base.cpc = t->cfg_base->cpc;
cfg->base.ibs = t->cfg_base->ibs;
cfg->base.obs = t->cfg_base->obs;
cfg->base.is_pages = t->cfg_base->is_pages;
cfg->base.audio_fmt = *t->in_fmt;
- cfg->out_fmt = *t->cfg_ext->copier.out_fmt;
- cfg->feature_mask = t->cfg_ext->copier.feature_mask;
- cfg->gtw_cfg.node_id = node_id;
- cfg->gtw_cfg.dma_buffer_size = t->cfg_ext->copier.dma_buffer_size;
- /* config_length in DWORDs */
- cfg->gtw_cfg.config_length = DIV_ROUND_UP(data_size, 4);
- if (data)
- memcpy(&cfg->gtw_cfg.config, data, data_size);
+ cfg->out_fmt = *te->copier.out_fmt;
+ cfg->feature_mask = te->copier.feature_mask;
+ avs_init_node_id(&cfg->gtw_cfg.node_id, te, dma_id);
+ cfg->gtw_cfg.dma_buffer_size = te->copier.dma_buffer_size;
+ mod->gtw_attrs = cfg->gtw_cfg.config.attrs;
+ ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id,
+ t->domain, cfg, cfg_size, &mod->instance_id);
+ return ret;
+}
+
+static int avs_whm_create(struct avs_dev *adev, struct avs_path_module *mod)
+{
+ struct avs_tplg_module *t = mod->template;
+ struct avs_tplg_modcfg_ext *te;
+ struct avs_whm_cfg *cfg;
+ size_t cfg_size;
+ u32 dma_id;
+ int ret;
+
+ te = t->cfg_ext;
+ cfg = adev->modcfg_buf;
+ dma_id = mod->owner->owner->dma_id;
+ cfg_size = offsetof(struct avs_whm_cfg, gtw_cfg.config);
+
+ ret = avs_fill_gtw_config(adev, &cfg->gtw_cfg, t, dma_id, &cfg_size);
+ if (ret)
+ return ret;
+
+ cfg->base.cpc = t->cfg_base->cpc;
+ cfg->base.ibs = t->cfg_base->ibs;
+ cfg->base.obs = t->cfg_base->obs;
+ cfg->base.is_pages = t->cfg_base->is_pages;
+ cfg->base.audio_fmt = *t->in_fmt;
+ cfg->ref_fmt = *te->whm.ref_fmt;
+ cfg->out_fmt = *te->whm.out_fmt;
+ cfg->wake_tick_period = te->whm.wake_tick_period;
+ avs_init_node_id(&cfg->gtw_cfg.node_id, te, dma_id);
+ cfg->gtw_cfg.dma_buffer_size = te->whm.dma_buffer_size;
mod->gtw_attrs = cfg->gtw_cfg.config.attrs;
- ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id,
- t->core_id, t->domain, cfg, cfg_size,
- &mod->instance_id);
+ ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id,
+ t->domain, cfg, cfg_size, &mod->instance_id);
return ret;
}
-static struct avs_control_data *avs_get_module_control(struct avs_path_module *mod)
+static struct soc_mixer_control *avs_get_module_control(struct avs_path_module *mod,
+ const char *name)
{
struct avs_tplg_module *t = mod->template;
struct avs_tplg_path_template *path_tmpl;
@@ -280,27 +432,93 @@ static struct avs_control_data *avs_get_module_control(struct avs_path_module *m
mc = (struct soc_mixer_control *)w->kcontrols[i]->private_value;
ctl_data = (struct avs_control_data *)mc->dobj.private;
- if (ctl_data->id == t->ctl_id)
- return ctl_data;
+ if (ctl_data->id == t->ctl_id && strstr(w->kcontrols[i]->id.name, name))
+ return mc;
}
return NULL;
}
+int avs_peakvol_set_volume(struct avs_dev *adev, struct avs_path_module *mod,
+ struct soc_mixer_control *mc, long *input)
+{
+ struct avs_volume_cfg vols[SND_SOC_TPLG_MAX_CHAN] = {{0}};
+ struct avs_control_data *ctl_data;
+ struct avs_tplg_module *t;
+ int ret, i;
+
+ ctl_data = mc->dobj.private;
+ t = mod->template;
+ if (!input)
+ input = ctl_data->values;
+
+ if (mc->num_channels) {
+ for (i = 0; i < mc->num_channels; i++) {
+ vols[i].channel_id = i;
+ vols[i].target_volume = input[i];
+ vols[i].curve_type = t->cfg_ext->peakvol.curve_type;
+ vols[i].curve_duration = t->cfg_ext->peakvol.curve_duration;
+ }
+
+ ret = avs_ipc_peakvol_set_volumes(adev, mod->module_id, mod->instance_id, vols,
+ mc->num_channels);
+ return AVS_IPC_RET(ret);
+ }
+
+ /* Target all channels if no individual selected. */
+ vols[0].channel_id = AVS_ALL_CHANNELS_MASK;
+ vols[0].target_volume = input[0];
+ vols[0].curve_type = t->cfg_ext->peakvol.curve_type;
+ vols[0].curve_duration = t->cfg_ext->peakvol.curve_duration;
+
+ ret = avs_ipc_peakvol_set_volume(adev, mod->module_id, mod->instance_id, &vols[0]);
+ return AVS_IPC_RET(ret);
+}
+
+int avs_peakvol_set_mute(struct avs_dev *adev, struct avs_path_module *mod,
+ struct soc_mixer_control *mc, long *input)
+{
+ struct avs_mute_cfg mutes[SND_SOC_TPLG_MAX_CHAN] = {{0}};
+ struct avs_control_data *ctl_data;
+ struct avs_tplg_module *t;
+ int ret, i;
+
+ ctl_data = mc->dobj.private;
+ t = mod->template;
+ if (!input)
+ input = ctl_data->values;
+
+ if (mc->num_channels) {
+ for (i = 0; i < mc->num_channels; i++) {
+ mutes[i].channel_id = i;
+ mutes[i].mute = !input[i];
+ mutes[i].curve_type = t->cfg_ext->peakvol.curve_type;
+ mutes[i].curve_duration = t->cfg_ext->peakvol.curve_duration;
+ }
+
+ ret = avs_ipc_peakvol_set_mutes(adev, mod->module_id, mod->instance_id, mutes,
+ mc->num_channels);
+ return AVS_IPC_RET(ret);
+ }
+
+ /* Target all channels if no individual selected. */
+ mutes[0].channel_id = AVS_ALL_CHANNELS_MASK;
+ mutes[0].mute = !input[0];
+ mutes[0].curve_type = t->cfg_ext->peakvol.curve_type;
+ mutes[0].curve_duration = t->cfg_ext->peakvol.curve_duration;
+
+ ret = avs_ipc_peakvol_set_mute(adev, mod->module_id, mod->instance_id, &mutes[0]);
+ return AVS_IPC_RET(ret);
+}
+
static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod)
{
struct avs_tplg_module *t = mod->template;
- struct avs_control_data *ctl_data;
+ struct soc_mixer_control *mc;
struct avs_peakvol_cfg *cfg;
- int volume = S32_MAX;
size_t cfg_size;
int ret;
- ctl_data = avs_get_module_control(mod);
- if (ctl_data)
- volume = ctl_data->volume;
-
- /* As 2+ channels controls are unsupported, have a single block for all channels. */
cfg_size = struct_size(cfg, vols, 1);
if (cfg_size > AVS_MAILBOX_SIZE)
return -EINVAL;
@@ -312,15 +530,28 @@ static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod)
cfg->base.obs = t->cfg_base->obs;
cfg->base.is_pages = t->cfg_base->is_pages;
cfg->base.audio_fmt = *t->in_fmt;
- cfg->vols[0].target_volume = volume;
cfg->vols[0].channel_id = AVS_ALL_CHANNELS_MASK;
- cfg->vols[0].curve_type = AVS_AUDIO_CURVE_NONE;
- cfg->vols[0].curve_duration = 0;
+ cfg->vols[0].target_volume = S32_MAX;
+ cfg->vols[0].curve_type = t->cfg_ext->peakvol.curve_type;
+ cfg->vols[0].curve_duration = t->cfg_ext->peakvol.curve_duration;
ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id,
t->domain, cfg, cfg_size, &mod->instance_id);
+ if (ret)
+ return ret;
- return ret;
+ /* Now configure both VOLUME and MUTE parameters. */
+ mc = avs_get_module_control(mod, "Volume");
+ if (mc) {
+ ret = avs_peakvol_set_volume(adev, mod, mc, NULL);
+ if (ret)
+ return ret;
+ }
+
+ mc = avs_get_module_control(mod, "Switch");
+ if (mc)
+ return avs_peakvol_set_mute(adev, mod, mc, NULL);
+ return 0;
}
static int avs_updown_mix_create(struct avs_dev *adev, struct avs_path_module *mod)
@@ -336,7 +567,7 @@ static int avs_updown_mix_create(struct avs_dev *adev, struct avs_path_module *m
cfg.base.audio_fmt = *t->in_fmt;
cfg.out_channel_config = t->cfg_ext->updown_mix.out_channel_config;
cfg.coefficients_select = t->cfg_ext->updown_mix.coefficients_select;
- for (i = 0; i < AVS_CHANNELS_MAX; i++)
+ for (i = 0; i < AVS_COEFF_CHANNELS_MAX; i++)
cfg.coefficients[i] = t->cfg_ext->updown_mix.coefficients[i];
cfg.channel_map = t->cfg_ext->updown_mix.channel_map;
@@ -367,6 +598,7 @@ static int avs_asrc_create(struct avs_dev *adev, struct avs_path_module *mod)
struct avs_tplg_module *t = mod->template;
struct avs_asrc_cfg cfg;
+ memset(&cfg, 0, sizeof(cfg));
cfg.base.cpc = t->cfg_base->cpc;
cfg.base.ibs = t->cfg_base->ibs;
cfg.base.obs = t->cfg_base->obs;
@@ -534,6 +766,7 @@ static struct avs_module_create avs_module_create[] = {
{ &AVS_ASRC_MOD_UUID, avs_asrc_create },
{ &AVS_INTELWOV_MOD_UUID, avs_wov_create },
{ &AVS_PROBE_MOD_UUID, avs_probe_create },
+ { &AVS_WOVHOSTM_MOD_UUID, avs_whm_create },
};
static int avs_path_module_type_create(struct avs_dev *adev, struct avs_path_module *mod)
@@ -710,8 +943,6 @@ static int avs_path_pipeline_arm(struct avs_dev *adev,
/* bind current module to next module on list */
source = mod;
sink = list_next_entry(mod, node);
- if (!source || !sink)
- return -EINVAL;
ret = avs_ipc_bind(adev, source->module_id, source->instance_id,
sink->module_id, sink->instance_id, 0, 0);
diff --git a/sound/soc/intel/avs/path.h b/sound/soc/intel/avs/path.h
index 657f7b093e80..c65ed84aa853 100644
--- a/sound/soc/intel/avs/path.h
+++ b/sound/soc/intel/avs/path.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright(c) 2021 Intel Corporation. All rights reserved.
+ * Copyright(c) 2021 Intel Corporation
*
* Authors: Cezary Rojewski <cezary.rojewski@intel.com>
* Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -69,4 +69,14 @@ int avs_path_reset(struct avs_path *path);
int avs_path_pause(struct avs_path *path);
int avs_path_run(struct avs_path *path, int trigger);
+int avs_path_set_constraint(struct avs_dev *adev, struct avs_tplg_path_template *template,
+ struct snd_pcm_hw_constraint_list *rate_list,
+ struct snd_pcm_hw_constraint_list *channels_list,
+ struct snd_pcm_hw_constraint_list *sample_bits_list);
+
+int avs_peakvol_set_volume(struct avs_dev *adev, struct avs_path_module *mod,
+ struct soc_mixer_control *mc, long *input);
+int avs_peakvol_set_mute(struct avs_dev *adev, struct avs_path_module *mod,
+ struct soc_mixer_control *mc, long *input);
+
#endif
diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index 2cafbc392cdb..405cfc1ab0cb 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -16,20 +16,28 @@
#include <sound/soc-component.h>
#include "avs.h"
#include "path.h"
+#include "pcm.h"
#include "topology.h"
+#include "utils.h"
#include "../../codecs/hda.h"
struct avs_dma_data {
struct avs_tplg_path_template *template;
struct avs_path *path;
- /*
- * link stream is stored within substream's runtime
- * private_data to fulfill the needs of codec BE path
- *
- * host stream assigned
- */
- struct hdac_ext_stream *host_stream;
+ struct avs_dev *adev;
+ /* LINK-stream utilized in BE operations while HOST in FE ones. */
+ union {
+ struct hdac_ext_stream *link_stream;
+ struct hdac_ext_stream *host_stream;
+ };
+
+ struct snd_pcm_hw_constraint_list rate_list;
+ struct snd_pcm_hw_constraint_list channels_list;
+ struct snd_pcm_hw_constraint_list sample_bits_list;
+
+ struct work_struct period_elapsed_work;
+ struct hdac_ext_link *link;
struct snd_pcm_substream *substream;
};
@@ -56,15 +64,69 @@ avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction)
return dw->priv;
}
-static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe,
- const struct snd_soc_dai_ops *ops)
+static void avs_period_elapsed_work(struct work_struct *work)
+{
+ struct avs_dma_data *data = container_of(work, struct avs_dma_data, period_elapsed_work);
+
+ snd_pcm_period_elapsed(data->substream);
+}
+
+void avs_period_elapsed(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
+
+ schedule_work(&data->period_elapsed_work);
+}
+
+static int hw_rule_param_size(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
+static int avs_hw_constraints_init(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct avs_dev *adev = to_avs_dev(dai->dev);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_pcm_hw_constraint_list *r, *c, *s;
struct avs_tplg_path_template *template;
struct avs_dma_data *data;
+ int ret;
+
+ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0)
+ return ret;
+
+ data = snd_soc_dai_get_dma_data(dai, substream);
+ r = &(data->rate_list);
+ c = &(data->channels_list);
+ s = &(data->sample_bits_list);
+
+ template = avs_dai_find_path_template(dai, !rtd->dai_link->no_pcm, substream->stream);
+ ret = avs_path_set_constraint(data->adev, template, r, c, s);
+ if (ret <= 0)
+ return ret;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, r);
+ if (ret < 0)
+ return ret;
- template = avs_dai_find_path_template(dai, is_fe, substream->stream);
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, c);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, s);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct avs_dev *adev = to_avs_dev(dai->component->dev);
+ struct avs_tplg_path_template *template;
+ struct avs_dma_data *data;
+
+ template = avs_dai_find_path_template(dai, !rtd->dai_link->no_pcm, substream->stream);
if (!template) {
dev_err(dai->dev, "no %s path for dai %s, invalid tplg?\n",
snd_pcm_stream_str(substream), dai->name);
@@ -77,12 +139,32 @@ static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_d
data->substream = substream;
data->template = template;
+ data->adev = adev;
+ INIT_WORK(&data->period_elapsed_work, avs_period_elapsed_work);
snd_soc_dai_set_dma_data(dai, substream, data);
if (rtd->dai_link->ignore_suspend)
adev->num_lp_paths++;
- return 0;
+ return avs_hw_constraints_init(substream, dai);
+}
+
+static void avs_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct avs_dma_data *data;
+
+ data = snd_soc_dai_get_dma_data(dai, substream);
+
+ if (rtd->dai_link->ignore_suspend)
+ data->adev->num_lp_paths--;
+
+ kfree(data->rate_list.list);
+ kfree(data->channels_list.list);
+ kfree(data->sample_bits_list.list);
+
+ snd_soc_dai_set_dma_data(dai, substream, NULL);
+ kfree(data);
}
static int avs_dai_hw_params(struct snd_pcm_substream *substream,
@@ -92,7 +174,6 @@ static int avs_dai_hw_params(struct snd_pcm_substream *substream,
{
struct avs_dma_data *data;
struct avs_path *path;
- struct avs_dev *adev = to_avs_dev(dai->dev);
int ret;
data = snd_soc_dai_get_dma_data(dai, substream);
@@ -109,7 +190,7 @@ static int avs_dai_hw_params(struct snd_pcm_substream *substream,
params_rate(be_hw_params), params_channels(be_hw_params),
params_width(be_hw_params), params_physical_width(be_hw_params));
- path = avs_path_create(adev, dma_id, data->template, fe_hw_params, be_hw_params);
+ path = avs_path_create(data->adev, dma_id, data->template, fe_hw_params, be_hw_params);
if (IS_ERR(path)) {
ret = PTR_ERR(path);
dev_err(dai->dev, "create path failed: %d\n", ret);
@@ -129,6 +210,7 @@ static int avs_dai_be_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dpcm *dpcm;
be = snd_soc_substream_to_rtd(substream);
+ /* dpcm_fe_dai_open() guarantees the list is not empty at this point. */
for_each_dpcm_fe(be, substream->stream, dpcm) {
fe = dpcm->fe;
fe_hw_params = &fe->dpcm[substream->stream].hw_params;
@@ -137,8 +219,7 @@ static int avs_dai_be_hw_params(struct snd_pcm_substream *substream,
return avs_dai_hw_params(substream, fe_hw_params, be_hw_params, dai, dma_id);
}
-static int avs_dai_prepare(struct avs_dev *adev, struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
+static int avs_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
struct avs_dma_data *data;
int ret;
@@ -159,28 +240,6 @@ static int avs_dai_prepare(struct avs_dev *adev, struct snd_pcm_substream *subst
return ret;
}
-static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops;
-
-static int avs_dai_nonhda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
-{
- return avs_dai_startup(substream, dai, false, &avs_dai_nonhda_be_ops);
-}
-
-static void avs_dai_nonhda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct avs_dev *adev = to_avs_dev(dai->dev);
- struct avs_dma_data *data;
-
- if (rtd->dai_link->ignore_suspend)
- adev->num_lp_paths--;
-
- data = snd_soc_dai_get_dma_data(dai, substream);
-
- snd_soc_dai_set_dma_data(dai, substream, NULL);
- kfree(data);
-}
-
static int avs_dai_nonhda_be_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
{
@@ -209,11 +268,6 @@ static int avs_dai_nonhda_be_hw_free(struct snd_pcm_substream *substream, struct
return 0;
}
-static int avs_dai_nonhda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
-{
- return avs_dai_prepare(to_avs_dev(dai->dev), substream, dai);
-}
-
static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
@@ -265,108 +319,165 @@ static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cm
}
static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = {
- .startup = avs_dai_nonhda_be_startup,
- .shutdown = avs_dai_nonhda_be_shutdown,
+ .startup = avs_dai_startup,
+ .shutdown = avs_dai_shutdown,
.hw_params = avs_dai_nonhda_be_hw_params,
.hw_free = avs_dai_nonhda_be_hw_free,
- .prepare = avs_dai_nonhda_be_prepare,
+ .prepare = avs_dai_prepare,
.trigger = avs_dai_nonhda_be_trigger,
};
-static const struct snd_soc_dai_ops avs_dai_hda_be_ops;
+static int __avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai,
+ struct hdac_ext_link *link)
+{
+ struct hdac_ext_stream *link_stream;
+ struct avs_dma_data *data;
+ int ret;
+
+ ret = avs_dai_startup(substream, dai);
+ if (ret)
+ return ret;
+
+ data = snd_soc_dai_get_dma_data(dai, substream);
+ link_stream = snd_hdac_ext_stream_assign(&data->adev->base.core, substream,
+ HDAC_EXT_STREAM_TYPE_LINK);
+ if (!link_stream) {
+ avs_dai_shutdown(substream, dai);
+ return -EBUSY;
+ }
+
+ data->link_stream = link_stream;
+ data->link = link;
+ return 0;
+}
static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
- return avs_dai_startup(substream, dai, false, &avs_dai_hda_be_ops);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct hdac_ext_link *link;
+ struct avs_dma_data *data;
+ struct hda_codec *codec;
+ int ret;
+
+ codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
+
+ link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr);
+ if (!link)
+ return -EINVAL;
+
+ ret = __avs_dai_hda_be_startup(substream, dai, link);
+ if (!ret) {
+ data = snd_soc_dai_get_dma_data(dai, substream);
+ substream->runtime->private_data = data->link_stream;
+ }
+
+ return ret;
+}
+
+static int avs_dai_i2shda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ struct avs_dev *adev = to_avs_dev(dai->component->dev);
+ struct hdac_ext_link *link;
+
+ link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core, AZX_REG_ML_LEPTR_ID_INTEL_SSP);
+ if (!link)
+ return -EINVAL;
+ return __avs_dai_hda_be_startup(substream, dai, link);
+}
+
+static int avs_dai_dmichda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ struct avs_dev *adev = to_avs_dev(dai->component->dev);
+ struct hdac_ext_link *link;
+
+ link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core, AZX_REG_ML_LEPTR_ID_INTEL_DMIC);
+ if (!link)
+ return -EINVAL;
+ return __avs_dai_hda_be_startup(substream, dai, link);
}
static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
- return avs_dai_nonhda_be_shutdown(substream, dai);
+ struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
+
+ snd_hdac_ext_stream_release(data->link_stream, HDAC_EXT_STREAM_TYPE_LINK);
+ substream->runtime->private_data = NULL;
+ avs_dai_shutdown(substream, dai);
+}
+
+static void avs_dai_althda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+ struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
+
+ snd_hdac_ext_stream_release(data->link_stream, HDAC_EXT_STREAM_TYPE_LINK);
+ avs_dai_shutdown(substream, dai);
}
static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
{
struct avs_dma_data *data;
- struct hdac_ext_stream *link_stream;
data = snd_soc_dai_get_dma_data(dai, substream);
if (data->path)
return 0;
- link_stream = substream->runtime->private_data;
-
return avs_dai_be_hw_params(substream, hw_params, dai,
- hdac_stream(link_stream)->stream_tag - 1);
+ hdac_stream(data->link_stream)->stream_tag - 1);
}
static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
- struct avs_dma_data *data;
- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct hdac_ext_stream *link_stream;
- struct hdac_ext_link *link;
- struct hda_codec *codec;
-
- dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
+ struct avs_dma_data *data;
data = snd_soc_dai_get_dma_data(dai, substream);
if (!data->path)
return 0;
- link_stream = substream->runtime->private_data;
+ link_stream = data->link_stream;
link_stream->link_prepared = false;
avs_path_free(data->path);
data->path = NULL;
/* clear link <-> stream mapping */
- codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
- link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr);
- if (!link)
- return -EINVAL;
-
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- snd_hdac_ext_bus_link_clear_stream_id(link, hdac_stream(link_stream)->stream_tag);
+ snd_hdac_ext_bus_link_clear_stream_id(data->link,
+ hdac_stream(link_stream)->stream_tag);
return 0;
}
static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_stream *stream_info;
+ const struct snd_soc_pcm_stream *stream_info;
struct hdac_ext_stream *link_stream;
- struct hdac_ext_link *link;
- struct hda_codec *codec;
- struct hdac_bus *bus;
+ struct avs_dma_data *data;
unsigned int format_val;
unsigned int bits;
int ret;
- link_stream = runtime->private_data;
+ data = snd_soc_dai_get_dma_data(dai, substream);
+ link_stream = data->link_stream;
+
if (link_stream->link_prepared)
return 0;
- codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
- bus = &codec->bus->core;
stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
stream_info->sig_bits);
format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
+ snd_hdac_ext_stream_decouple(&data->adev->base.core, link_stream, true);
snd_hdac_ext_stream_reset(link_stream);
snd_hdac_ext_stream_setup(link_stream, format_val);
- link = snd_hdac_ext_bus_get_hlink_by_addr(bus, codec->core.addr);
- if (!link)
- return -EINVAL;
-
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- snd_hdac_ext_bus_link_set_stream_id(link, hdac_stream(link_stream)->stream_tag);
+ snd_hdac_ext_bus_link_set_stream_id(data->link,
+ hdac_stream(link_stream)->stream_tag);
- ret = avs_dai_prepare(to_avs_dev(dai->dev), substream, dai);
+ ret = avs_dai_prepare(substream, dai);
if (ret)
return ret;
@@ -378,14 +489,12 @@ static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct hdac_ext_stream *link_stream;
struct avs_dma_data *data;
int ret = 0;
dev_dbg(dai->dev, "entry %s cmd=%d\n", __func__, cmd);
data = snd_soc_dai_get_dma_data(dai, substream);
- link_stream = substream->runtime->private_data;
switch (cmd) {
case SNDRV_PCM_TRIGGER_RESUME:
@@ -394,7 +503,7 @@ static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
fallthrough;
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- snd_hdac_ext_stream_start(link_stream);
+ snd_hdac_ext_stream_start(data->link_stream);
ret = avs_path_pause(data->path);
if (ret < 0) {
@@ -417,7 +526,7 @@ static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
if (ret < 0)
dev_err(dai->dev, "pause BE path failed: %d\n", ret);
- snd_hdac_ext_stream_clear(link_stream);
+ snd_hdac_ext_stream_clear(data->link_stream);
ret = avs_path_reset(data->path);
if (ret < 0)
@@ -441,82 +550,110 @@ static const struct snd_soc_dai_ops avs_dai_hda_be_ops = {
.trigger = avs_dai_hda_be_trigger,
};
-static const unsigned int rates[] = {
- 8000, 11025, 12000, 16000,
- 22050, 24000, 32000, 44100,
- 48000, 64000, 88200, 96000,
- 128000, 176400, 192000,
+static const struct snd_soc_dai_ops avs_dai_i2shda_be_ops = {
+ .startup = avs_dai_i2shda_be_startup,
+ .shutdown = avs_dai_althda_be_shutdown,
+ .hw_params = avs_dai_hda_be_hw_params,
+ .hw_free = avs_dai_hda_be_hw_free,
+ .prepare = avs_dai_hda_be_prepare,
+ .trigger = avs_dai_hda_be_trigger,
};
-static const struct snd_pcm_hw_constraint_list hw_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
+static const struct snd_soc_dai_ops avs_dai_dmichda_be_ops = {
+ .startup = avs_dai_dmichda_be_startup,
+ .shutdown = avs_dai_althda_be_shutdown,
+ .hw_params = avs_dai_hda_be_hw_params,
+ .hw_free = avs_dai_hda_be_hw_free,
+ .prepare = avs_dai_hda_be_prepare,
+ .trigger = avs_dai_hda_be_trigger,
};
-const struct snd_soc_dai_ops avs_dai_fe_ops;
+static int hw_rule_param_size(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
+{
+ struct snd_interval *interval = hw_param_interval(params, rule->var);
+ struct snd_interval to;
-static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+ snd_interval_any(&to);
+ to.integer = interval->integer;
+ to.max = interval->max;
+ /*
+ * Commonly 2ms buffer size is used in HDA scenarios whereas 4ms is used
+ * when streaming through GPDMA. Align to the latter to account for both.
+ */
+ to.min = params_rate(params) / 1000 * 4;
+
+ if (rule->var == SNDRV_PCM_HW_PARAM_PERIOD_SIZE)
+ to.min /= params_periods(params);
+
+ return snd_interval_refine(interval, &to);
+}
+
+static int avs_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct avs_dma_data *data;
- struct avs_dev *adev = to_avs_dev(dai->dev);
- struct hdac_bus *bus = &adev->base.core;
+ int ret;
+
+ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0)
+ return ret;
+
+ /* Avoid wrap-around with wall-clock. */
+ ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 20, 178000000);
+ if (ret < 0)
+ return ret;
+
+ /* Adjust buffer and period size based on the audio format. */
+ snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, hw_rule_param_size, NULL,
+ SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_CHANNELS,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+ snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, hw_rule_param_size, NULL,
+ SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_CHANNELS,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+
+ return 0;
+}
+
+static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
struct hdac_ext_stream *host_stream;
+ struct avs_dma_data *data;
+ struct hdac_bus *bus;
int ret;
- ret = avs_dai_startup(substream, dai, true, &avs_dai_fe_ops);
+ ret = avs_pcm_hw_constraints_init(substream);
+ if (ret)
+ return ret;
+
+ ret = avs_dai_startup(substream, dai);
if (ret)
return ret;
data = snd_soc_dai_get_dma_data(dai, substream);
+ bus = &data->adev->base.core;
host_stream = snd_hdac_ext_stream_assign(bus, substream, HDAC_EXT_STREAM_TYPE_HOST);
if (!host_stream) {
- ret = -EBUSY;
- goto err;
+ avs_dai_shutdown(substream, dai);
+ return -EBUSY;
}
data->host_stream = host_stream;
- ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- goto err;
-
- /* avoid wrap-around with wall-clock */
- ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 20, 178000000);
- if (ret < 0)
- goto err;
-
- ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_rates);
- if (ret < 0)
- goto err;
-
snd_pcm_set_sync(substream);
dev_dbg(dai->dev, "%s fe STARTUP tag %d str %p",
__func__, hdac_stream(host_stream)->stream_tag, substream);
return 0;
-
-err:
- kfree(data);
- return ret;
}
static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct avs_dev *adev = to_avs_dev(dai->dev);
struct avs_dma_data *data;
- if (rtd->dai_link->ignore_suspend)
- adev->num_lp_paths--;
-
data = snd_soc_dai_get_dma_data(dai, substream);
- snd_soc_dai_set_dma_data(dai, substream, NULL);
snd_hdac_ext_stream_release(data->host_stream, HDAC_EXT_STREAM_TYPE_HOST);
- kfree(data);
+ avs_dai_shutdown(substream, dai);
}
static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream,
@@ -540,6 +677,7 @@ static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream,
hdac_stream(host_stream)->format_val = 0;
fe = snd_soc_substream_to_rtd(substream);
+ /* dpcm_fe_dai_open() guarantees the list is not empty at this point. */
for_each_dpcm_be(fe, substream->stream, dpcm) {
be = dpcm->be;
be_hw_params = &be->dpcm[substream->stream].hw_params;
@@ -606,11 +744,11 @@ static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_so
static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_stream *stream_info;
+ const struct snd_soc_pcm_stream *stream_info;
struct avs_dma_data *data;
- struct avs_dev *adev = to_avs_dev(dai->dev);
struct hdac_ext_stream *host_stream;
unsigned int format_val;
+ struct hdac_bus *bus;
unsigned int bits;
int ret;
@@ -620,6 +758,8 @@ static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_so
if (hdac_stream(host_stream)->prepared)
return 0;
+ bus = hdac_stream(host_stream)->bus;
+ snd_hdac_ext_stream_decouple(bus, data->host_stream, true);
snd_hdac_stream_reset(hdac_stream(host_stream));
stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
@@ -635,7 +775,7 @@ static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_so
if (ret < 0)
return ret;
- ret = avs_dai_prepare(adev, substream, dai);
+ ret = avs_dai_prepare(substream, dai);
if (ret)
return ret;
@@ -887,7 +1027,8 @@ static int avs_component_probe(struct snd_soc_component *component)
else
mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
"hda-generic-tplg.bin");
-
+ if (!mach->tplg_filename)
+ return -ENOMEM;
filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
mach->tplg_filename);
if (!filename)
@@ -1226,7 +1367,7 @@ static int avs_component_construct(struct snd_soc_component *component,
return 0;
}
-static const struct snd_soc_component_driver avs_component_driver = {
+static struct snd_soc_component_driver avs_component_driver = {
.name = "avs-pcm",
.probe = avs_component_probe,
.remove = avs_component_remove,
@@ -1241,7 +1382,7 @@ static const struct snd_soc_component_driver avs_component_driver = {
};
int avs_soc_component_register(struct device *dev, const char *name,
- const struct snd_soc_component_driver *drv,
+ struct snd_soc_component_driver *drv,
struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
{
struct avs_soc_component *acomp;
@@ -1259,13 +1400,14 @@ int avs_soc_component_register(struct device *dev, const char *name,
acomp->base.name = name;
INIT_LIST_HEAD(&acomp->node);
+ drv->use_dai_pcm_id = !obsolete_card_names;
+
return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais);
}
static struct snd_soc_dai_driver dmic_cpu_dais[] = {
{
.name = "DMIC Pin",
- .ops = &avs_dai_nonhda_be_ops,
.capture = {
.stream_name = "DMIC Rx",
.channels_min = 1,
@@ -1276,7 +1418,6 @@ static struct snd_soc_dai_driver dmic_cpu_dais[] = {
},
{
.name = "DMIC WoV Pin",
- .ops = &avs_dai_nonhda_be_ops,
.capture = {
.stream_name = "DMIC WoV Rx",
.channels_min = 1,
@@ -1289,17 +1430,27 @@ static struct snd_soc_dai_driver dmic_cpu_dais[] = {
int avs_dmic_platform_register(struct avs_dev *adev, const char *name)
{
+ const struct snd_soc_dai_ops *ops;
+
+ if (avs_platattr_test(adev, ALTHDA))
+ ops = &avs_dai_dmichda_be_ops;
+ else
+ ops = &avs_dai_nonhda_be_ops;
+
+ dmic_cpu_dais[0].ops = ops;
+ dmic_cpu_dais[1].ops = ops;
return avs_soc_component_register(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
ARRAY_SIZE(dmic_cpu_dais));
}
static const struct snd_soc_dai_driver i2s_dai_template = {
- .ops = &avs_dai_nonhda_be_ops,
.playback = {
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = AVS_CHANNELS_MAX,
.rates = SNDRV_PCM_RATE_8000_192000 |
- SNDRV_PCM_RATE_KNOT,
+ SNDRV_PCM_RATE_12000 |
+ SNDRV_PCM_RATE_24000 |
+ SNDRV_PCM_RATE_128000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
@@ -1308,9 +1459,11 @@ static const struct snd_soc_dai_driver i2s_dai_template = {
},
.capture = {
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = AVS_CHANNELS_MAX,
.rates = SNDRV_PCM_RATE_8000_192000 |
- SNDRV_PCM_RATE_KNOT,
+ SNDRV_PCM_RATE_12000 |
+ SNDRV_PCM_RATE_24000 |
+ SNDRV_PCM_RATE_128000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
@@ -1323,10 +1476,15 @@ int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned l
unsigned long *tdms)
{
struct snd_soc_dai_driver *cpus, *dai;
+ const struct snd_soc_dai_ops *ops;
size_t ssp_count, cpu_count;
int i, j;
ssp_count = adev->hw_cfg.i2s_caps.ctrl_count;
+ if (avs_platattr_test(adev, ALTHDA))
+ ops = &avs_dai_i2shda_be_ops;
+ else
+ ops = &avs_dai_nonhda_be_ops;
cpu_count = 0;
for_each_set_bit(i, &port_mask, ssp_count)
@@ -1336,7 +1494,7 @@ int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned l
for_each_set_bit(i, &port_mask, ssp_count)
cpu_count += hweight_long(tdms[i]);
- cpus = devm_kzalloc(adev->dev, sizeof(*cpus) * cpu_count, GFP_KERNEL);
+ cpus = devm_kcalloc(adev->dev, cpu_count, sizeof(*cpus), GFP_KERNEL);
if (!cpus)
return -ENOMEM;
@@ -1354,6 +1512,7 @@ int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned l
if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
return -ENOMEM;
+ dai->ops = ops;
dai++;
}
}
@@ -1362,7 +1521,7 @@ int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned l
goto plat_register;
for_each_set_bit(i, &port_mask, ssp_count) {
- for_each_set_bit(j, &tdms[i], ssp_count) {
+ for_each_set_bit(j, &tdms[i], AVS_CHANNELS_MAX) {
memcpy(dai, &i2s_dai_template, sizeof(*dai));
dai->name =
@@ -1374,6 +1533,7 @@ int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned l
if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
return -ENOMEM;
+ dai->ops = ops;
dai++;
}
}
@@ -1387,7 +1547,7 @@ static const struct snd_soc_dai_driver hda_cpu_dai = {
.ops = &avs_dai_hda_be_ops,
.playback = {
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = AVS_CHANNELS_MAX,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
@@ -1397,7 +1557,7 @@ static const struct snd_soc_dai_driver hda_cpu_dai = {
},
.capture = {
.channels_min = 1,
- .channels_max = 8,
+ .channels_max = AVS_CHANNELS_MAX,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
@@ -1416,7 +1576,7 @@ static void avs_component_hda_unregister_dais(struct snd_soc_component *componen
mach = dev_get_platdata(component->card->dev);
codec = mach->pdata;
- sprintf(name, "%s-cpu", dev_name(&codec->core.dev));
+ snprintf(name, sizeof(name), "%s-cpu", dev_name(&codec->core.dev));
for_each_component_dais_safe(component, dai, save) {
int stream;
@@ -1436,6 +1596,7 @@ static int avs_component_hda_probe(struct snd_soc_component *component)
struct snd_soc_dapm_context *dapm;
struct snd_soc_dai_driver *dais;
struct snd_soc_acpi_mach *mach;
+ struct avs_mach_pdata *pdata;
struct hda_codec *codec;
struct hda_pcm *pcm;
const char *cname;
@@ -1445,7 +1606,8 @@ static int avs_component_hda_probe(struct snd_soc_component *component)
if (!mach)
return -EINVAL;
- codec = mach->pdata;
+ pdata = mach->pdata;
+ codec = pdata->codec;
if (list_empty(&codec->pcm_list_head))
return -EINVAL;
list_for_each_entry(pcm, &codec->pcm_list_head, list)
@@ -1522,6 +1684,7 @@ static int avs_component_hda_probe(struct snd_soc_component *component)
if (ret < 0) {
dev_err(component->dev, "create widgets failed: %d\n",
ret);
+ snd_soc_unregister_dai(dai);
goto exit;
}
}
@@ -1536,16 +1699,14 @@ exit:
static void avs_component_hda_remove(struct snd_soc_component *component)
{
- avs_component_hda_unregister_dais(component);
avs_component_remove(component);
+ avs_component_hda_unregister_dais(component);
}
static int avs_component_hda_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct hdac_ext_stream *link_stream;
- struct hda_codec *codec;
if (!rtd->dai_link->no_pcm) {
struct snd_pcm_hardware hwparams = avs_pcm_hardware;
@@ -1577,41 +1738,16 @@ static int avs_component_hda_open(struct snd_soc_component *component,
return snd_soc_set_runtime_hwparams(substream, &hwparams);
}
- codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
- link_stream = snd_hdac_ext_stream_assign(&codec->bus->core, substream,
- HDAC_EXT_STREAM_TYPE_LINK);
- if (!link_stream)
- return -EBUSY;
-
- substream->runtime->private_data = link_stream;
- return 0;
-}
-
-static int avs_component_hda_close(struct snd_soc_component *component,
- struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct hdac_ext_stream *link_stream;
-
- /* only BE DAI links are handled here */
- if (!rtd->dai_link->no_pcm)
- return 0;
-
- link_stream = substream->runtime->private_data;
- snd_hdac_ext_stream_release(link_stream, HDAC_EXT_STREAM_TYPE_LINK);
- substream->runtime->private_data = NULL;
-
return 0;
}
-static const struct snd_soc_component_driver avs_hda_component_driver = {
+static struct snd_soc_component_driver avs_hda_component_driver = {
.name = "avs-hda-pcm",
.probe = avs_component_hda_probe,
.remove = avs_component_hda_remove,
.suspend = avs_component_suspend,
.resume = avs_component_resume,
.open = avs_component_hda_open,
- .close = avs_component_hda_close,
.pointer = avs_component_pointer,
.mmap = avs_component_mmap,
.pcm_construct = avs_component_construct,
diff --git a/sound/soc/intel/avs/pcm.h b/sound/soc/intel/avs/pcm.h
new file mode 100644
index 000000000000..0f3615c90398
--- /dev/null
+++ b/sound/soc/intel/avs/pcm.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright(c) 2024 Intel Corporation
+ *
+ * Authors: Cezary Rojewski <cezary.rojewski@intel.com>
+ * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+ */
+
+#ifndef __SOUND_SOC_INTEL_AVS_PCM_H
+#define __SOUND_SOC_INTEL_AVS_PCM_H
+
+#include <sound/pcm.h>
+
+void avs_period_elapsed(struct snd_pcm_substream *substream);
+
+#endif
diff --git a/sound/soc/intel/avs/probes.c b/sound/soc/intel/avs/probes.c
index 817e543036f2..a42736b9aa55 100644
--- a/sound/soc/intel/avs/probes.c
+++ b/sound/soc/intel/avs/probes.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -19,8 +19,11 @@ static int avs_dsp_init_probe(struct avs_dev *adev, union avs_connector_node_id
struct avs_probe_cfg cfg = {{0}};
struct avs_module_entry mentry;
u8 dummy;
+ int ret;
- avs_get_module_entry(adev, &AVS_PROBE_MOD_UUID, &mentry);
+ ret = avs_get_module_entry(adev, &AVS_PROBE_MOD_UUID, &mentry);
+ if (ret)
+ return ret;
/*
* Probe module uses no cycles, audio data format and input and output
@@ -39,11 +42,12 @@ static int avs_dsp_init_probe(struct avs_dev *adev, union avs_connector_node_id
static void avs_dsp_delete_probe(struct avs_dev *adev)
{
struct avs_module_entry mentry;
+ int ret;
- avs_get_module_entry(adev, &AVS_PROBE_MOD_UUID, &mentry);
-
- /* There is only ever one probe module instance. */
- avs_dsp_delete_module(adev, mentry.module_id, 0, INVALID_PIPELINE_ID, 0);
+ ret = avs_get_module_entry(adev, &AVS_PROBE_MOD_UUID, &mentry);
+ if (!ret)
+ /* There is only ever one probe module instance. */
+ avs_dsp_delete_module(adev, mentry.module_id, 0, INVALID_PIPELINE_ID, 0);
}
static inline struct hdac_ext_stream *avs_compr_get_host_stream(struct snd_compr_stream *cstream)
@@ -280,7 +284,7 @@ static struct snd_soc_dai_driver probe_cpu_dais[] = {
},
};
-static const struct snd_soc_component_driver avs_probe_component_driver = {
+static struct snd_soc_component_driver avs_probe_component_driver = {
.name = "avs-probe-compr",
.compress_ops = &avs_probe_compress_ops,
.module_get_upon_open = 1, /* increment refcount when a stream is opened */
diff --git a/sound/soc/intel/avs/ptl.c b/sound/soc/intel/avs/ptl.c
new file mode 100644
index 000000000000..2be4b545c91d
--- /dev/null
+++ b/sound/soc/intel/avs/ptl.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright(c) 2024-2025 Intel Corporation
+ *
+ * Authors: Cezary Rojewski <cezary.rojewski@intel.com>
+ * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+ */
+
+#include <sound/hdaudio_ext.h>
+#include "avs.h"
+#include "registers.h"
+#include "trace.h"
+
+#define MTL_HfDSSGBL_BASE 0x1000
+#define MTL_REG_HfDSSCS (MTL_HfDSSGBL_BASE + 0x0)
+#define MTL_HfDSSCS_SPA BIT(16)
+#define MTL_HfDSSCS_CPA BIT(24)
+
+#define MTL_DSPCS_BASE 0x178D00
+#define MTL_REG_DSPCCTL (MTL_DSPCS_BASE + 0x4)
+#define MTL_DSPCCTL_OSEL GENMASK(25, 24)
+#define MTL_DSPCCTL_OSEL_HOST BIT(25)
+
+static int avs_ptl_core_power_on(struct avs_dev *adev)
+{
+ u32 reg;
+ int ret;
+
+ /* Power up DSP domain. */
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfDSSCS, MTL_HfDSSCS_SPA, MTL_HfDSSCS_SPA);
+ trace_avs_dsp_core_op(1, AVS_MAIN_CORE_MASK, "power dsp", true);
+
+ ret = snd_hdac_adsp_readl_poll(adev, MTL_REG_HfDSSCS, reg,
+ (reg & MTL_HfDSSCS_CPA) == MTL_HfDSSCS_CPA,
+ AVS_ADSPCS_INTERVAL_US, AVS_ADSPCS_TIMEOUT_US);
+ if (ret) {
+ dev_err(adev->dev, "power on domain dsp failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Prevent power gating of DSP domain. */
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfPWRCTL2, MTL_HfPWRCTL2_WPDSPHPxPG,
+ MTL_HfPWRCTL2_WPDSPHPxPG);
+ trace_avs_dsp_core_op(1, AVS_MAIN_CORE_MASK, "prevent dsp PG", true);
+
+ ret = snd_hdac_adsp_readl_poll(adev, MTL_REG_HfPWRSTS2, reg,
+ (reg & MTL_HfPWRSTS2_DSPHPxPGS) == MTL_HfPWRSTS2_DSPHPxPGS,
+ AVS_ADSPCS_INTERVAL_US, AVS_ADSPCS_TIMEOUT_US);
+
+ /* Set ownership to HOST. */
+ snd_hdac_adsp_updatel(adev, MTL_REG_DSPCCTL, MTL_DSPCCTL_OSEL, MTL_DSPCCTL_OSEL_HOST);
+ return ret;
+}
+
+static int avs_ptl_core_power_off(struct avs_dev *adev)
+{
+ u32 reg;
+
+ /* Allow power gating of DSP domain. No STS polling as HOST is only one of its users. */
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfPWRCTL2, MTL_HfPWRCTL2_WPDSPHPxPG, 0);
+ trace_avs_dsp_core_op(0, AVS_MAIN_CORE_MASK, "allow dsp pg", false);
+
+ /* Power down DSP domain. */
+ snd_hdac_adsp_updatel(adev, MTL_REG_HfDSSCS, MTL_HfDSSCS_SPA, 0);
+ trace_avs_dsp_core_op(0, AVS_MAIN_CORE_MASK, "power dsp", false);
+
+ return snd_hdac_adsp_readl_poll(adev, MTL_REG_HfDSSCS, reg,
+ (reg & MTL_HfDSSCS_CPA) == 0,
+ AVS_ADSPCS_INTERVAL_US, AVS_ADSPCS_TIMEOUT_US);
+}
+
+static int avs_ptl_core_power(struct avs_dev *adev, u32 core_mask, bool power)
+{
+ core_mask &= AVS_MAIN_CORE_MASK;
+ if (!core_mask)
+ return 0;
+
+ if (power)
+ return avs_ptl_core_power_on(adev);
+ return avs_ptl_core_power_off(adev);
+}
+
+const struct avs_dsp_ops avs_ptl_dsp_ops = {
+ .power = avs_ptl_core_power,
+ .reset = avs_mtl_core_reset,
+ .stall = avs_lnl_core_stall,
+ .dsp_interrupt = avs_mtl_dsp_interrupt,
+ .int_control = avs_mtl_interrupt_control,
+ .load_basefw = avs_hda_load_basefw,
+ .load_lib = avs_hda_load_library,
+ .transfer_mods = avs_hda_transfer_modules,
+ .log_buffer_offset = avs_icl_log_buffer_offset,
+ .log_buffer_status = avs_apl_log_buffer_status,
+ .coredump = avs_apl_coredump,
+ .d0ix_toggle = avs_icl_d0ix_toggle,
+ .set_d0ix = avs_icl_set_d0ix,
+ AVS_SET_ENABLE_LOGS_OP(icl)
+};
diff --git a/sound/soc/intel/avs/registers.h b/sound/soc/intel/avs/registers.h
index 6126adca500c..97767882ffa1 100644
--- a/sound/soc/intel/avs/registers.h
+++ b/sound/soc/intel/avs/registers.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+ * Copyright(c) 2021-2022 Intel Corporation
*
* Authors: Cezary Rojewski <cezary.rojewski@intel.com>
* Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -9,6 +9,8 @@
#ifndef __SOUND_SOC_INTEL_AVS_REGS_H
#define __SOUND_SOC_INTEL_AVS_REGS_H
+#include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/iopoll.h>
#include <linux/sizes.h>
#define AZX_PCIREG_PGCTL 0x44
@@ -33,6 +35,8 @@
#define AVS_ADSPCS_CSTALL_MASK(cm) ((cm) << 8)
#define AVS_ADSPCS_SPA_MASK(cm) ((cm) << 16)
#define AVS_ADSPCS_CPA_MASK(cm) ((cm) << 24)
+#define AVS_ADSPCS_INTERVAL_US 500
+#define AVS_ADSPCS_TIMEOUT_US 10000
#define AVS_MAIN_CORE_MASK BIT(0)
#define AVS_ADSP_HIPCCTL_BUSY BIT(0)
@@ -65,16 +69,52 @@
#define CNL_ADSP_HIPCIDR_BUSY BIT(31)
#define CNL_ADSP_HIPCIDA_DONE BIT(31)
+/* MTL Intel HOST Inter-Processor Communication Registers */
+#define MTL_HfIPC_BASE 0x73000
+#define MTL_REG_HfIPCxTDR (MTL_HfIPC_BASE + 0x200)
+#define MTL_REG_HfIPCxTDA (MTL_HfIPC_BASE + 0x204)
+#define MTL_REG_HfIPCxIDR (MTL_HfIPC_BASE + 0x210)
+#define MTL_REG_HfIPCxIDA (MTL_HfIPC_BASE + 0x214)
+#define MTL_REG_HfIPCxCTL (MTL_HfIPC_BASE + 0x228)
+#define MTL_REG_HfIPCxTDD (MTL_HfIPC_BASE + 0x300)
+#define MTL_REG_HfIPCxIDD (MTL_HfIPC_BASE + 0x380)
+
+#define MTL_HfIPCxTDR_BUSY BIT(31)
+#define MTL_HfIPCxTDA_BUSY BIT(31)
+#define MTL_HfIPCxIDR_BUSY BIT(31)
+#define MTL_HfIPCxIDA_DONE BIT(31)
+
+#define MTL_HfFLV_BASE 0x162000
+#define MTL_REG_HfFLGP(x, y) (MTL_HfFLV_BASE + 0x1200 + (x) * 0x20 + (y) * 0x08)
+#define LNL_REG_HfDFR(x) (0x160200 + (x) * 0x8)
+
+#define MTL_DWICTL_BASE 0x1800
+#define MTL_DWICTL_REG_INTENL (MTL_DWICTL_BASE + 0x0)
+#define MTL_DWICTL_REG_FINALSTATUSL (MTL_DWICTL_BASE + 0x30)
+
+#define MTL_HfPMCCU_BASE 0x1D00
+#define MTL_REG_HfCLKCTL (MTL_HfPMCCU_BASE + 0x10)
+#define MTL_REG_HfPWRCTL (MTL_HfPMCCU_BASE + 0x18)
+#define MTL_REG_HfPWRSTS (MTL_HfPMCCU_BASE + 0x1C)
+#define MTL_REG_HfPWRCTL2 (MTL_HfPMCCU_BASE + 0x20)
+#define MTL_REG_HfPWRSTS2 (MTL_HfPMCCU_BASE + 0x24)
+#define MTL_HfPWRCTL_WPDSPHPxPG BIT(0)
+#define MTL_HfPWRSTS_DSPHPxPGS BIT(0)
+#define MTL_HfPWRCTL2_WPDSPHPxPG BIT(0)
+#define MTL_HfPWRSTS2_DSPHPxPGS BIT(0)
+
/* Intel HD Audio SRAM windows base addresses */
#define SKL_ADSP_SRAM_BASE_OFFSET 0x8000
#define SKL_ADSP_SRAM_WINDOW_SIZE 0x2000
#define APL_ADSP_SRAM_BASE_OFFSET 0x80000
#define APL_ADSP_SRAM_WINDOW_SIZE 0x20000
+#define MTL_ADSP_SRAM_BASE_OFFSET 0x180000
+#define MTL_ADSP_SRAM_WINDOW_SIZE 0x8000
/* Constants used when accessing SRAM, space shared with firmware */
-#define AVS_FW_REG_BASE(adev) ((adev)->spec->sram->base_offset)
+#define AVS_FW_REG_BASE(adev) ((adev)->spec->hipc->sts_offset)
#define AVS_FW_REG_STATUS(adev) (AVS_FW_REG_BASE(adev) + 0x0)
-#define AVS_FW_REG_ERROR_CODE(adev) (AVS_FW_REG_BASE(adev) + 0x4)
+#define AVS_FW_REG_ERROR(adev) (AVS_FW_REG_BASE(adev) + 0x4)
#define AVS_WINDOW_CHUNK_SIZE SZ_4K
#define AVS_FW_REGS_SIZE AVS_WINDOW_CHUNK_SIZE
@@ -98,4 +138,47 @@
#define avs_downlink_addr(adev) \
avs_sram_addr(adev, AVS_DOWNLINK_WINDOW)
+#define snd_hdac_adsp_writeb(adev, reg, value) \
+ snd_hdac_reg_writeb(&(adev)->base.core, (adev)->dsp_ba + (reg), value)
+#define snd_hdac_adsp_readb(adev, reg) \
+ snd_hdac_reg_readb(&(adev)->base.core, (adev)->dsp_ba + (reg))
+#define snd_hdac_adsp_writew(adev, reg, value) \
+ snd_hdac_reg_writew(&(adev)->base.core, (adev)->dsp_ba + (reg), value)
+#define snd_hdac_adsp_readw(adev, reg) \
+ snd_hdac_reg_readw(&(adev)->base.core, (adev)->dsp_ba + (reg))
+#define snd_hdac_adsp_writel(adev, reg, value) \
+ snd_hdac_reg_writel(&(adev)->base.core, (adev)->dsp_ba + (reg), value)
+#define snd_hdac_adsp_readl(adev, reg) \
+ snd_hdac_reg_readl(&(adev)->base.core, (adev)->dsp_ba + (reg))
+#define snd_hdac_adsp_writeq(adev, reg, value) \
+ snd_hdac_reg_writeq(&(adev)->base.core, (adev)->dsp_ba + (reg), value)
+#define snd_hdac_adsp_readq(adev, reg) \
+ snd_hdac_reg_readq(&(adev)->base.core, (adev)->dsp_ba + (reg))
+
+#define snd_hdac_adsp_updateb(adev, reg, mask, val) \
+ snd_hdac_adsp_writeb(adev, reg, \
+ (snd_hdac_adsp_readb(adev, reg) & ~(mask)) | (val))
+#define snd_hdac_adsp_updatew(adev, reg, mask, val) \
+ snd_hdac_adsp_writew(adev, reg, \
+ (snd_hdac_adsp_readw(adev, reg) & ~(mask)) | (val))
+#define snd_hdac_adsp_updatel(adev, reg, mask, val) \
+ snd_hdac_adsp_writel(adev, reg, \
+ (snd_hdac_adsp_readl(adev, reg) & ~(mask)) | (val))
+#define snd_hdac_adsp_updateq(adev, reg, mask, val) \
+ snd_hdac_adsp_writeq(adev, reg, \
+ (snd_hdac_adsp_readq(adev, reg) & ~(mask)) | (val))
+
+#define snd_hdac_adsp_readb_poll(adev, reg, val, cond, delay_us, timeout_us) \
+ readb_poll_timeout((adev)->dsp_ba + (reg), val, cond, \
+ delay_us, timeout_us)
+#define snd_hdac_adsp_readw_poll(adev, reg, val, cond, delay_us, timeout_us) \
+ readw_poll_timeout((adev)->dsp_ba + (reg), val, cond, \
+ delay_us, timeout_us)
+#define snd_hdac_adsp_readl_poll(adev, reg, val, cond, delay_us, timeout_us) \
+ readl_poll_timeout((adev)->dsp_ba + (reg), val, cond, \
+ delay_us, timeout_us)
+#define snd_hdac_adsp_readq_poll(adev, reg, val, cond, delay_us, timeout_us) \
+ readq_poll_timeout((adev)->dsp_ba + (reg), val, cond, \
+ delay_us, timeout_us)
+
#endif /* __SOUND_SOC_INTEL_AVS_REGS_H */
diff --git a/sound/soc/intel/avs/skl.c b/sound/soc/intel/avs/skl.c
index d19f8953993f..d66ef000de9e 100644
--- a/sound/soc/intel/avs/skl.c
+++ b/sound/soc/intel/avs/skl.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -10,31 +10,68 @@
#include <linux/slab.h>
#include <sound/hdaudio_ext.h>
#include "avs.h"
+#include "cldma.h"
#include "messages.h"
+#include "registers.h"
-irqreturn_t avs_skl_irq_thread(struct avs_dev *adev)
+void avs_skl_ipc_interrupt(struct avs_dev *adev)
{
- union avs_reply_msg msg;
- u32 hipct, hipcte;
+ const struct avs_spec *spec = adev->spec;
+ u32 hipc_ack, hipc_rsp;
- hipct = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCT);
- hipcte = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCTE);
+ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,
+ AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY, 0);
- /* Ensure DSP sent new response to process. */
- if (!(hipct & SKL_ADSP_HIPCT_BUSY))
- return IRQ_NONE;
+ hipc_ack = snd_hdac_adsp_readl(adev, spec->hipc->ack_offset);
+ hipc_rsp = snd_hdac_adsp_readl(adev, spec->hipc->rsp_offset);
- msg.primary = hipct;
- msg.ext.val = hipcte;
- avs_dsp_process_response(adev, msg.val);
+ /* DSP acked host's request. */
+ if (hipc_ack & spec->hipc->ack_done_mask) {
+ complete(&adev->ipc->done_completion);
- /* Tell DSP we accepted its message. */
- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCT, SKL_ADSP_HIPCT_BUSY, SKL_ADSP_HIPCT_BUSY);
- /* Unmask busy interrupt. */
- snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL, AVS_ADSP_HIPCCTL_BUSY,
- AVS_ADSP_HIPCCTL_BUSY);
+ /* Tell DSP it has our attention. */
+ snd_hdac_adsp_updatel(adev, spec->hipc->ack_offset, spec->hipc->ack_done_mask,
+ spec->hipc->ack_done_mask);
+ }
- return IRQ_HANDLED;
+ /* DSP sent new response to process */
+ if (hipc_rsp & spec->hipc->rsp_busy_mask) {
+ union avs_reply_msg msg;
+
+ msg.primary = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCT);
+ msg.ext.val = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCTE);
+
+ avs_dsp_process_response(adev, msg.val);
+
+ /* Tell DSP we accepted its message. */
+ snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCT, SKL_ADSP_HIPCT_BUSY,
+ SKL_ADSP_HIPCT_BUSY);
+ }
+
+ snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,
+ AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY,
+ AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY);
+}
+
+static irqreturn_t avs_skl_dsp_interrupt(struct avs_dev *adev)
+{
+ u32 adspis = snd_hdac_adsp_readl(adev, AVS_ADSP_REG_ADSPIS);
+ irqreturn_t ret = IRQ_NONE;
+
+ if (adspis == UINT_MAX)
+ return ret;
+
+ if (adspis & AVS_ADSP_ADSPIS_CLDMA) {
+ hda_cldma_interrupt(&code_loader);
+ ret = IRQ_HANDLED;
+ }
+
+ if (adspis & AVS_ADSP_ADSPIS_IPC) {
+ avs_skl_ipc_interrupt(adev);
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
}
static int __maybe_unused
@@ -128,8 +165,7 @@ const struct avs_dsp_ops avs_skl_dsp_ops = {
.power = avs_dsp_core_power,
.reset = avs_dsp_core_reset,
.stall = avs_dsp_core_stall,
- .irq_handler = avs_irq_handler,
- .irq_thread = avs_skl_irq_thread,
+ .dsp_interrupt = avs_skl_dsp_interrupt,
.int_control = avs_dsp_interrupt_control,
.load_basefw = avs_cldma_load_basefw,
.load_lib = avs_cldma_load_library,
diff --git a/sound/soc/intel/avs/sysfs.c b/sound/soc/intel/avs/sysfs.c
index cce21636fbc0..74b2e6f38d76 100644
--- a/sound/soc/intel/avs/sysfs.c
+++ b/sound/soc/intel/avs/sysfs.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2024 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2024 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
diff --git a/sound/soc/intel/avs/tgl.c b/sound/soc/intel/avs/tgl.c
index 0e052e7f6bac..9dbb3ad0954a 100644
--- a/sound/soc/intel/avs/tgl.c
+++ b/sound/soc/intel/avs/tgl.c
@@ -1,12 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2024 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2024 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
//
+#include <linux/pci.h>
#include "avs.h"
+#include "messages.h"
+
+#define CPUID_TSC_LEAF 0x15
static int avs_tgl_dsp_core_power(struct avs_dev *adev, u32 core_mask, bool power)
{
@@ -35,16 +39,44 @@ static int avs_tgl_dsp_core_stall(struct avs_dev *adev, u32 core_mask, bool stal
return avs_dsp_core_stall(adev, core_mask, stall);
}
+static int avs_tgl_config_basefw(struct avs_dev *adev)
+{
+ struct pci_dev *pci = adev->base.pci;
+ struct avs_bus_hwid hwid;
+ int ret;
+#ifdef CONFIG_X86
+ unsigned int ecx;
+
+#include <asm/cpuid/api.h>
+ ecx = cpuid_ecx(CPUID_TSC_LEAF);
+ if (ecx) {
+ ret = avs_ipc_set_fw_config(adev, 1, AVS_FW_CFG_XTAL_FREQ_HZ, sizeof(ecx), &ecx);
+ if (ret)
+ return AVS_IPC_RET(ret);
+ }
+#endif
+
+ hwid.device = pci->device;
+ hwid.subsystem = pci->subsystem_vendor | (pci->subsystem_device << 16);
+ hwid.revision = pci->revision;
+
+ ret = avs_ipc_set_fw_config(adev, 1, AVS_FW_CFG_BUS_HARDWARE_ID, sizeof(hwid), &hwid);
+ if (ret)
+ return AVS_IPC_RET(ret);
+
+ return 0;
+}
+
const struct avs_dsp_ops avs_tgl_dsp_ops = {
.power = avs_tgl_dsp_core_power,
.reset = avs_tgl_dsp_core_reset,
.stall = avs_tgl_dsp_core_stall,
- .irq_handler = avs_irq_handler,
- .irq_thread = avs_cnl_irq_thread,
+ .dsp_interrupt = avs_cnl_dsp_interrupt,
.int_control = avs_dsp_interrupt_control,
.load_basefw = avs_icl_load_basefw,
.load_lib = avs_hda_load_library,
.transfer_mods = avs_hda_transfer_modules,
+ .config_basefw = avs_tgl_config_basefw,
.log_buffer_offset = avs_icl_log_buffer_offset,
.log_buffer_status = avs_apl_log_buffer_status,
.coredump = avs_apl_coredump,
diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c
index 13061bd1488b..f2e4ad8b8e14 100644
--- a/sound/soc/intel/avs/topology.c
+++ b/sound/soc/intel/avs/topology.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021 Intel Corporation. All rights reserved.
+// Copyright(c) 2021 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -815,6 +815,66 @@ static const struct avs_tplg_token_parser modcfg_ext_parsers[] = {
.offset = offsetof(struct avs_tplg_modcfg_ext, generic.num_output_pins),
.parse = avs_parse_short_token,
},
+ {
+ .token = AVS_TKN_MODCFG_WHM_REF_AFMT_ID_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_modcfg_ext, whm.ref_fmt),
+ .parse = avs_parse_audio_format_ptr,
+ },
+ {
+ .token = AVS_TKN_MODCFG_WHM_OUT_AFMT_ID_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_modcfg_ext, whm.out_fmt),
+ .parse = avs_parse_audio_format_ptr,
+ },
+ {
+ .token = AVS_TKN_MODCFG_WHM_WAKE_TICK_PERIOD_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_modcfg_ext, whm.wake_tick_period),
+ .parse = avs_parse_word_token,
+ },
+ {
+ .token = AVS_TKN_MODCFG_WHM_VINDEX_U8,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_BYTE,
+ .offset = offsetof(struct avs_tplg_modcfg_ext, whm.vindex),
+ .parse = avs_parse_byte_token,
+ },
+ {
+ .token = AVS_TKN_MODCFG_WHM_DMA_TYPE_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_modcfg_ext, whm.dma_type),
+ .parse = avs_parse_word_token,
+ },
+ {
+ .token = AVS_TKN_MODCFG_WHM_DMABUFF_SIZE_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_modcfg_ext, whm.dma_buffer_size),
+ .parse = avs_parse_word_token,
+ },
+ {
+ .token = AVS_TKN_MODCFG_WHM_BLOB_AFMT_ID_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_modcfg_ext, whm.blob_fmt),
+ .parse = avs_parse_audio_format_ptr,
+ },
+ {
+ .token = AVS_TKN_MODCFG_PEAKVOL_VOLUME_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_modcfg_ext, peakvol.target_volume),
+ .parse = avs_parse_word_token,
+ },
+ {
+ .token = AVS_TKN_MODCFG_PEAKVOL_CURVE_TYPE_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_modcfg_ext, peakvol.curve_type),
+ .parse = avs_parse_word_token,
+ },
+ {
+ .token = AVS_TKN_MODCFG_PEAKVOL_CURVE_DURATION_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_modcfg_ext, peakvol.curve_duration),
+ .parse = avs_parse_word_token,
+ },
};
static const struct avs_tplg_token_parser pin_format_parsers[] = {
@@ -1466,7 +1526,7 @@ avs_tplg_path_template_create(struct snd_soc_component *comp, struct avs_tplg *o
static const struct avs_tplg_token_parser mod_init_config_parsers[] = {
{
- .token = AVS_TKN_MOD_INIT_CONFIG_ID_U32,
+ .token = AVS_TKN_INIT_CONFIG_ID_U32,
.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
.offset = offsetof(struct avs_tplg_init_config, id),
.parse = avs_parse_word_token,
@@ -1519,7 +1579,7 @@ static int avs_tplg_parse_initial_configs(struct snd_soc_component *comp,
esize = le32_to_cpu(tuples->size) + le32_to_cpu(tmp->size);
ret = parse_dictionary_entries(comp, tuples, esize, config, 1, sizeof(*config),
- AVS_TKN_MOD_INIT_CONFIG_ID_U32,
+ AVS_TKN_INIT_CONFIG_ID_U32,
mod_init_config_parsers,
ARRAY_SIZE(mod_init_config_parsers));
@@ -1545,8 +1605,8 @@ static int avs_route_load(struct snd_soc_component *comp, int index,
{
struct snd_soc_acpi_mach *mach = dev_get_platdata(comp->card->dev);
size_t len = SNDRV_CTL_ELEM_ID_NAME_MAXLEN;
- char buf[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
int ssp_port, tdm_slot;
+ char *buf;
/* See parse_link_formatted_string() for dynamic naming when(s). */
if (!avs_mach_singular_ssp(mach))
@@ -1557,13 +1617,24 @@ static int avs_route_load(struct snd_soc_component *comp, int index,
return 0;
tdm_slot = avs_mach_ssp_tdm(mach, ssp_port);
+ buf = devm_kzalloc(comp->card->dev, len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
avs_ssp_sprint(buf, len, route->source, ssp_port, tdm_slot);
- strscpy((char *)route->source, buf, len);
+ route->source = buf;
+
+ buf = devm_kzalloc(comp->card->dev, len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
avs_ssp_sprint(buf, len, route->sink, ssp_port, tdm_slot);
- strscpy((char *)route->sink, buf, len);
+ route->sink = buf;
+
if (route->control) {
+ buf = devm_kzalloc(comp->card->dev, len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
avs_ssp_sprint(buf, len, route->control, ssp_port, tdm_slot);
- strscpy((char *)route->control, buf, len);
+ route->control = buf;
}
return 0;
@@ -1582,6 +1653,8 @@ static int avs_widget_load(struct snd_soc_component *comp, int index,
if (!le32_to_cpu(dw->priv.size))
return 0;
+ w->no_wname_in_kcontrol_name = true;
+
if (w->ignore_suspend && !AVS_S0IX_SUPPORTED) {
dev_info_once(comp->dev, "Device does not support S0IX, check BIOS settings\n");
w->ignore_suspend = false;
@@ -1595,8 +1668,8 @@ static int avs_widget_load(struct snd_soc_component *comp, int index,
/* See parse_link_formatted_string() for dynamic naming when(s). */
if (avs_mach_singular_tdm(mach, ssp_port)) {
- /* size is based on possible %d -> SSP:TDM, where SSP and TDM < 10 + '\0' */
- size_t size = strlen(dw->name) + 2;
+ /* size is based on possible %d -> SSP:TDM, where SSP and TDM < 16 + '\0' */
+ size_t size = strlen(dw->name) + 3;
char *buf;
tdm_slot = avs_mach_ssp_tdm(mach, ssp_port);
@@ -1832,13 +1905,23 @@ static int avs_manifest(struct snd_soc_component *comp, int index,
return 0;
}
-#define AVS_CONTROL_OPS_VOLUME 257
+enum {
+ AVS_CONTROL_OPS_VOLUME = 257,
+ AVS_CONTROL_OPS_MUTE,
+};
static const struct snd_soc_tplg_kcontrol_ops avs_control_ops[] = {
{
.id = AVS_CONTROL_OPS_VOLUME,
.get = avs_control_volume_get,
.put = avs_control_volume_put,
+ .info = avs_control_volume_info,
+ },
+ {
+ .id = AVS_CONTROL_OPS_MUTE,
+ .get = avs_control_mute_get,
+ .put = avs_control_mute_put,
+ .info = avs_control_mute_info,
},
};
@@ -1860,18 +1943,20 @@ avs_control_load(struct snd_soc_component *comp, int index, struct snd_kcontrol_
struct avs_control_data *ctl_data;
struct soc_mixer_control *mc;
size_t block_size;
- int ret;
+ int ret, i;
switch (le32_to_cpu(hdr->type)) {
case SND_SOC_TPLG_TYPE_MIXER:
- tmc = container_of(hdr, typeof(*tmc), hdr);
- tuples = tmc->priv.array;
- block_size = le32_to_cpu(tmc->priv.size);
break;
default:
return -EINVAL;
}
+ mc = (struct soc_mixer_control *)ctmpl->private_value;
+ tmc = container_of(hdr, typeof(*tmc), hdr);
+ tuples = tmc->priv.array;
+ block_size = le32_to_cpu(tmc->priv.size);
+
ctl_data = devm_kzalloc(comp->card->dev, sizeof(*ctl_data), GFP_KERNEL);
if (!ctl_data)
return -ENOMEM;
@@ -1882,12 +1967,17 @@ avs_control_load(struct snd_soc_component *comp, int index, struct snd_kcontrol_
if (ret)
return ret;
- mc = (struct soc_mixer_control *)ctmpl->private_value;
mc->dobj.private = ctl_data;
+ if (tmc->invert) {
+ ctl_data->values[0] = mc->max;
+ for (i = 1; i < mc->num_channels; i++)
+ ctl_data->values[i] = mc->max;
+ }
+
return 0;
}
-static struct snd_soc_tplg_ops avs_tplg_ops = {
+static const struct snd_soc_tplg_ops avs_tplg_ops = {
.io_ops = avs_control_ops,
.io_ops_count = ARRAY_SIZE(avs_control_ops),
.control_load = avs_control_load,
diff --git a/sound/soc/intel/avs/topology.h b/sound/soc/intel/avs/topology.h
index 6a59dd766603..f5601a4e3ec8 100644
--- a/sound/soc/intel/avs/topology.h
+++ b/sound/soc/intel/avs/topology.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright(c) 2021 Intel Corporation. All rights reserved.
+ * Copyright(c) 2021 Intel Corporation
*
* Authors: Cezary Rojewski <cezary.rojewski@intel.com>
* Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -74,13 +74,20 @@ struct avs_tplg_modcfg_ext {
union avs_virtual_index vindex;
u32 dma_type;
u32 dma_buffer_size;
- u32 config_length;
- /* config_data part of priv data */
} copier;
struct {
+ struct avs_audio_format *ref_fmt;
+ struct avs_audio_format *out_fmt;
+ u32 wake_tick_period;
+ union avs_virtual_index vindex;
+ u32 dma_type;
+ u32 dma_buffer_size;
+ struct avs_audio_format *blob_fmt; /* optional override */
+ } whm;
+ struct {
u32 out_channel_config;
u32 coefficients_select;
- s32 coefficients[AVS_CHANNELS_MAX];
+ s32 coefficients[AVS_COEFF_CHANNELS_MAX];
u32 channel_map;
} updown_mix;
struct {
@@ -106,6 +113,11 @@ struct avs_tplg_modcfg_ext {
struct {
struct avs_audio_format *out_fmt;
} micsel;
+ struct {
+ u32 target_volume;
+ u32 curve_type;
+ u32 curve_duration;
+ } peakvol;
};
};
diff --git a/sound/soc/intel/avs/trace.c b/sound/soc/intel/avs/trace.c
index c63eea909b5e..a98da521db0f 100644
--- a/sound/soc/intel/avs/trace.c
+++ b/sound/soc/intel/avs/trace.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
diff --git a/sound/soc/intel/avs/trace.h b/sound/soc/intel/avs/trace.h
index 855b06bb14b0..f4288d0ad5ef 100644
--- a/sound/soc/intel/avs/trace.h
+++ b/sound/soc/intel/avs/trace.h
@@ -24,7 +24,7 @@ TRACE_EVENT(avs_dsp_core_op,
TP_fast_assign(
__entry->reg = reg;
__entry->mask = mask;
- __assign_str(op, op);
+ __assign_str(op);
__entry->flag = flag;
),
@@ -37,60 +37,62 @@ TRACE_EVENT(avs_dsp_core_op,
void trace_avs_msg_payload(const void *data, size_t size);
-#define trace_avs_request(msg, fwregs) \
+#define trace_avs_request(msg, sts, lec) \
({ \
- trace_avs_ipc_request_msg((msg)->header, fwregs); \
+ trace_avs_ipc_request_msg((msg)->header, sts, lec); \
trace_avs_msg_payload((msg)->data, (msg)->size); \
})
-#define trace_avs_reply(msg, fwregs) \
+#define trace_avs_reply(msg, sts, lec) \
({ \
- trace_avs_ipc_reply_msg((msg)->header, fwregs); \
+ trace_avs_ipc_reply_msg((msg)->header, sts, lec); \
trace_avs_msg_payload((msg)->data, (msg)->size); \
})
-#define trace_avs_notify(msg, fwregs) \
+#define trace_avs_notify(msg, sts, lec) \
({ \
- trace_avs_ipc_notify_msg((msg)->header, fwregs); \
+ trace_avs_ipc_notify_msg((msg)->header, sts, lec); \
trace_avs_msg_payload((msg)->data, (msg)->size); \
})
#endif
DECLARE_EVENT_CLASS(avs_ipc_msg_hdr,
- TP_PROTO(u64 header, u64 fwregs),
+ TP_PROTO(u64 header, u32 sts, u32 lec),
- TP_ARGS(header, fwregs),
+ TP_ARGS(header, sts, lec),
TP_STRUCT__entry(
__field(u64, header)
- __field(u64, fwregs)
+ __field(u32, sts)
+ __field(u32, lec)
),
TP_fast_assign(
__entry->header = header;
- __entry->fwregs = fwregs;
+ __entry->sts = sts;
+ __entry->lec = lec;
),
TP_printk("primary: 0x%08X, extension: 0x%08X,\n"
- "fwstatus: 0x%08X, fwerror: 0x%08X",
+ "status: 0x%08X, error: 0x%08X",
lower_32_bits(__entry->header), upper_32_bits(__entry->header),
- lower_32_bits(__entry->fwregs), upper_32_bits(__entry->fwregs))
+ __entry->sts, __entry->lec)
);
DEFINE_EVENT(avs_ipc_msg_hdr, avs_ipc_request_msg,
- TP_PROTO(u64 header, u64 fwregs),
- TP_ARGS(header, fwregs)
+ TP_PROTO(u64 header, u32 sts, u32 lec),
+ TP_ARGS(header, sts, lec)
);
DEFINE_EVENT(avs_ipc_msg_hdr, avs_ipc_reply_msg,
- TP_PROTO(u64 header, u64 fwregs),
- TP_ARGS(header, fwregs)
+ TP_PROTO(u64 header, u32 sts, u32 lec),
+ TP_ARGS(header, sts, lec)
);
DEFINE_EVENT(avs_ipc_msg_hdr, avs_ipc_notify_msg,
- TP_PROTO(u64 header, u64 fwregs),
- TP_ARGS(header, fwregs)
+ TP_PROTO(u64 header, u32 sts, u32 lec),
+ TP_ARGS(header, sts, lec)
);
TRACE_EVENT_CONDITION(avs_ipc_msg_payload,
@@ -135,7 +137,7 @@ TRACE_EVENT(avs_d0ix,
),
TP_fast_assign(
- __assign_str(op, op);
+ __assign_str(op);
__entry->proceed = proceed;
__entry->header = header;
),
diff --git a/sound/soc/intel/avs/utils.c b/sound/soc/intel/avs/utils.c
index 82416b86662d..81f9b67d8e29 100644
--- a/sound/soc/intel/avs/utils.c
+++ b/sound/soc/intel/avs/utils.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -250,7 +250,7 @@ int avs_request_firmware(struct avs_dev *adev, const struct firmware **fw_p, con
if (!entry)
return -ENOMEM;
- entry->name = kstrdup(name, GFP_KERNEL);
+ entry->name = kstrdup_const(name, GFP_KERNEL);
if (!entry->name) {
kfree(entry);
return -ENOMEM;
@@ -258,7 +258,7 @@ int avs_request_firmware(struct avs_dev *adev, const struct firmware **fw_p, con
ret = request_firmware(&entry->fw, name, adev->dev);
if (ret < 0) {
- kfree(entry->name);
+ kfree_const(entry->name);
kfree(entry);
return ret;
}
@@ -282,7 +282,7 @@ void avs_release_last_firmware(struct avs_dev *adev)
list_del(&entry->node);
release_firmware(entry->fw);
- kfree(entry->name);
+ kfree_const(entry->name);
kfree(entry);
}
@@ -296,7 +296,7 @@ void avs_release_firmwares(struct avs_dev *adev)
list_for_each_entry_safe(entry, tmp, &adev->fw_list, node) {
list_del(&entry->node);
release_firmware(entry->fw);
- kfree(entry->name);
+ kfree_const(entry->name);
kfree(entry);
}
}
diff --git a/sound/soc/intel/avs/utils.h b/sound/soc/intel/avs/utils.h
index 0b82a98ed024..955a40d2c30c 100644
--- a/sound/soc/intel/avs/utils.h
+++ b/sound/soc/intel/avs/utils.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright(c) 2023 Intel Corporation. All rights reserved.
+ * Copyright(c) 2023 Intel Corporation
*
* Authors: Cezary Rojewski <cezary.rojewski@intel.com>
* Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
@@ -11,6 +11,16 @@
#include <sound/soc-acpi.h>
+extern bool obsolete_card_names;
+
+struct avs_mach_pdata {
+ struct hda_codec *codec;
+ unsigned long *tdms;
+ char *codec_name; /* DMIC only */
+
+ bool obsolete_card_names;
+};
+
static inline bool avs_mach_singular_ssp(struct snd_soc_acpi_mach *mach)
{
return hweight_long(mach->mach_params.i2s_link_mask) == 1;
@@ -23,14 +33,16 @@ static inline u32 avs_mach_ssp_port(struct snd_soc_acpi_mach *mach)
static inline bool avs_mach_singular_tdm(struct snd_soc_acpi_mach *mach, u32 port)
{
- unsigned long *tdms = mach->pdata;
+ struct avs_mach_pdata *pdata = mach->pdata;
+ unsigned long *tdms = pdata->tdms;
return !tdms || (hweight_long(tdms[port]) == 1);
}
static inline u32 avs_mach_ssp_tdm(struct snd_soc_acpi_mach *mach, u32 port)
{
- unsigned long *tdms = mach->pdata;
+ struct avs_mach_pdata *pdata = mach->pdata;
+ unsigned long *tdms = pdata->tdms;
return tdms ? __ffs(tdms[port]) : 0;
}
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,
+ &current_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,
- &current_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(&params, 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);
diff --git a/sound/soc/intel/catpt/Makefile b/sound/soc/intel/catpt/Makefile
index c393a45795da..f5f6a7e956ce 100644
--- a/sound/soc/intel/catpt/Makefile
+++ b/sound/soc/intel/catpt/Makefile
@@ -1,4 +1,4 @@
-snd-soc-catpt-objs := device.o dsp.o loader.o ipc.o messages.o pcm.o sysfs.o
+snd-soc-catpt-y := device.o dsp.o loader.o ipc.o messages.o pcm.o sysfs.o
# tell define_trace.h where to find the trace header
CFLAGS_device.o := -I$(src)
diff --git a/sound/soc/intel/catpt/core.h b/sound/soc/intel/catpt/core.h
index a64a0a77dcb7..c01d27e9fd88 100644
--- a/sound/soc/intel/catpt/core.h
+++ b/sound/soc/intel/catpt/core.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright(c) 2020 Intel Corporation. All rights reserved.
+ * Copyright(c) 2020 Intel Corporation
*
* Author: Cezary Rojewski <cezary.rojewski@intel.com>
*/
diff --git a/sound/soc/intel/catpt/device.c b/sound/soc/intel/catpt/device.c
index cac3dffbd0d9..faa916f40069 100644
--- a/sound/soc/intel/catpt/device.c
+++ b/sound/soc/intel/catpt/device.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
//
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
//
@@ -28,7 +28,7 @@
#define CREATE_TRACE_POINTS
#include "trace.h"
-static int __maybe_unused catpt_suspend(struct device *dev)
+static int catpt_suspend(struct device *dev)
{
struct catpt_dev *cdev = dev_get_drvdata(dev);
struct dma_chan *chan;
@@ -72,7 +72,7 @@ release_dma_chan:
return catpt_dsp_power_down(cdev);
}
-static int __maybe_unused catpt_resume(struct device *dev)
+static int catpt_resume(struct device *dev)
{
struct catpt_dev *cdev = dev_get_drvdata(dev);
int ret, i;
@@ -106,7 +106,7 @@ static int __maybe_unused catpt_resume(struct device *dev)
return 0;
}
-static int __maybe_unused catpt_runtime_suspend(struct device *dev)
+static int catpt_runtime_suspend(struct device *dev)
{
if (!try_module_get(dev->driver->owner)) {
dev_info(dev, "module unloading, skipping suspend\n");
@@ -117,14 +117,14 @@ static int __maybe_unused catpt_runtime_suspend(struct device *dev)
return catpt_suspend(dev);
}
-static int __maybe_unused catpt_runtime_resume(struct device *dev)
+static int catpt_runtime_resume(struct device *dev)
{
return catpt_resume(dev);
}
static const struct dev_pm_ops catpt_dev_pm = {
- SET_SYSTEM_SLEEP_PM_OPS(catpt_suspend, catpt_resume)
- SET_RUNTIME_PM_OPS(catpt_runtime_suspend, catpt_runtime_resume, NULL)
+ SYSTEM_SLEEP_PM_OPS(catpt_suspend, catpt_resume)
+ RUNTIME_PM_OPS(catpt_runtime_suspend, catpt_runtime_resume, NULL)
};
/* machine board owned by CATPT is removed with this hook */
@@ -374,11 +374,11 @@ MODULE_DEVICE_TABLE(acpi, catpt_ids);
static struct platform_driver catpt_acpi_driver = {
.probe = catpt_acpi_probe,
- .remove_new = catpt_acpi_remove,
+ .remove = catpt_acpi_remove,
.driver = {
.name = "intel_catpt",
.acpi_match_table = catpt_ids,
- .pm = &catpt_dev_pm,
+ .pm = pm_ptr(&catpt_dev_pm),
.dev_groups = catpt_attr_groups,
},
};
diff --git a/sound/soc/intel/catpt/dsp.c b/sound/soc/intel/catpt/dsp.c
index 5454c6d9ab5b..008a20a2acbd 100644
--- a/sound/soc/intel/catpt/dsp.c
+++ b/sound/soc/intel/catpt/dsp.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
//
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
//
@@ -156,7 +156,7 @@ static void catpt_dsp_set_srampge(struct catpt_dev *cdev, struct resource *sram,
{
unsigned long old;
u32 off = sram->start;
- u32 b = __ffs(mask);
+ unsigned long b = __ffs(mask);
old = catpt_readl_pci(cdev, VDRTCTL0) & mask;
dev_dbg(cdev->dev, "SRAMPGE [0x%08lx] 0x%08lx -> 0x%08lx",
diff --git a/sound/soc/intel/catpt/ipc.c b/sound/soc/intel/catpt/ipc.c
index 5b718a846fda..d26863249097 100644
--- a/sound/soc/intel/catpt/ipc.c
+++ b/sound/soc/intel/catpt/ipc.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
//
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
//
diff --git a/sound/soc/intel/catpt/loader.c b/sound/soc/intel/catpt/loader.c
index ff7b8f0d34ac..696d84314eeb 100644
--- a/sound/soc/intel/catpt/loader.c
+++ b/sound/soc/intel/catpt/loader.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
//
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
//
diff --git a/sound/soc/intel/catpt/messages.c b/sound/soc/intel/catpt/messages.c
index a793d114afa4..30eec2de4dc1 100644
--- a/sound/soc/intel/catpt/messages.c
+++ b/sound/soc/intel/catpt/messages.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
//
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
//
diff --git a/sound/soc/intel/catpt/messages.h b/sound/soc/intel/catpt/messages.h
index c17e948d9f52..a634943eb669 100644
--- a/sound/soc/intel/catpt/messages.h
+++ b/sound/soc/intel/catpt/messages.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright(c) 2020 Intel Corporation. All rights reserved.
+ * Copyright(c) 2020 Intel Corporation
*
* Author: Cezary Rojewski <cezary.rojewski@intel.com>
*/
diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c
index 3daf5eb37f7b..81a2f0339e05 100644
--- a/sound/soc/intel/catpt/pcm.c
+++ b/sound/soc/intel/catpt/pcm.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
//
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
//
diff --git a/sound/soc/intel/catpt/registers.h b/sound/soc/intel/catpt/registers.h
index 47280d82842e..6c1ad28c6d69 100644
--- a/sound/soc/intel/catpt/registers.h
+++ b/sound/soc/intel/catpt/registers.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright(c) 2020 Intel Corporation. All rights reserved.
+ * Copyright(c) 2020 Intel Corporation
*
* Author: Cezary Rojewski <cezary.rojewski@intel.com>
*/
diff --git a/sound/soc/intel/catpt/sysfs.c b/sound/soc/intel/catpt/sysfs.c
index 9b6d2d93a2e7..936ac9d503ff 100644
--- a/sound/soc/intel/catpt/sysfs.c
+++ b/sound/soc/intel/catpt/sysfs.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
//
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
//
diff --git a/sound/soc/intel/catpt/trace.h b/sound/soc/intel/catpt/trace.h
index bb3d627dbeaf..010f57b6a7a8 100644
--- a/sound/soc/intel/catpt/trace.h
+++ b/sound/soc/intel/catpt/trace.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright(c) 2020 Intel Corporation. All rights reserved.
+ * Copyright(c) 2020 Intel Corporation
*
* Author: Cezary Rojewski <cezary.rojewski@intel.com>
*/
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
index f7370e5b4e9e..7822bcae6c69 100644
--- a/sound/soc/intel/common/Makefile
+++ b/sound/soc/intel/common/Makefile
@@ -1,7 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-soc-sst-dsp-objs := sst-dsp.o
-snd-soc-sst-ipc-objs := sst-ipc.o
-snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-match.o \
+snd-soc-acpi-intel-match-y := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-match.o \
soc-acpi-intel-hsw-bdw-match.o \
soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \
soc-acpi-intel-bxt-match.o soc-acpi-intel-glk-match.o \
@@ -12,8 +10,13 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m
soc-acpi-intel-rpl-match.o soc-acpi-intel-mtl-match.o \
soc-acpi-intel-arl-match.o \
soc-acpi-intel-lnl-match.o \
+ soc-acpi-intel-ptl-match.o \
soc-acpi-intel-hda-match.o \
- soc-acpi-intel-sdw-mockup-match.o
+ soc-acpi-intel-sdw-mockup-match.o sof-function-topology-lib.o
+
+snd-soc-acpi-intel-match-y += soc-acpi-intel-ssp-common.o
+
+snd-soc-acpi-intel-sdca-quirks-y += soc-acpi-intel-sdca-quirks.o
-obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
obj-$(CONFIG_SND_SOC_ACPI_INTEL_MATCH) += snd-soc-acpi-intel-match.o
+obj-$(CONFIG_SND_SOC_ACPI_INTEL_SDCA_QUIRKS) += snd-soc-acpi-intel-sdca-quirks.o
diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c
index 0da79a3ba1f0..a68efbe98948 100644
--- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c
@@ -7,6 +7,7 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
+#include <sound/soc-acpi-intel-ssp-common.h>
static const struct snd_soc_acpi_codecs essx_83x6 = {
.num_codecs = 3,
@@ -34,6 +35,86 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
.group_id = 1,
};
+static const struct snd_soc_acpi_endpoint spk_2_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 2,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_3_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 3,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_2_r_adr[] = {
+ {
+ .adr = 0x00023201FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP3"
+ },
+ {
+ .adr = 0x00023301FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_3_endpoint,
+ .name_prefix = "AMP4"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_3_l_adr[] = {
+ {
+ .adr = 0x00033001fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00033101fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_2_endpoint,
+ .name_prefix = "AMP2"
+ }
+};
+
+static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
+ { /* Jack Playback Endpoint */
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* DMIC Capture Endpoint */
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Jack Capture Endpoint */
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Speaker Playback Endpoint */
+ .num = 3,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = {
+ {
+ .adr = 0x00003001FA424301ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
+ .endpoints = cs42l43_endpoints,
+ .name_prefix = "cs42l43"
+ }
+};
+
static const struct snd_soc_acpi_adr_device rt711_0_adr[] = {
{
.adr = 0x000020025D071100ull,
@@ -133,6 +214,15 @@ static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = {
}
};
+static const struct snd_soc_acpi_adr_device rt1316_2_group2_adr[] = {
+ {
+ .adr = 0x000232025D131601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "rt1316-2"
+ }
+};
+
static const struct snd_soc_acpi_adr_device rt1316_1_single_adr[] = {
{
.adr = 0x000130025D131601ull,
@@ -415,6 +505,25 @@ static const struct snd_soc_acpi_adr_device rt5682_0_adr[] = {
}
};
+static const struct snd_soc_acpi_link_adr adl_cs42l43_l0_cs35l56_l23[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_0_adr),
+ .adr_d = cs42l43_0_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(cs35l56_2_r_adr),
+ .adr_d = cs35l56_2_r_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(cs35l56_3_l_adr),
+ .adr_d = cs35l56_3_l_adr,
+ },
+ {}
+};
+
static const struct snd_soc_acpi_link_adr adl_rvp[] = {
{
.mask = BIT(0),
@@ -447,9 +556,18 @@ static const struct snd_soc_acpi_link_adr adl_chromebook_base[] = {
{}
};
-static const struct snd_soc_acpi_codecs adl_max98373_amp = {
- .num_codecs = 1,
- .codecs = {"MX98373"}
+static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link02[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt1316_0_group2_adr),
+ .adr_d = rt1316_0_group2_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt1316_2_group2_adr),
+ .adr_d = rt1316_2_group2_adr,
+ },
+ {}
};
static const struct snd_soc_acpi_codecs adl_max98357a_amp = {
@@ -457,19 +575,9 @@ static const struct snd_soc_acpi_codecs adl_max98357a_amp = {
.codecs = {"MX98357A"}
};
-static const struct snd_soc_acpi_codecs adl_max98360a_amp = {
- .num_codecs = 1,
- .codecs = {"MX98360A"}
-};
-
static const struct snd_soc_acpi_codecs adl_rt5682_rt5682s_hp = {
.num_codecs = 2,
- .codecs = {"10EC5682", "RTL5682"},
-};
-
-static const struct snd_soc_acpi_codecs adl_rt1015p_amp = {
- .num_codecs = 1,
- .codecs = {"RTL1015"}
+ .codecs = {RT5682_ACPI_HID, RT5682S_ACPI_HID},
};
static const struct snd_soc_acpi_codecs adl_rt1019p_amp = {
@@ -477,49 +585,20 @@ static const struct snd_soc_acpi_codecs adl_rt1019p_amp = {
.codecs = {"RTL1019"}
};
-static const struct snd_soc_acpi_codecs adl_max98390_amp = {
- .num_codecs = 1,
- .codecs = {"MX98390"}
-};
-
static const struct snd_soc_acpi_codecs adl_lt6911_hdmi = {
.num_codecs = 1,
.codecs = {"INTC10B0"}
};
-static const struct snd_soc_acpi_codecs adl_nau8318_amp = {
- .num_codecs = 1,
- .codecs = {"NVTN2012"}
-};
-
-static struct snd_soc_acpi_codecs adl_rt5650_amp = {
- .num_codecs = 1,
- .codecs = {"10EC5650"}
-};
-
struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = {
{
.comp_ids = &adl_rt5682_rt5682s_hp,
- .drv_name = "adl_rt5682_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &adl_max98373_amp,
- .sof_tplg_filename = "sof-adl-max98373-rt5682.tplg",
- },
- {
- .comp_ids = &adl_rt5682_rt5682s_hp,
.drv_name = "adl_mx98357_rt5682",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &adl_max98357a_amp,
.sof_tplg_filename = "sof-adl-max98357a-rt5682.tplg",
},
{
- .comp_ids = &adl_rt5682_rt5682s_hp,
- .drv_name = "adl_rt5682_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &adl_max98360a_amp,
- .sof_tplg_filename = "sof-adl-max98360a-rt5682.tplg",
- },
- {
.id = "10508825",
.drv_name = "adl_rt1019p_8825",
.machine_quirk = snd_soc_acpi_codec_list,
@@ -527,53 +606,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = {
.sof_tplg_filename = "sof-adl-rt1019-nau8825.tplg",
},
{
- .id = "10508825",
- .drv_name = "adl_nau8825_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &adl_max98373_amp,
- .sof_tplg_filename = "sof-adl-max98373-nau8825.tplg",
- },
- {
- .id = "10508825",
- .drv_name = "adl_nau8825_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &adl_max98360a_amp,
- .sof_tplg_filename = "sof-adl-max98360a-nau8825.tplg",
- },
- {
- .comp_ids = &adl_rt5682_rt5682s_hp,
- .drv_name = "adl_rt5682_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &adl_rt1019p_amp,
- .sof_tplg_filename = "sof-adl-rt1019-rt5682.tplg",
- },
- {
- .id = "10508825",
- .drv_name = "adl_nau8825_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &adl_rt1015p_amp,
- .sof_tplg_filename = "sof-adl-rt1015-nau8825.tplg",
- },
- {
- .id = "10508825",
- .drv_name = "adl_nau8825_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &adl_nau8318_amp,
- .sof_tplg_filename = "sof-adl-nau8318-nau8825.tplg",
- },
- {
- .id = "10508825",
- .drv_name = "sof_nau8825",
- .sof_tplg_filename = "sof-adl-nau8825.tplg",
- },
- {
- .comp_ids = &adl_rt5682_rt5682s_hp,
- .drv_name = "adl_rt5682_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &adl_max98390_amp,
- .sof_tplg_filename = "sof-adl-max98390-rt5682.tplg",
- },
- {
.comp_ids = &adl_rt5682_rt5682s_hp,
.drv_name = "adl_rt5682_c1_h02",
.machine_quirk = snd_soc_acpi_codec_list,
@@ -581,18 +613,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = {
.sof_tplg_filename = "sof-adl-rt5682-ssp1-hdmi-ssp02.tplg",
},
{
- .comp_ids = &adl_rt5682_rt5682s_hp,
- .drv_name = "adl_rt5682_def",
- .sof_tplg_filename = "sof-adl-rt5682.tplg",
- },
- {
- .id = "10134242",
- .drv_name = "adl_mx98360a_cs4242",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &adl_max98360a_amp,
- .sof_tplg_filename = "sof-adl-max98360a-cs42l42.tplg",
- },
- {
.comp_ids = &essx_83x6,
.drv_name = "adl_es83x6_c1_h02",
.machine_quirk = snd_soc_acpi_codec_list,
@@ -607,19 +627,43 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = {
SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
+ /* place boards for each headphone codec: sof driver will complete the
+ * tplg name and machine driver will detect the amp type
+ */
+ {
+ .id = CS42L42_ACPI_HID,
+ .drv_name = "adl_cs42l42_def",
+ .sof_tplg_filename = "sof-adl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ {
+ .id = DA7219_ACPI_HID,
+ .drv_name = "adl_da7219_def",
+ .sof_tplg_filename = "sof-adl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
{
- .id = "10EC5650",
+ .id = NAU8825_ACPI_HID,
+ .drv_name = "adl_nau8825_def",
+ .sof_tplg_filename = "sof-adl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ {
+ .id = RT5650_ACPI_HID,
.drv_name = "adl_rt5682_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &adl_rt5650_amp,
- .sof_tplg_filename = "sof-adl-rt5650.tplg",
+ .sof_tplg_filename = "sof-adl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
},
{
- .id = "DLGS7219",
- .drv_name = "adl_mx98360_da7219",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &adl_max98360a_amp,
- .sof_tplg_filename = "sof-adl-max98360a-da7219.tplg",
+ .comp_ids = &adl_rt5682_rt5682s_hp,
+ .drv_name = "adl_rt5682_def",
+ .sof_tplg_filename = "sof-adl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
},
/* place amp-only boards in the end of table */
{
@@ -639,6 +683,12 @@ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_adl_machines);
/* this table is used when there is no I2S codec present */
struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = {
{
+ .link_mask = BIT(0) | BIT(2) | BIT(3),
+ .links = adl_cs42l43_l0_cs35l56_l23,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-adl-cs42l43-l0-cs35l56-l23.tplg",
+ },
+ {
.link_mask = 0xF, /* 4 active links required */
.links = adl_default,
.drv_name = "sof_sdw",
@@ -722,6 +772,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = {
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-adl-sdw-max98373-rt5682.tplg",
},
+ {
+ .link_mask = BIT(0) | BIT(2),
+ .links = adl_sdw_rt1316_link02,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-adl-rt1316-l02.tplg",
+ },
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_adl_sdw_machines);
diff --git a/sound/soc/intel/common/soc-acpi-intel-arl-match.c b/sound/soc/intel/common/soc-acpi-intel-arl-match.c
index e52797aae6e6..73e581e93755 100644
--- a/sound/soc/intel/common/soc-acpi-intel-arl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-arl-match.c
@@ -7,6 +7,8 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
+#include <sound/soc-acpi-intel-ssp-common.h>
+#include "sof-function-topology-lib.h"
static const struct snd_soc_acpi_endpoint single_endpoint = {
.num = 0,
@@ -15,6 +17,200 @@ static const struct snd_soc_acpi_endpoint single_endpoint = {
.group_id = 0,
};
+static const struct snd_soc_acpi_endpoint spk_l_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_2_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 2,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_3_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 3,
+ .group_id = 1,
+};
+
+/*
+ * RT722 is a multi-function codec, three endpoints are created for
+ * its headset, amp and dmic functions.
+ */
+static const struct snd_soc_acpi_endpoint rt722_endpoints[] = {
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ {
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ {
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_2_lr_adr[] = {
+ {
+ .adr = 0x00023001FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00023101FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP2"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_3_lr_adr[] = {
+ {
+ .adr = 0x00033001FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00033401FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP2"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_2_r_adr[] = {
+ {
+ .adr = 0x00023201FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP3"
+ },
+ {
+ .adr = 0x00023301FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_3_endpoint,
+ .name_prefix = "AMP4"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_3_l_adr[] = {
+ {
+ .adr = 0x00033001fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00033101fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_2_endpoint,
+ .name_prefix = "AMP2"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_2_r1_adr[] = {
+ {
+ .adr = 0x00023101FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP2"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_3_l3_adr[] = {
+ {
+ .adr = 0x00033301fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_2_r3_adr[] = {
+ {
+ .adr = 0x00023301fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP2"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_3_l1_adr[] = {
+ {
+ .adr = 0x00033101fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
+ { /* Jack Playback Endpoint */
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* DMIC Capture Endpoint */
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Jack Capture Endpoint */
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Speaker Playback Endpoint */
+ .num = 3,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = {
+ {
+ .adr = 0x00003001FA424301ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
+ .endpoints = cs42l43_endpoints,
+ .name_prefix = "cs42l43"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = {
+ {
+ .adr = 0x00023001FA424301ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
+ .endpoints = cs42l43_endpoints,
+ .name_prefix = "cs42l43"
+ }
+};
+
static const struct snd_soc_acpi_adr_device rt711_0_adr[] = {
{
.adr = 0x000020025D071100ull,
@@ -24,6 +220,136 @@ static const struct snd_soc_acpi_adr_device rt711_0_adr[] = {
}
};
+static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = {
+ {
+ .adr = 0x000030025D071101ull,
+ .num_endpoints = 1,
+ .endpoints = &single_endpoint,
+ .name_prefix = "rt711"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = {
+ {
+ .adr = 0x000030025D072201ull,
+ .num_endpoints = ARRAY_SIZE(rt722_endpoints),
+ .endpoints = rt722_endpoints,
+ .name_prefix = "rt722"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1320_2_single_adr[] = {
+ {
+ .adr = 0x000230025D132001ull,
+ .num_endpoints = 1,
+ .endpoints = &single_endpoint,
+ .name_prefix = "rt1320-1"
+ }
+};
+
+static const struct snd_soc_acpi_link_adr arl_cs42l43_l0[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_0_adr),
+ .adr_d = cs42l43_0_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr arl_cs42l43_l2[] = {
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(cs42l43_2_adr),
+ .adr_d = cs42l43_2_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr arl_cs42l43_l2_cs35l56_l3[] = {
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(cs42l43_2_adr),
+ .adr_d = cs42l43_2_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(cs35l56_3_lr_adr),
+ .adr_d = cs35l56_3_lr_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_l2[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_0_adr),
+ .adr_d = cs42l43_0_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(cs35l56_2_lr_adr),
+ .adr_d = cs35l56_2_lr_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_l23[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_0_adr),
+ .adr_d = cs42l43_0_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(cs35l56_2_r_adr),
+ .adr_d = cs35l56_2_r_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(cs35l56_3_l_adr),
+ .adr_d = cs35l56_3_l_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_2_l23[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_0_adr),
+ .adr_d = cs42l43_0_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(cs35l56_2_r1_adr),
+ .adr_d = cs35l56_2_r1_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(cs35l56_3_l3_adr),
+ .adr_d = cs35l56_3_l3_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_3_l23[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_0_adr),
+ .adr_d = cs42l43_0_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(cs35l56_2_r3_adr),
+ .adr_d = cs35l56_2_r3_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(cs35l56_3_l1_adr),
+ .adr_d = cs35l56_3_l1_adr,
+ },
+ {}
+};
+
static const struct snd_soc_acpi_link_adr arl_rvp[] = {
{
.mask = BIT(0),
@@ -33,7 +359,73 @@ static const struct snd_soc_acpi_link_adr arl_rvp[] = {
{}
};
+static const struct snd_soc_acpi_link_adr arl_sdca_rvp[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt711_sdca_0_adr),
+ .adr_d = rt711_sdca_0_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr arl_rt722_l0_rt1320_l2[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt722_0_single_adr),
+ .adr_d = rt722_0_single_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt1320_2_single_adr),
+ .adr_d = rt1320_2_single_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_codecs arl_essx_83x6 = {
+ .num_codecs = 3,
+ .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
+};
+
+static const struct snd_soc_acpi_codecs arl_rt5682_hp = {
+ .num_codecs = 2,
+ .codecs = {RT5682_ACPI_HID, RT5682S_ACPI_HID},
+};
+
+static const struct snd_soc_acpi_codecs arl_lt6911_hdmi = {
+ .num_codecs = 1,
+ .codecs = {"INTC10B0"}
+};
+
struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_machines[] = {
+ {
+ .comp_ids = &arl_essx_83x6,
+ .drv_name = "arl_es83x6_c1_h02",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &arl_lt6911_hdmi,
+ .sof_tplg_filename = "sof-arl-es83x6-ssp1-hdmi-ssp02.tplg",
+ },
+ {
+ .comp_ids = &arl_essx_83x6,
+ .drv_name = "sof-essx8336",
+ .sof_tplg_filename = "sof-arl-es8336", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
+ SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
+ SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
+ },
+ {
+ .comp_ids = &arl_rt5682_hp,
+ .drv_name = "arl_rt5682_c1_h02",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &arl_lt6911_hdmi,
+ .sof_tplg_filename = "sof-arl-rt5682-ssp1-hdmi-ssp02.tplg",
+ },
+ /* place amp-only boards in the end of table */
+ {
+ .id = "INTC10B0",
+ .drv_name = "arl_lt6911_hdmi_ssp",
+ .sof_tplg_filename = "sof-arl-hdmi-ssp02.tplg",
+ },
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_arl_machines);
@@ -41,11 +433,73 @@ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_arl_machines);
/* this table is used when there is no I2S codec present */
struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = {
{
+ .link_mask = BIT(0) | BIT(2) | BIT(3),
+ .links = arl_cs42l43_l0_cs35l56_l23,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(0) | BIT(2) | BIT(3),
+ .links = arl_cs42l43_l0_cs35l56_2_l23,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(0) | BIT(2) | BIT(3),
+ .links = arl_cs42l43_l0_cs35l56_3_l23,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(0) | BIT(2),
+ .links = arl_cs42l43_l0_cs35l56_l2,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l2.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(0),
+ .links = arl_cs42l43_l0,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-arl-cs42l43-l0.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(2),
+ .links = arl_cs42l43_l2,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-arl-cs42l43-l2.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(2) | BIT(3),
+ .links = arl_cs42l43_l2_cs35l56_l3,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-arl-cs42l43-l2-cs35l56-l3.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
.link_mask = 0x1, /* link0 required */
.links = arl_rvp,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-arl-rt711.tplg",
},
+ {
+ .link_mask = 0x1, /* link0 required */
+ .links = arl_sdca_rvp,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-arl-rt711-l0.tplg",
+ },
+ {
+ .link_mask = BIT(0) | BIT(2),
+ .links = arl_rt722_l0_rt1320_l2,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-arl-rt722-l0_rt1320-l2.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_arl_sdw_machines);
diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c
index 5e2ec60e2954..e4c3492a0c28 100644
--- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c
@@ -84,7 +84,6 @@ static const struct dmi_system_id lenovo_yoga_tab3_x90[] = {
/* Lenovo Yoga Tab 3 Pro YT3-X90, codec missing from DSDT */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
},
},
diff --git a/sound/soc/intel/common/soc-acpi-intel-cml-match.c b/sound/soc/intel/common/soc-acpi-intel-cml-match.c
index 5eab17820532..f79d7558174a 100644
--- a/sound/soc/intel/common/soc-acpi-intel-cml-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-cml-match.c
@@ -42,40 +42,40 @@ static const struct snd_soc_acpi_codecs max98390_spk_codecs = {
struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_machines[] = {
{
.id = "10EC5682",
- .drv_name = "cml_rt1011_rt5682",
+ .drv_name = "cml_rt5682_def",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &rt1011_spk_codecs,
.sof_tplg_filename = "sof-cml-rt1011-rt5682.tplg",
},
{
.id = "10EC5682",
- .drv_name = "cml_rt1015_rt5682",
+ .drv_name = "cml_rt5682_def",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &rt1015_spk_codecs,
.sof_tplg_filename = "sof-cml-rt1011-rt5682.tplg",
},
{
.id = "10EC5682",
- .drv_name = "sof_rt5682",
+ .drv_name = "cml_rt5682_def",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &max98357a_spk_codecs,
.sof_tplg_filename = "sof-cml-rt5682-max98357a.tplg",
},
{
.id = "10EC5682",
- .drv_name = "sof_rt5682",
+ .drv_name = "cml_rt5682_def",
.sof_tplg_filename = "sof-cml-rt5682.tplg",
},
{
.id = "DLGS7219",
- .drv_name = "cml_da7219_mx98357a",
+ .drv_name = "cml_da7219_def",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &max98357a_spk_codecs,
.sof_tplg_filename = "sof-cml-da7219-max98357a.tplg",
},
{
.id = "DLGS7219",
- .drv_name = "cml_da7219_mx98357a",
+ .drv_name = "cml_da7219_def",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &max98390_spk_codecs,
.sof_tplg_filename = "sof-cml-da7219-max98390.tplg",
diff --git a/sound/soc/intel/common/soc-acpi-intel-cnl-match.c b/sound/soc/intel/common/soc-acpi-intel-cnl-match.c
index 3df89e4511da..8bbb1052faf2 100644
--- a/sound/soc/intel/common/soc-acpi-intel-cnl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-cnl-match.c
@@ -8,7 +8,6 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
-#include "../skylake/skl.h"
#include "soc-acpi-intel-sdw-mockup-match.h"
static const struct snd_soc_acpi_codecs essx_83x6 = {
@@ -16,16 +15,11 @@ static const struct snd_soc_acpi_codecs essx_83x6 = {
.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
};
-static struct skl_machine_pdata cnl_pdata = {
- .use_tplg_pcm = true,
-};
-
struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = {
{
.id = "INT34C2",
.drv_name = "cnl_rt274",
.fw_filename = "intel/dsp_fw_cnl.bin",
- .pdata = &cnl_pdata,
.sof_tplg_filename = "sof-cnl-rt274.tplg",
},
{
diff --git a/sound/soc/intel/common/soc-acpi-intel-ehl-match.c b/sound/soc/intel/common/soc-acpi-intel-ehl-match.c
index 84639c41a268..78255d56b08c 100644
--- a/sound/soc/intel/common/soc-acpi-intel-ehl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-ehl-match.c
@@ -8,7 +8,6 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
-#include "../skylake/skl.h"
struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[] = {
{
diff --git a/sound/soc/intel/common/soc-acpi-intel-glk-match.c b/sound/soc/intel/common/soc-acpi-intel-glk-match.c
index 8911c90bbaf6..c82c8c93d200 100644
--- a/sound/soc/intel/common/soc-acpi-intel-glk-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-glk-match.c
@@ -33,7 +33,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[] = {
},
{
.id = "DLGS7219",
- .drv_name = "glk_da7219_mx98357a",
+ .drv_name = "glk_da7219_def",
.fw_filename = "intel/dsp_fw_glk.bin",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &glk_codecs,
@@ -41,7 +41,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[] = {
},
{
.comp_ids = &glk_rt5682_rt5682s_hp,
- .drv_name = "glk_rt5682_mx98357a",
+ .drv_name = "glk_rt5682_def",
.fw_filename = "intel/dsp_fw_glk.bin",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &glk_codecs,
diff --git a/sound/soc/intel/common/soc-acpi-intel-hda-match.c b/sound/soc/intel/common/soc-acpi-intel-hda-match.c
index 2017fd0d676f..e93336e27beb 100644
--- a/sound/soc/intel/common/soc-acpi-intel-hda-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-hda-match.c
@@ -8,27 +8,13 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
-#include "../skylake/skl.h"
-
-static struct skl_machine_pdata hda_pdata = {
- .use_tplg_pcm = true,
-};
struct snd_soc_acpi_mach snd_soc_acpi_intel_hda_machines[] = {
{
/* .id is not used in this file */
.drv_name = "skl_hda_dsp_generic",
-
- /* .fw_filename is dynamically set in skylake driver */
-
- .sof_tplg_filename = "sof-hda-generic.tplg",
-
- /*
- * .machine_quirk and .quirk_data are not used here but
- * can be used if we need a more complicated machine driver
- * combining HDA+other device (e.g. DMIC).
- */
- .pdata = &hda_pdata,
+ .sof_tplg_filename = "sof-hda-generic", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
{},
};
diff --git a/sound/soc/intel/common/soc-acpi-intel-icl-match.c b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
index d0062f2cd256..6ce75fbb842e 100644
--- a/sound/soc/intel/common/soc-acpi-intel-icl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
@@ -8,28 +8,22 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
-#include "../skylake/skl.h"
static const struct snd_soc_acpi_codecs essx_83x6 = {
.num_codecs = 3,
.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
};
-static struct skl_machine_pdata icl_pdata = {
- .use_tplg_pcm = true,
-};
-
struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[] = {
{
.id = "INT34C2",
.drv_name = "icl_rt274",
.fw_filename = "intel/dsp_fw_icl.bin",
- .pdata = &icl_pdata,
.sof_tplg_filename = "sof-icl-rt274.tplg",
},
{
.id = "10EC5682",
- .drv_name = "sof_rt5682",
+ .drv_name = "icl_rt5682_def",
.sof_tplg_filename = "sof-icl-rt5682.tplg",
},
{
diff --git a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c
index a6ac2525df17..d4b397c53bcc 100644
--- a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c
@@ -52,14 +52,14 @@ static const struct snd_soc_acpi_codecs rt5682_rt5682s_hp = {
struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = {
{
.id = "DLGS7219",
- .drv_name = "jsl_mx98373_da7219",
+ .drv_name = "jsl_da7219_def",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &mx98373_spk,
.sof_tplg_filename = "sof-jsl-da7219.tplg",
},
{
.id = "DLGS7219",
- .drv_name = "jsl_mx98360_da7219",
+ .drv_name = "jsl_da7219_def",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &mx98360a_spk,
.sof_tplg_filename = "sof-jsl-da7219-mx98360a.tplg",
diff --git a/sound/soc/intel/common/soc-acpi-intel-kbl-match.c b/sound/soc/intel/common/soc-acpi-intel-kbl-match.c
index 4e817f559d38..d4c158d8441b 100644
--- a/sound/soc/intel/common/soc-acpi-intel-kbl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-kbl-match.c
@@ -8,9 +8,6 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
-#include "../skylake/skl.h"
-
-static struct skl_machine_pdata skl_dmic_data;
static const struct snd_soc_acpi_codecs kbl_codecs = {
.num_codecs = 1,
@@ -54,7 +51,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = {
.fw_filename = "intel/dsp_fw_kbl.bin",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &kbl_codecs,
- .pdata = &skl_dmic_data,
},
{
.id = "MX98357A",
@@ -62,7 +58,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = {
.fw_filename = "intel/dsp_fw_kbl.bin",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &kbl_codecs,
- .pdata = &skl_dmic_data,
},
{
.id = "MX98927",
@@ -70,7 +65,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = {
.fw_filename = "intel/dsp_fw_kbl.bin",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &kbl_5663_5514_codecs,
- .pdata = &skl_dmic_data,
},
{
.id = "MX98927",
@@ -78,7 +72,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = {
.fw_filename = "intel/dsp_fw_kbl.bin",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &kbl_poppy_codecs,
- .pdata = &skl_dmic_data,
},
{
.id = "10EC5663",
@@ -91,7 +84,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = {
.fw_filename = "intel/dsp_fw_kbl.bin",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &kbl_7219_98357_codecs,
- .pdata = &skl_dmic_data,
},
{
.id = "DLGS7219",
@@ -99,7 +91,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = {
.fw_filename = "intel/dsp_fw_kbl.bin",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &kbl_7219_98927_codecs,
- .pdata = &skl_dmic_data
},
{
.id = "10EC5660",
@@ -117,13 +108,11 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = {
.fw_filename = "intel/dsp_fw_kbl.bin",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &kbl_7219_98373_codecs,
- .pdata = &skl_dmic_data
},
{
.id = "MX98373",
.drv_name = "kbl_max98373",
.fw_filename = "intel/dsp_fw_kbl.bin",
- .pdata = &skl_dmic_data
},
{},
};
diff --git a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c
index 74d6dcd7471f..558dc4c91239 100644
--- a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c
@@ -2,12 +2,14 @@
/*
* soc-acpi-intel-lnl-match.c - tables and support for LNL ACPI enumeration.
*
- * Copyright (c) 2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2023, Intel Corporation
*
*/
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
+#include "sof-function-topology-lib.h"
+#include "soc-acpi-intel-sdca-quirks.h"
#include "soc-acpi-intel-sdw-mockup-match.h"
struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_machines[] = {
@@ -36,6 +38,48 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
.group_id = 1,
};
+static const struct snd_soc_acpi_endpoint spk_1_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_2_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 2,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_3_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 3,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_4_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 4,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_5_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 5,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_6_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 6,
+ .group_id = 1,
+};
+
static const struct snd_soc_acpi_endpoint rt712_endpoints[] = {
{
.num = 0,
@@ -76,6 +120,206 @@ static const struct snd_soc_acpi_endpoint rt722_endpoints[] = {
},
};
+static const struct snd_soc_acpi_endpoint jack_dmic_endpoints[] = {
+ /* Jack Endpoint */
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ /* DMIC Endpoint */
+ {
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint jack_amp_g1_dmic_endpoints[] = {
+ /* Jack Endpoint */
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ /* Amp Endpoint, work as spk_l_endpoint */
+ {
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 1,
+ },
+ /* DMIC Endpoint */
+ {
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
+ { /* Jack Playback Endpoint */
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* DMIC Capture Endpoint */
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Jack Capture Endpoint */
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Speaker Playback Endpoint */
+ .num = 3,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs42l43_amp_spkagg_endpoints[] = {
+ { /* Jack Playback Endpoint */
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* DMIC Capture Endpoint */
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Jack Capture Endpoint */
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Speaker Playback Endpoint */
+ .num = 3,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 1,
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_2_l_adr[] = {
+ {
+ .adr = 0x00023001FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00023101FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_2_endpoint,
+ .name_prefix = "AMP2"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_3_r_adr[] = {
+ {
+ .adr = 0x00033201fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP3"
+ },
+ {
+ .adr = 0x00033301fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_3_endpoint,
+ .name_prefix = "AMP4"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_3_lr_adr[] = {
+ {
+ .adr = 0x00033001fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00033101fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "AMP2"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_1_3amp_adr[] = {
+ {
+ .adr = 0x00013001fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_1_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00013101fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_2_endpoint,
+ .name_prefix = "AMP2"
+ },
+ {
+ .adr = 0x00013201fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_3_endpoint,
+ .name_prefix = "AMP3"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_3_3amp_adr[] = {
+ {
+ .adr = 0x00033301fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_4_endpoint,
+ .name_prefix = "AMP4"
+ },
+ {
+ .adr = 0x00033401fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_5_endpoint,
+ .name_prefix = "AMP5"
+ },
+ {
+ .adr = 0x00033501fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_6_endpoint,
+ .name_prefix = "AMP6"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = {
+ {
+ .adr = 0x00003001FA424301ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
+ .endpoints = cs42l43_endpoints,
+ .name_prefix = "cs42l43"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = {
+ {
+ .adr = 0x00023001fa424301ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_amp_spkagg_endpoints),
+ .endpoints = cs42l43_amp_spkagg_endpoints,
+ .name_prefix = "cs42l43"
+ }
+};
+
static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = {
{
.adr = 0x000030025D071101ull,
@@ -103,6 +347,15 @@ static const struct snd_soc_acpi_adr_device rt1712_3_single_adr[] = {
}
};
+static const struct snd_soc_acpi_adr_device rt712_vb_2_group1_adr[] = {
+ {
+ .adr = 0x000230025D071201ull,
+ .num_endpoints = ARRAY_SIZE(jack_amp_g1_dmic_endpoints),
+ .endpoints = jack_amp_g1_dmic_endpoints,
+ .name_prefix = "rt712"
+ }
+};
+
static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = {
{
.adr = 0x000030025d072201ull,
@@ -130,6 +383,87 @@ static const struct snd_soc_acpi_adr_device rt1316_3_group1_adr[] = {
}
};
+static const struct snd_soc_acpi_adr_device rt1318_1_adr[] = {
+ {
+ .adr = 0x000133025D131801ull,
+ .num_endpoints = 1,
+ .endpoints = &single_endpoint,
+ .name_prefix = "rt1318-1"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1318_1_group1_adr[] = {
+ {
+ .adr = 0x000130025D131801ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "rt1318-1"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1318_2_group1_adr[] = {
+ {
+ .adr = 0x000232025D131801ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "rt1318-2"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1320_1_group1_adr[] = {
+ {
+ .adr = 0x000130025D132001ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "rt1320-1"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1320_1_group2_adr[] = {
+ {
+ .adr = 0x000130025D132001ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "rt1320-1"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1320_3_group2_adr[] = {
+ {
+ .adr = 0x000330025D132001ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "rt1320-2"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt713_0_adr[] = {
+ {
+ .adr = 0x000031025D071301ull,
+ .num_endpoints = 1,
+ .endpoints = &single_endpoint,
+ .name_prefix = "rt713"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt713_vb_2_adr[] = {
+ {
+ .adr = 0x000230025d071301ull,
+ .num_endpoints = ARRAY_SIZE(jack_dmic_endpoints),
+ .endpoints = jack_dmic_endpoints,
+ .name_prefix = "rt713"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt714_0_adr[] = {
+ {
+ .adr = 0x000030025D071401ull,
+ .num_endpoints = 1,
+ .endpoints = &single_endpoint,
+ .name_prefix = "rt714"
+ }
+};
+
static const struct snd_soc_acpi_adr_device rt714_1_adr[] = {
{
.adr = 0x000130025D071401ull,
@@ -139,6 +473,67 @@ static const struct snd_soc_acpi_adr_device rt714_1_adr[] = {
}
};
+static const struct snd_soc_acpi_link_adr lnl_cs42l43_l0[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_0_adr),
+ .adr_d = cs42l43_0_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr lnl_cs42l43_l0_cs35l56_l3[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_0_adr),
+ .adr_d = cs42l43_0_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(cs35l56_3_lr_adr),
+ .adr_d = cs35l56_3_lr_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr lnl_cs42l43_l0_cs35l56_l23[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_0_adr),
+ .adr_d = cs42l43_0_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(cs35l56_2_l_adr),
+ .adr_d = cs35l56_2_l_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(cs35l56_3_r_adr),
+ .adr_d = cs35l56_3_r_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr lnl_cs42l43_l2_cs35l56x6_l13[] = {
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(cs42l43_2_adr),
+ .adr_d = cs42l43_2_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs35l56_1_3amp_adr),
+ .adr_d = cs35l56_1_3amp_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(cs35l56_3_3amp_adr),
+ .adr_d = cs35l56_3_3amp_adr,
+ },
+ {}
+};
+
static const struct snd_soc_acpi_link_adr lnl_rvp[] = {
{
.mask = BIT(0),
@@ -195,6 +590,73 @@ static const struct snd_soc_acpi_link_adr lnl_3_in_1_sdca[] = {
{}
};
+static const struct snd_soc_acpi_link_adr lnl_sdw_rt1318_l12_rt714_l0[] = {
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1318_1_group1_adr),
+ .adr_d = rt1318_1_group1_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt1318_2_group1_adr),
+ .adr_d = rt1318_2_group1_adr,
+ },
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt714_0_adr),
+ .adr_d = rt714_0_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr lnl_sdw_rt713_l0_rt1318_l1[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt713_0_adr),
+ .adr_d = rt713_0_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1318_1_adr),
+ .adr_d = rt1318_1_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr lnl_sdw_rt713_vb_l2_rt1320_l13[] = {
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt713_vb_2_adr),
+ .adr_d = rt713_vb_2_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1320_1_group2_adr),
+ .adr_d = rt1320_1_group2_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt1320_3_group2_adr),
+ .adr_d = rt1320_3_group2_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr lnl_sdw_rt712_vb_l2_rt1320_l1[] = {
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt712_vb_2_group1_adr),
+ .adr_d = rt712_vb_2_group1_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1320_1_group1_adr),
+ .adr_d = rt1320_1_group1_adr,
+ },
+ {}
+};
+
+/* this table is used when there is no I2S codec present */
/* this table is used when there is no I2S codec present */
struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = {
/* mockup tests need to be first */
@@ -217,12 +679,43 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = {
.sof_tplg_filename = "sof-lnl-rt715-rt711-rt1308-mono.tplg",
},
{
+ .link_mask = BIT(0),
+ .links = sdw_mockup_multi_func,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-lnl-rt722-l0.tplg", /* Reuse the existing tplg file */
+ },
+ {
.link_mask = GENMASK(3, 0),
.links = lnl_3_in_1_sdca,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-lnl-rt711-l0-rt1316-l23-rt714-l1.tplg",
},
{
+ .link_mask = BIT(0) | BIT(2) | BIT(3),
+ .links = lnl_cs42l43_l0_cs35l56_l23,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-lnl-cs42l43-l0-cs35l56-l23.tplg",
+ },
+ {
+ .link_mask = BIT(1) | BIT(2) | BIT(3),
+ .links = lnl_cs42l43_l2_cs35l56x6_l13,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-lnl-cs42l43-l2-cs35l56x6-l13.tplg",
+ },
+ {
+ .link_mask = BIT(0) | BIT(3),
+ .links = lnl_cs42l43_l0_cs35l56_l3,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-lnl-cs42l43-l0-cs35l56-l3.tplg",
+ },
+ {
+ .link_mask = BIT(0),
+ .links = lnl_cs42l43_l0,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-lnl-cs42l43-l0.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
.link_mask = BIT(0),
.links = lnl_rvp,
.drv_name = "sof_sdw",
@@ -239,6 +732,35 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = {
.links = lnl_rt722_only,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-lnl-rt722-l0.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = GENMASK(2, 0),
+ .links = lnl_sdw_rt1318_l12_rt714_l0,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-lnl-rt1318-l12-rt714-l0.tplg"
+ },
+ {
+ .link_mask = BIT(0) | BIT(1),
+ .links = lnl_sdw_rt713_l0_rt1318_l1,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-lnl-rt713-l0-rt1318-l1.tplg"
+ },
+ {
+ .link_mask = BIT(1) | BIT(2),
+ .links = lnl_sdw_rt712_vb_l2_rt1320_l1,
+ .drv_name = "sof_sdw",
+ .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb,
+ .sof_tplg_filename = "sof-lnl-rt712-l2-rt1320-l1.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(1) | BIT(2) | BIT(3),
+ .links = lnl_sdw_rt713_vb_l2_rt1320_l13,
+ .drv_name = "sof_sdw",
+ .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb,
+ .sof_tplg_filename = "sof-lnl-rt713-l2-rt1320-l13.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
},
{},
};
diff --git a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c
index e9a5da079089..75dc8935a794 100644
--- a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c
@@ -6,28 +6,18 @@
*
*/
+#include <linux/soundwire/sdw_intel.h>
+#include <sound/sdca.h>
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
+#include <sound/soc-acpi-intel-ssp-common.h>
+#include "sof-function-topology-lib.h"
+#include "soc-acpi-intel-sdca-quirks.h"
#include "soc-acpi-intel-sdw-mockup-match.h"
-static const struct snd_soc_acpi_codecs mtl_max98357a_amp = {
- .num_codecs = 1,
- .codecs = {"MX98357A"}
-};
-
-static const struct snd_soc_acpi_codecs mtl_max98360a_amp = {
- .num_codecs = 1,
- .codecs = {"MX98360A"}
-};
-
-static const struct snd_soc_acpi_codecs mtl_rt1019p_amp = {
- .num_codecs = 1,
- .codecs = {"RTL1019"}
-};
-
static const struct snd_soc_acpi_codecs mtl_rt5682_rt5682s_hp = {
.num_codecs = 2,
- .codecs = {"10EC5682", "RTL5682"},
+ .codecs = {RT5682_ACPI_HID, RT5682S_ACPI_HID},
};
static const struct snd_soc_acpi_codecs mtl_essx_83x6 = {
@@ -40,34 +30,8 @@ static const struct snd_soc_acpi_codecs mtl_lt6911_hdmi = {
.codecs = {"INTC10B0"}
};
-static const struct snd_soc_acpi_codecs mtl_rt5650_amp = {
- .num_codecs = 1,
- .codecs = {"10EC5650"}
-};
-
struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[] = {
{
- .comp_ids = &mtl_rt5682_rt5682s_hp,
- .drv_name = "mtl_mx98357_rt5682",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &mtl_max98357a_amp,
- .sof_tplg_filename = "sof-mtl-max98357a-rt5682.tplg",
- },
- {
- .comp_ids = &mtl_rt5682_rt5682s_hp,
- .drv_name = "mtl_mx98360_rt5682",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &mtl_max98360a_amp,
- .sof_tplg_filename = "sof-mtl-max98360a-rt5682.tplg",
- },
- {
- .comp_ids = &mtl_rt5682_rt5682s_hp,
- .drv_name = "mtl_rt5682_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &mtl_rt1019p_amp,
- .sof_tplg_filename = "sof-mtl-rt1019-rt5682.tplg",
- },
- {
.comp_ids = &mtl_essx_83x6,
.drv_name = "mtl_es83x6_c1_h02",
.machine_quirk = snd_soc_acpi_codec_list,
@@ -83,11 +47,49 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[] = {
SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
{
- .id = "10EC5650",
- .drv_name = "mtl_rt5682_def",
+ .comp_ids = &mtl_rt5682_rt5682s_hp,
+ .drv_name = "mtl_rt5682_c1_h02",
.machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &mtl_rt5650_amp,
- .sof_tplg_filename = "sof-mtl-rt5650.tplg",
+ .quirk_data = &mtl_lt6911_hdmi,
+ .sof_tplg_filename = "sof-mtl-rt5682-ssp1-hdmi-ssp02.tplg",
+ },
+ /* place boards for each headphone codec: sof driver will complete the
+ * tplg name and machine driver will detect the amp type
+ */
+ {
+ .id = CS42L42_ACPI_HID,
+ .drv_name = "mtl_cs42l42_def",
+ .sof_tplg_filename = "sof-mtl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ {
+ .id = DA7219_ACPI_HID,
+ .drv_name = "mtl_da7219_def",
+ .sof_tplg_filename = "sof-mtl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ {
+ .id = NAU8825_ACPI_HID,
+ .drv_name = "mtl_nau8825_def",
+ .sof_tplg_filename = "sof-mtl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ {
+ .id = RT5650_ACPI_HID,
+ .drv_name = "mtl_rt5682_def",
+ .sof_tplg_filename = "sof-mtl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ {
+ .comp_ids = &mtl_rt5682_rt5682s_hp,
+ .drv_name = "mtl_rt5682_def",
+ .sof_tplg_filename = "sof-mtl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
},
/* place amp-only boards in the end of table */
{
@@ -135,6 +137,27 @@ static const struct snd_soc_acpi_endpoint rt712_endpoints[] = {
},
};
+static const struct snd_soc_acpi_endpoint rt712_vb_endpoints[] = {
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ {
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ {
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
/*
* RT722 is a multi-function codec, three endpoints are created for
* its headset, amp and dmic functions.
@@ -192,6 +215,15 @@ static const struct snd_soc_acpi_adr_device rt712_0_single_adr[] = {
}
};
+static const struct snd_soc_acpi_adr_device rt712_vb_0_single_adr[] = {
+ {
+ .adr = 0x000030025D071201ull,
+ .num_endpoints = ARRAY_SIZE(rt712_vb_endpoints),
+ .endpoints = rt712_vb_endpoints,
+ .name_prefix = "rt712"
+ }
+};
+
static const struct snd_soc_acpi_adr_device rt1712_3_single_adr[] = {
{
.adr = 0x000330025D171201ull,
@@ -288,6 +320,24 @@ static const struct snd_soc_acpi_adr_device rt1316_2_group2_adr[] = {
}
};
+static const struct snd_soc_acpi_adr_device rt1316_3_single_adr[] = {
+ {
+ .adr = 0x000330025D131601ull,
+ .num_endpoints = 1,
+ .endpoints = &single_endpoint,
+ .name_prefix = "rt1316-1"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1318_1_single_adr[] = {
+ {
+ .adr = 0x000130025D131801ull,
+ .num_endpoints = 1,
+ .endpoints = &single_endpoint,
+ .name_prefix = "rt1318-1"
+ }
+};
+
static const struct snd_soc_acpi_adr_device rt1318_1_group1_adr[] = {
{
.adr = 0x000130025D131801ull,
@@ -324,7 +374,7 @@ static const struct snd_soc_acpi_adr_device rt714_1_adr[] = {
}
};
-static const struct snd_soc_acpi_link_adr mtl_712_only[] = {
+static const struct snd_soc_acpi_link_adr mtl_712_l0_1712_l3[] = {
{
.mask = BIT(0),
.num_adr = ARRAY_SIZE(rt712_0_single_adr),
@@ -338,27 +388,245 @@ static const struct snd_soc_acpi_link_adr mtl_712_only[] = {
{}
};
+static const struct snd_soc_acpi_link_adr mtl_712_l0[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt712_0_single_adr),
+ .adr_d = rt712_0_single_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr mtl_712_vb_l0[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt712_vb_0_single_adr),
+ .adr_d = rt712_vb_0_single_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
+ { /* Jack Playback Endpoint */
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* DMIC Capture Endpoint */
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Jack Capture Endpoint */
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Speaker Playback Endpoint */
+ .num = 3,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = {
{
.adr = 0x00003001FA424301ull,
- .num_endpoints = 1,
- .endpoints = &single_endpoint,
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
+ .endpoints = cs42l43_endpoints,
.name_prefix = "cs42l43"
}
};
+/* CS42L43 - speaker DAI aggregated with 4 amps */
+static const struct snd_soc_acpi_endpoint cs42l43_4amp_spkagg_endpoints[] = {
+ { /* Jack Playback Endpoint */
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* DMIC Capture Endpoint */
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Jack Capture Endpoint */
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Speaker Playback Endpoint */
+ .num = 3,
+ .aggregated = 1,
+ .group_position = 4,
+ .group_id = 1,
+ },
+};
+
+/* CS42L43 on link3 aggregated with 4 amps */
+static const struct snd_soc_acpi_adr_device cs42l43_l3_4amp_spkagg_adr[] = {
+ {
+ .adr = 0x00033001FA424301ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_4amp_spkagg_endpoints),
+ .endpoints = cs42l43_4amp_spkagg_endpoints,
+ .name_prefix = "cs42l43"
+ }
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_l_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 2,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_r_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 2,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_2_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 2,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 2,
+ .group_id = 2,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_3_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 3,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 3,
+ .group_id = 2,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_4_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 4,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 4,
+ .group_id = 2,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_5_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 5,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 5,
+ .group_id = 2,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_6_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 6,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 6,
+ .group_id = 2,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_7_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 7,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 7,
+ .group_id = 2,
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_0_adr[] = {
+ {
+ .adr = 0x00003301FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00003201FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_2_endpoint,
+ .name_prefix = "AMP2"
+ }
+};
+
static const struct snd_soc_acpi_adr_device cs35l56_1_adr[] = {
{
.adr = 0x00013701FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_r_endpoint,
- .name_prefix = "AMP8"
+ .name_prefix = "AMP3"
},
{
.adr = 0x00013601FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_3_endpoint,
- .name_prefix = "AMP7"
+ .name_prefix = "AMP4"
}
};
@@ -377,17 +645,71 @@ static const struct snd_soc_acpi_adr_device cs35l56_2_adr[] = {
}
};
+static const struct snd_soc_acpi_adr_device cs35l56_0_fb_adr[] = {
+ {
+ .adr = 0x00003301FA355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_l_fb_endpoints),
+ .endpoints = cs35l56_l_fb_endpoints,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00003201FA355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_2_fb_endpoints),
+ .endpoints = cs35l56_2_fb_endpoints,
+ .name_prefix = "AMP2"
+ },
+ {
+ .adr = 0x00003101FA355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_4_fb_endpoints),
+ .endpoints = cs35l56_4_fb_endpoints,
+ .name_prefix = "AMP3"
+ },
+ {
+ .adr = 0x00003001FA355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_6_fb_endpoints),
+ .endpoints = cs35l56_6_fb_endpoints,
+ .name_prefix = "AMP4"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_1_fb_adr[] = {
+ {
+ .adr = 0x00013701FA355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_r_fb_endpoints),
+ .endpoints = cs35l56_r_fb_endpoints,
+ .name_prefix = "AMP8"
+ },
+ {
+ .adr = 0x00013601FA355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_3_fb_endpoints),
+ .endpoints = cs35l56_3_fb_endpoints,
+ .name_prefix = "AMP7"
+ },
+ {
+ .adr = 0x00013501FA355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_5_fb_endpoints),
+ .endpoints = cs35l56_5_fb_endpoints,
+ .name_prefix = "AMP6"
+ },
+ {
+ .adr = 0x00013401FA355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_7_fb_endpoints),
+ .endpoints = cs35l56_7_fb_endpoints,
+ .name_prefix = "AMP5"
+ },
+};
+
static const struct snd_soc_acpi_adr_device cs35l56_2_r_adr[] = {
{
.adr = 0x00023201FA355601ull,
- .num_endpoints = 1,
- .endpoints = &spk_r_endpoint,
+ .num_endpoints = ARRAY_SIZE(cs35l56_r_fb_endpoints),
+ .endpoints = cs35l56_r_fb_endpoints,
.name_prefix = "AMP3"
},
{
.adr = 0x00023301FA355601ull,
- .num_endpoints = 1,
- .endpoints = &spk_3_endpoint,
+ .num_endpoints = ARRAY_SIZE(cs35l56_3_fb_endpoints),
+ .endpoints = cs35l56_3_fb_endpoints,
.name_prefix = "AMP4"
}
@@ -396,18 +718,36 @@ static const struct snd_soc_acpi_adr_device cs35l56_2_r_adr[] = {
static const struct snd_soc_acpi_adr_device cs35l56_3_l_adr[] = {
{
.adr = 0x00033001fa355601ull,
- .num_endpoints = 1,
- .endpoints = &spk_l_endpoint,
+ .num_endpoints = ARRAY_SIZE(cs35l56_l_fb_endpoints),
+ .endpoints = cs35l56_l_fb_endpoints,
.name_prefix = "AMP1"
},
{
.adr = 0x00033101fa355601ull,
- .num_endpoints = 1,
- .endpoints = &spk_2_endpoint,
+ .num_endpoints = ARRAY_SIZE(cs35l56_2_fb_endpoints),
+ .endpoints = cs35l56_2_fb_endpoints,
.name_prefix = "AMP2"
}
};
+static const struct snd_soc_acpi_adr_device cs35l63_1_fb_adr[] = {
+ {
+ .adr = 0x00013001FA356301ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_l_fb_endpoints),
+ .endpoints = cs35l56_l_fb_endpoints,
+ .name_prefix = "AMP1"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l63_3_fb_adr[] = {
+ {
+ .adr = 0x00033101FA356301ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_r_fb_endpoints),
+ .endpoints = cs35l56_r_fb_endpoints,
+ .name_prefix = "AMP2"
+ },
+};
+
static const struct snd_soc_acpi_link_adr rt5682_link2_max98373_link0[] = {
/* Expected order: jack -> amp */
{
@@ -508,6 +848,49 @@ static const struct snd_soc_acpi_link_adr mtl_rt713_l0_rt1316_l12_rt1713_l3[] =
{}
};
+static const struct snd_soc_acpi_link_adr mtl_rt713_l0_rt1318_l1_rt1713_l3[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt713_0_single_adr),
+ .adr_d = rt713_0_single_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1318_1_single_adr),
+ .adr_d = rt1318_1_single_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt1713_3_single_adr),
+ .adr_d = rt1713_3_single_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr mtl_rt713_l0_rt1318_l12_rt1713_l3[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt713_0_single_adr),
+ .adr_d = rt713_0_single_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1318_1_group1_adr),
+ .adr_d = rt1318_1_group1_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt1318_2_group1_adr),
+ .adr_d = rt1318_2_group1_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt1713_3_single_adr),
+ .adr_d = rt1713_3_single_adr,
+ },
+ {}
+};
+
static const struct snd_soc_acpi_link_adr mtl_rt713_l0_rt1316_l12[] = {
{
.mask = BIT(0),
@@ -527,6 +910,20 @@ static const struct snd_soc_acpi_link_adr mtl_rt713_l0_rt1316_l12[] = {
{}
};
+static const struct snd_soc_acpi_link_adr mtl_rt711_l0_rt1316_l3[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt711_sdca_0_adr),
+ .adr_d = rt711_sdca_0_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt1316_3_single_adr),
+ .adr_d = rt1316_3_single_adr,
+ },
+ {}
+};
+
static const struct snd_soc_acpi_adr_device mx8363_2_adr[] = {
{
.adr = 0x000230019F836300ull,
@@ -566,6 +963,15 @@ static const struct snd_soc_acpi_link_adr cs42l42_link0_max98363_link2[] = {
{}
};
+static const struct snd_soc_acpi_link_adr mtl_cs42l43_l0[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_0_adr),
+ .adr_d = cs42l43_0_adr,
+ },
+ {}
+};
+
static const struct snd_soc_acpi_link_adr mtl_cs42l43_cs35l56[] = {
{
.mask = BIT(0),
@@ -605,6 +1011,54 @@ static const struct snd_soc_acpi_link_adr cs42l43_link0_cs35l56_link2_link3[] =
{}
};
+static const struct snd_soc_acpi_link_adr cs42l43_link3_cs35l56_x4_link0_link1_spkagg[] = {
+ /* Expected order: jack -> amp */
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(cs42l43_l3_4amp_spkagg_adr),
+ .adr_d = cs42l43_l3_4amp_spkagg_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = 2,
+ .adr_d = cs35l56_1_adr,
+ },
+ {
+ .mask = BIT(0),
+ .num_adr = 2,
+ .adr_d = cs35l56_0_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr mtl_cs35l56_x8_link0_link1_fb[] = {
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs35l56_1_fb_adr),
+ .adr_d = cs35l56_1_fb_adr,
+ },
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs35l56_0_fb_adr),
+ .adr_d = cs35l56_0_fb_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr mtl_cs35l63_x2_link1_link3_fb[] = {
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(cs35l63_3_fb_adr),
+ .adr_d = cs35l63_3_fb_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs35l63_1_fb_adr),
+ .adr_d = cs35l63_1_fb_adr,
+ },
+ {}
+};
+
/* this table is used when there is no I2S codec present */
struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = {
/* mockup tests need to be first */
@@ -633,6 +1087,18 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = {
.sof_tplg_filename = "sof-mtl-rt713-l0-rt1316-l12-rt1713-l3.tplg",
},
{
+ .link_mask = GENMASK(3, 0),
+ .links = mtl_rt713_l0_rt1318_l12_rt1713_l3,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-mtl-rt713-l0-rt1318-l12-rt1713-l3.tplg",
+ },
+ {
+ .link_mask = BIT(0) | BIT(1) | BIT(3),
+ .links = mtl_rt713_l0_rt1318_l1_rt1713_l3,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-mtl-rt713-l0-rt1318-l1-rt1713-l3.tplg",
+ },
+ {
.link_mask = GENMASK(2, 0),
.links = mtl_rt713_l0_rt1316_l12,
.drv_name = "sof_sdw",
@@ -640,11 +1106,26 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = {
},
{
.link_mask = BIT(3) | BIT(0),
- .links = mtl_712_only,
+ .links = mtl_712_l0_1712_l3,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-mtl-rt712-l0-rt1712-l3.tplg",
},
{
+ .link_mask = BIT(0),
+ .links = mtl_712_vb_l0,
+ .drv_name = "sof_sdw",
+ .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb,
+ .sof_tplg_filename = "sof-mtl-rt712-vb-l0.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(0),
+ .links = mtl_712_l0,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-mtl-rt712-l0.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
.link_mask = GENMASK(2, 0),
.links = mtl_sdw_rt1318_l12_rt714_l0,
.drv_name = "sof_sdw",
@@ -655,12 +1136,41 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = {
.links = cs42l43_link0_cs35l56_link2_link3,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-mtl-cs42l43-l0-cs35l56-l23.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(0) | BIT(1) | BIT(3),
+ .links = cs42l43_link3_cs35l56_x4_link0_link1_spkagg,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-mtl-cs42l43-l3-cs35l56-l01-spkagg.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
},
{
.link_mask = GENMASK(2, 0),
.links = mtl_cs42l43_cs35l56,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-mtl-cs42l43-l0-cs35l56-l12.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(0) | BIT(1),
+ .links = mtl_cs35l56_x8_link0_link1_fb,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-mtl-cs35l56-l01-fb8.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(0),
+ .links = mtl_cs42l43_l0,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-mtl-cs42l43-l0.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(1) | BIT(3),
+ .links = mtl_cs35l63_x2_link1_link3_fb,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-mtl-cs35l56-l01-fb8.tplg",
},
{
.link_mask = GENMASK(3, 0),
@@ -669,10 +1179,17 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = {
.sof_tplg_filename = "sof-mtl-rt711-l0-rt1316-l23-rt714-l1.tplg",
},
{
+ .link_mask = 0x9, /* 2 active links required */
+ .links = mtl_rt711_l0_rt1316_l3,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-mtl-rt711-l0-rt1316-l3.tplg",
+ },
+ {
.link_mask = BIT(0),
.links = mtl_rt722_only,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-mtl-rt722-l0.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
},
{
.link_mask = BIT(0),
@@ -695,3 +1212,5 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = {
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_sdw_machines);
+
+MODULE_IMPORT_NS("SND_SOC_ACPI_INTEL_SDCA_QUIRKS");
diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c
new file mode 100644
index 000000000000..eae75f3f0fa4
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c
@@ -0,0 +1,683 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * soc-acpi-intel-ptl-match.c - tables and support for PTL ACPI enumeration.
+ *
+ * Copyright (c) 2024, Intel Corporation.
+ *
+ * Order of entries in snd_soc_acpi_intel_ptl_sdw_machines[] matters.
+ * Check subset of link mask when matching the machine driver, rule is
+ * superset match should be ordered before subset matches.
+ */
+
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+#include "sof-function-topology-lib.h"
+#include "soc-acpi-intel-sdca-quirks.h"
+#include "soc-acpi-intel-sdw-mockup-match.h"
+#include <sound/soc-acpi-intel-ssp-common.h>
+
+static const struct snd_soc_acpi_codecs ptl_rt5682_rt5682s_hp = {
+ .num_codecs = 2,
+ .codecs = {RT5682_ACPI_HID, RT5682S_ACPI_HID},
+};
+
+struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_machines[] = {
+ {
+ .comp_ids = &ptl_rt5682_rt5682s_hp,
+ .drv_name = "ptl_rt5682_def",
+ .sof_tplg_filename = "sof-ptl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ptl_machines);
+
+static const struct snd_soc_acpi_endpoint single_endpoint = {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+};
+
+static const struct snd_soc_acpi_endpoint spk_l_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_1_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_2_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 2,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_3_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 3,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_4_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 4,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_5_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 5,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_6_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 6,
+ .group_id = 1,
+};
+
+/*
+ * Multi-function codecs with three endpoints created for
+ * headset, amp and dmic functions.
+ */
+static const struct snd_soc_acpi_endpoint rt_mf_endpoints[] = {
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ {
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ {
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint jack_dmic_endpoints[] = {
+ /* Jack Endpoint */
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ /* DMIC Endpoint */
+ {
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint jack_amp_g1_dmic_endpoints[] = {
+ /* Jack Endpoint */
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ /* Amp Endpoint, work as spk_l_endpoint */
+ {
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 1,
+ },
+ /* DMIC Endpoint */
+ {
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs42l43_amp_spkagg_endpoints[] = {
+ { /* Jack Playback Endpoint */
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* DMIC Capture Endpoint */
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Jack Capture Endpoint */
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Speaker Playback Endpoint */
+ .num = 3,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 1,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
+ { /* Jack Playback Endpoint */
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* DMIC Capture Endpoint */
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Jack Capture Endpoint */
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Speaker Playback Endpoint */
+ .num = 3,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = {
+ {
+ .adr = 0x00023001fa424301ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_amp_spkagg_endpoints),
+ .endpoints = cs42l43_amp_spkagg_endpoints,
+ .name_prefix = "cs42l43"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_1_3amp_adr[] = {
+ {
+ .adr = 0x00013001fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_1_endpoint,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00013101fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_2_endpoint,
+ .name_prefix = "AMP2"
+ },
+ {
+ .adr = 0x00013201fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_3_endpoint,
+ .name_prefix = "AMP3"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_3_3amp_adr[] = {
+ {
+ .adr = 0x00033301fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_4_endpoint,
+ .name_prefix = "AMP4"
+ },
+ {
+ .adr = 0x00033401fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_5_endpoint,
+ .name_prefix = "AMP5"
+ },
+ {
+ .adr = 0x00033501fa355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_6_endpoint,
+ .name_prefix = "AMP6"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs42l43_3_adr[] = {
+ {
+ .adr = 0x00033001FA424301ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
+ .endpoints = cs42l43_endpoints,
+ .name_prefix = "cs42l43"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = {
+ {
+ .adr = 0x000030025D071101ull,
+ .num_endpoints = 1,
+ .endpoints = &single_endpoint,
+ .name_prefix = "rt711"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt712_vb_2_group1_adr[] = {
+ {
+ .adr = 0x000230025D071201ull,
+ .num_endpoints = ARRAY_SIZE(jack_amp_g1_dmic_endpoints),
+ .endpoints = jack_amp_g1_dmic_endpoints,
+ .name_prefix = "rt712"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt712_vb_3_group1_adr[] = {
+ {
+ .adr = 0x000330025D071201ull,
+ .num_endpoints = ARRAY_SIZE(jack_amp_g1_dmic_endpoints),
+ .endpoints = jack_amp_g1_dmic_endpoints,
+ .name_prefix = "rt712"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt713_vb_2_adr[] = {
+ {
+ .adr = 0x000230025d071301ull,
+ .num_endpoints = ARRAY_SIZE(jack_dmic_endpoints),
+ .endpoints = jack_dmic_endpoints,
+ .name_prefix = "rt713"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt713_vb_3_adr[] = {
+ {
+ .adr = 0x000330025D071301ull,
+ .num_endpoints = ARRAY_SIZE(jack_dmic_endpoints),
+ .endpoints = jack_dmic_endpoints,
+ .name_prefix = "rt713"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1320_3_group1_adr[] = {
+ {
+ .adr = 0x000330025D132001ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "rt1320-1"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt721_3_single_adr[] = {
+ {
+ .adr = 0x000330025d072101ull,
+ .num_endpoints = ARRAY_SIZE(rt_mf_endpoints),
+ .endpoints = rt_mf_endpoints,
+ .name_prefix = "rt721"
+ }
+};
+
+static const struct snd_soc_acpi_link_adr ptl_rt721_l3[] = {
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt721_3_single_adr),
+ .adr_d = rt721_3_single_adr,
+ },
+ {},
+};
+
+static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = {
+ {
+ .adr = 0x000030025d072201ull,
+ .num_endpoints = ARRAY_SIZE(rt_mf_endpoints),
+ .endpoints = rt_mf_endpoints,
+ .name_prefix = "rt722"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt722_1_single_adr[] = {
+ {
+ .adr = 0x000130025d072201ull,
+ .num_endpoints = ARRAY_SIZE(rt_mf_endpoints),
+ .endpoints = rt_mf_endpoints,
+ .name_prefix = "rt722"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt722_3_single_adr[] = {
+ {
+ .adr = 0x000330025d072201ull,
+ .num_endpoints = ARRAY_SIZE(rt_mf_endpoints),
+ .endpoints = rt_mf_endpoints,
+ .name_prefix = "rt722"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1320_1_group1_adr[] = {
+ {
+ .adr = 0x000130025D132001ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "rt1320-1"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1320_1_group2_adr[] = {
+ {
+ .adr = 0x000130025D132001ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "rt1320-1"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1320_2_group1_adr[] = {
+ {
+ .adr = 0x000230025D132001ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "rt1320-1"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1320_2_group2_adr[] = {
+ {
+ .adr = 0x000230025D132001ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "rt1320-1"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt1320_3_group2_adr[] = {
+ {
+ .adr = 0x000330025D132001ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "rt1320-2"
+ }
+};
+
+static const struct snd_soc_acpi_link_adr ptl_cs42l43_l2_cs35l56x6_l13[] = {
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(cs42l43_2_adr),
+ .adr_d = cs42l43_2_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs35l56_1_3amp_adr),
+ .adr_d = cs35l56_1_3amp_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(cs35l56_3_3amp_adr),
+ .adr_d = cs35l56_3_3amp_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr ptl_cs42l43_l3[] = {
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(cs42l43_3_adr),
+ .adr_d = cs42l43_3_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr ptl_rt722_only[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt722_0_single_adr),
+ .adr_d = rt722_0_single_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr ptl_rt722_l1[] = {
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt722_1_single_adr),
+ .adr_d = rt722_1_single_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr ptl_rt722_l3[] = {
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt722_3_single_adr),
+ .adr_d = rt722_3_single_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr ptl_rvp[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt711_sdca_0_adr),
+ .adr_d = rt711_sdca_0_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr ptl_sdw_rt713_vb_l2_rt1320_l13[] = {
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt713_vb_2_adr),
+ .adr_d = rt713_vb_2_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1320_1_group2_adr),
+ .adr_d = rt1320_1_group2_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt1320_3_group2_adr),
+ .adr_d = rt1320_3_group2_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr ptl_sdw_rt713_vb_l3_rt1320_l12[] = {
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt713_vb_3_adr),
+ .adr_d = rt713_vb_3_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1320_1_group2_adr),
+ .adr_d = rt1320_1_group2_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt1320_2_group2_adr),
+ .adr_d = rt1320_2_group2_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l2_rt1320_l1[] = {
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt712_vb_2_group1_adr),
+ .adr_d = rt712_vb_2_group1_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt1320_1_group1_adr),
+ .adr_d = rt1320_1_group1_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l3_rt1320_l2[] = {
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt712_vb_3_group1_adr),
+ .adr_d = rt712_vb_3_group1_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(rt1320_2_group1_adr),
+ .adr_d = rt1320_2_group1_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l3_rt1320_l3[] = {
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt712_vb_3_group1_adr),
+ .adr_d = rt712_vb_3_group1_adr,
+ },
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt1320_3_group1_adr),
+ .adr_d = rt1320_3_group1_adr,
+ },
+ {}
+};
+
+/* this table is used when there is no I2S codec present */
+struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = {
+/* Order Priority: mockup > most links > most bit link-mask > alphabetical */
+ {
+ .link_mask = GENMASK(3, 0),
+ .links = sdw_mockup_headset_2amps_mic,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt711-rt1308-rt715.tplg",
+ },
+ {
+ .link_mask = BIT(0) | BIT(1) | BIT(3),
+ .links = sdw_mockup_headset_1amp_mic,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt711-rt1308-mono-rt715.tplg",
+ },
+ {
+ .link_mask = GENMASK(2, 0),
+ .links = sdw_mockup_mic_headset_1amp,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt715-rt711-rt1308-mono.tplg",
+ },
+ {
+ .link_mask = BIT(0),
+ .links = sdw_mockup_multi_func,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt722.tplg", /* Reuse the existing tplg file */
+ },
+ {
+ .link_mask = BIT(1) | BIT(2) | BIT(3),
+ .links = ptl_sdw_rt713_vb_l2_rt1320_l13,
+ .drv_name = "sof_sdw",
+ .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb,
+ .sof_tplg_filename = "sof-ptl-rt713-l2-rt1320-l13.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(1) | BIT(2) | BIT(3),
+ .links = ptl_sdw_rt713_vb_l3_rt1320_l12,
+ .drv_name = "sof_sdw",
+ .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb,
+ .sof_tplg_filename = "sof-ptl-rt713-l3-rt1320-l12.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(1) | BIT(2) | BIT(3),
+ .links = ptl_cs42l43_l2_cs35l56x6_l13,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-cs42l43-l2-cs35l56x6-l13.tplg",
+ },
+ {
+ .link_mask = BIT(1) | BIT(2),
+ .links = ptl_sdw_rt712_vb_l2_rt1320_l1,
+ .drv_name = "sof_sdw",
+ .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb,
+ .sof_tplg_filename = "sof-ptl-rt712-l2-rt1320-l1.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(2) | BIT(3),
+ .links = ptl_sdw_rt712_vb_l3_rt1320_l2,
+ .drv_name = "sof_sdw",
+ .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb,
+ .sof_tplg_filename = "sof-ptl-rt712-l3-rt1320-l2.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(0),
+ .links = ptl_rvp,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt711.tplg",
+ },
+ {
+ .link_mask = BIT(0),
+ .links = ptl_rt722_only,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt722.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(1),
+ .links = ptl_rt722_l1,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt722.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(3),
+ .links = ptl_cs42l43_l3,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-cs42l43-l3.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(3),
+ .links = ptl_sdw_rt712_vb_l3_rt1320_l3,
+ .drv_name = "sof_sdw",
+ .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb,
+ .sof_tplg_filename = "sof-ptl-rt712-l3-rt1320-l3.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(3),
+ .links = ptl_rt721_l3,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt721.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {
+ .link_mask = BIT(3),
+ .links = ptl_rt722_l3,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt722.tplg",
+ .get_function_tplg_files = sof_sdw_get_tplg_files,
+ },
+ {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ptl_sdw_machines);
diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c
index 00a21af210fa..b83ac2e6337c 100644
--- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c
@@ -7,6 +7,7 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
+#include <sound/soc-acpi-intel-ssp-common.h>
static const struct snd_soc_acpi_endpoint single_endpoint = {
.num = 0,
@@ -29,6 +30,42 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
.group_id = 1,
};
+static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
+ { /* Jack Playback Endpoint */
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* DMIC Capture Endpoint */
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Jack Capture Endpoint */
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Speaker Playback Endpoint */
+ .num = 3,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = {
+ {
+ .adr = 0x00003001FA424301ull,
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
+ .endpoints = cs42l43_endpoints,
+ .name_prefix = "cs42l43"
+ }
+};
+
static const struct snd_soc_acpi_adr_device rt711_0_adr[] = {
{
.adr = 0x000020025D071100ull,
@@ -155,6 +192,15 @@ static const struct snd_soc_acpi_adr_device rt714_3_adr[] = {
}
};
+static const struct snd_soc_acpi_link_adr rpl_cs42l43_l0[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_0_adr),
+ .adr_d = cs42l43_0_adr,
+ },
+ {}
+};
+
static const struct snd_soc_acpi_link_adr rpl_sdca_3_in_1[] = {
{
.mask = BIT(0),
@@ -347,7 +393,7 @@ static const struct snd_soc_acpi_link_adr rplp_crb[] = {
static const struct snd_soc_acpi_codecs rpl_rt5682_hp = {
.num_codecs = 2,
- .codecs = {"10EC5682", "RTL5682"},
+ .codecs = {RT5682_ACPI_HID, RT5682S_ACPI_HID},
};
static const struct snd_soc_acpi_codecs rpl_essx_83x6 = {
@@ -360,31 +406,11 @@ static const struct snd_soc_acpi_codecs rpl_max98357a_amp = {
.codecs = {"MX98357A"}
};
-static const struct snd_soc_acpi_codecs rpl_max98360a_amp = {
- .num_codecs = 1,
- .codecs = {"MX98360A"},
-};
-
-static const struct snd_soc_acpi_codecs rpl_max98373_amp = {
- .num_codecs = 1,
- .codecs = {"MX98373"}
-};
-
static const struct snd_soc_acpi_codecs rpl_lt6911_hdmi = {
.num_codecs = 1,
.codecs = {"INTC10B0"}
};
-static const struct snd_soc_acpi_codecs rpl_nau8318_amp = {
- .num_codecs = 1,
- .codecs = {"NVTN2012"}
-};
-
-static const struct snd_soc_acpi_codecs rpl_rt1019p_amp = {
- .num_codecs = 1,
- .codecs = {"RTL1019"}
-};
-
struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = {
{
.comp_ids = &rpl_rt5682_hp,
@@ -395,41 +421,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = {
},
{
.comp_ids = &rpl_rt5682_hp,
- .drv_name = "rpl_rt5682_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &rpl_max98360a_amp,
- .sof_tplg_filename = "sof-rpl-max98360a-rt5682.tplg",
- },
- {
- .id = "10508825",
- .drv_name = "rpl_nau8825_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &rpl_max98373_amp,
- .sof_tplg_filename = "sof-rpl-max98373-nau8825.tplg",
- },
- {
- .id = "10508825",
- .drv_name = "rpl_nau8825_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &rpl_max98360a_amp,
- .sof_tplg_filename = "sof-rpl-max98360a-nau8825.tplg",
- },
- {
- .id = "10508825",
- .drv_name = "rpl_nau8825_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &rpl_nau8318_amp,
- .sof_tplg_filename = "sof-rpl-nau8318-nau8825.tplg",
- },
- {
- .comp_ids = &rpl_rt5682_hp,
- .drv_name = "rpl_rt5682_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &rpl_rt1019p_amp,
- .sof_tplg_filename = "sof-rpl-rt1019-rt5682.tplg",
- },
- {
- .comp_ids = &rpl_rt5682_hp,
.drv_name = "rpl_rt5682_c1_h02",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &rpl_lt6911_hdmi,
@@ -450,6 +441,45 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = {
SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
+ /* place boards for each headphone codec: sof driver will complete the
+ * tplg name and machine driver will detect the amp type
+ */
+ {
+ .id = CS42L42_ACPI_HID,
+ .drv_name = "rpl_cs42l42_def",
+ .sof_tplg_filename = "sof-rpl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ {
+ .id = DA7219_ACPI_HID,
+ .drv_name = "rpl_da7219_def",
+ .sof_tplg_filename = "sof-rpl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ {
+ .id = NAU8825_ACPI_HID,
+ .drv_name = "rpl_nau8825_def",
+ .sof_tplg_filename = "sof-rpl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ {
+ .id = RT5650_ACPI_HID,
+ .drv_name = "rpl_rt5682_def",
+ .sof_tplg_filename = "sof-rpl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ {
+ .comp_ids = &rpl_rt5682_hp,
+ .drv_name = "rpl_rt5682_def",
+ .sof_tplg_filename = "sof-rpl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ /* place amp-only boards in the end of table */
{
.id = "INTC10B0",
.drv_name = "rpl_lt6911_hdmi_ssp",
@@ -462,6 +492,12 @@ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_rpl_machines);
/* this table is used when there is no I2S codec present */
struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = {
{
+ .link_mask = BIT(0),
+ .links = rpl_cs42l43_l0,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-rpl-cs42l43-l0.tplg",
+ },
+ {
.link_mask = 0xF, /* 4 active links required */
.links = rpl_sdca_3_in_1,
.drv_name = "sof_sdw",
diff --git a/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.c b/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.c
new file mode 100644
index 000000000000..3eaa058f8460
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * soc-acpi-intel-sdca-quirks.c - tables and support for SDCA quirks
+ *
+ * Copyright (c) 2024, Intel Corporation.
+ *
+ */
+
+#include <linux/soundwire/sdw_intel.h>
+#include <sound/sdca.h>
+#include <sound/soc-acpi.h>
+#include "soc-acpi-intel-sdca-quirks.h"
+
+/*
+ * Pretend machine quirk. The argument type is not the traditional
+ * 'struct snd_soc_acpi_mach' pointer but instead the sdw_intel_ctx
+ * which contains the peripheral information required for the
+ * SoundWire/SDCA filter on the SMART_MIC setup and interface
+ * revision. When the return value is false, the entry in the
+ * 'snd_soc_acpi_mach' table needs to be skipped.
+ */
+bool snd_soc_acpi_intel_sdca_is_device_rt712_vb(void *arg)
+{
+ struct sdw_intel_ctx *ctx = arg;
+ int i;
+
+ if (!ctx)
+ return false;
+
+ for (i = 0; i < ctx->peripherals->num_peripherals; i++) {
+ if (sdca_device_quirk_match(ctx->peripherals->array[i],
+ SDCA_QUIRKS_RT712_VB))
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL_NS(snd_soc_acpi_intel_sdca_is_device_rt712_vb, "SND_SOC_ACPI_INTEL_SDCA_QUIRKS");
+
+MODULE_DESCRIPTION("ASoC ACPI Intel SDCA quirks");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("SND_SOC_SDCA");
diff --git a/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.h b/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.h
new file mode 100644
index 000000000000..bead5ec6243f
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * soc-acpi-intel-sdca-quirks.h - tables and support for SDCA quirks
+ *
+ * Copyright (c) 2024, Intel Corporation.
+ *
+ */
+
+#ifndef _SND_SOC_ACPI_INTEL_SDCA_QUIRKS
+#define _SND_SOC_ACPI_INTEL_SDCA_QUIRKS
+
+bool snd_soc_acpi_intel_sdca_is_device_rt712_vb(void *arg);
+
+#endif
diff --git a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c
index a3d33997736a..d122ce69fa4f 100644
--- a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c
@@ -31,6 +31,30 @@ static const struct snd_soc_acpi_endpoint sdw_mockup_r_endpoint = {
.group_id = 1,
};
+static const struct snd_soc_acpi_endpoint jack_amp_g1_dmic_endpoints[] = {
+ /* Jack Endpoint */
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ /* Amp Endpoint, work as spk_l_endpoint */
+ {
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 1,
+ },
+ /* DMIC Endpoint */
+ {
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
static const struct snd_soc_acpi_adr_device sdw_mockup_headset_0_adr[] = {
{
.adr = 0x0000000105AA5500ull,
@@ -103,6 +127,15 @@ static const struct snd_soc_acpi_adr_device sdw_mockup_amp_2_group1_adr[] = {
}
};
+static const struct snd_soc_acpi_adr_device sdw_mockup_multi_function_adr[] = {
+ {
+ .adr = 0x0000000105AAAA01ull,
+ .num_endpoints = ARRAY_SIZE(jack_amp_g1_dmic_endpoints),
+ .endpoints = jack_amp_g1_dmic_endpoints,
+ .name_prefix = "sdw_mockup_mmulti-function"
+ }
+};
+
const struct snd_soc_acpi_link_adr sdw_mockup_headset_1amp_mic[] = {
{
.mask = BIT(0),
@@ -164,3 +197,12 @@ const struct snd_soc_acpi_link_adr sdw_mockup_mic_headset_1amp[] = {
},
{}
};
+
+const struct snd_soc_acpi_link_adr sdw_mockup_multi_func[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(sdw_mockup_multi_function_adr),
+ .adr_d = sdw_mockup_multi_function_adr,
+ },
+ {}
+};
diff --git a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h
index c99eecd19e03..f7ed5beaca96 100644
--- a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h
+++ b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h
@@ -13,5 +13,6 @@
extern const struct snd_soc_acpi_link_adr sdw_mockup_headset_1amp_mic[];
extern const struct snd_soc_acpi_link_adr sdw_mockup_headset_2amps_mic[];
extern const struct snd_soc_acpi_link_adr sdw_mockup_mic_headset_1amp[];
+extern const struct snd_soc_acpi_link_adr sdw_mockup_multi_func[];
#endif
diff --git a/sound/soc/intel/common/soc-acpi-intel-skl-match.c b/sound/soc/intel/common/soc-acpi-intel-skl-match.c
index 75302e956742..ee6463202918 100644
--- a/sound/soc/intel/common/soc-acpi-intel-skl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-skl-match.c
@@ -8,9 +8,6 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
-#include "../skylake/skl.h"
-
-static struct skl_machine_pdata skl_dmic_data;
static const struct snd_soc_acpi_codecs skl_codecs = {
.num_codecs = 1,
@@ -29,7 +26,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_skl_machines[] = {
.fw_filename = "intel/dsp_fw_release.bin",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &skl_codecs,
- .pdata = &skl_dmic_data,
},
{
.id = "MX98357A",
@@ -37,7 +33,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_skl_machines[] = {
.fw_filename = "intel/dsp_fw_release.bin",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &skl_codecs,
- .pdata = &skl_dmic_data,
},
{},
};
diff --git a/sound/soc/intel/common/soc-acpi-intel-ssp-common.c b/sound/soc/intel/common/soc-acpi-intel-ssp-common.c
new file mode 100644
index 000000000000..f56f4bfa5187
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-ssp-common.c
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright(c) 2023 Intel Corporation
+
+#include <linux/device.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-ssp-common.h>
+
+/*
+ * Codec probe function
+ */
+#define CODEC_MAP_ENTRY(n, s, h, t) \
+ { \
+ .name = n, \
+ .tplg_suffix = s, \
+ .acpi_hid = h, \
+ .codec_type = t, \
+ }
+
+struct codec_map {
+ const char *name;
+ const char *tplg_suffix;
+ const char *acpi_hid;
+ enum snd_soc_acpi_intel_codec codec_type;
+};
+
+static const struct codec_map codecs[] = {
+ /* Cirrus Logic */
+ CODEC_MAP_ENTRY("CS42L42", "cs42l42", CS42L42_ACPI_HID, CODEC_CS42L42),
+
+ /* Dialog */
+ CODEC_MAP_ENTRY("DA7219", "da7219", DA7219_ACPI_HID, CODEC_DA7219),
+
+ /* Everest */
+ CODEC_MAP_ENTRY("ES8316", "es8336", ES8316_ACPI_HID, CODEC_ES8316),
+ CODEC_MAP_ENTRY("ES8326", "es8336", ES8326_ACPI_HID, CODEC_ES8326),
+ CODEC_MAP_ENTRY("ES8336", "es8336", ES8336_ACPI_HID, CODEC_ES8336),
+
+ /* Nuvoton */
+ CODEC_MAP_ENTRY("NAU8825", "nau8825", NAU8825_ACPI_HID, CODEC_NAU8825),
+
+ /* Realtek */
+ CODEC_MAP_ENTRY("RT5650", "rt5650", RT5650_ACPI_HID, CODEC_RT5650),
+ CODEC_MAP_ENTRY("RT5682", "rt5682", RT5682_ACPI_HID, CODEC_RT5682),
+ CODEC_MAP_ENTRY("RT5682S", "rt5682", RT5682S_ACPI_HID, CODEC_RT5682S),
+};
+
+static const struct codec_map amps[] = {
+ /* Cirrus Logic */
+ CODEC_MAP_ENTRY("CS35L41", "cs35l41", CS35L41_ACPI_HID, CODEC_CS35L41),
+
+ /* Maxim */
+ CODEC_MAP_ENTRY("MAX98357A", "max98357a", MAX_98357A_ACPI_HID, CODEC_MAX98357A),
+ CODEC_MAP_ENTRY("MAX98360A", "max98360a", MAX_98360A_ACPI_HID, CODEC_MAX98360A),
+ CODEC_MAP_ENTRY("MAX98373", "max98373", MAX_98373_ACPI_HID, CODEC_MAX98373),
+ CODEC_MAP_ENTRY("MAX98390", "max98390", MAX_98390_ACPI_HID, CODEC_MAX98390),
+
+ /* Nuvoton */
+ CODEC_MAP_ENTRY("NAU8318", "nau8318", NAU8318_ACPI_HID, CODEC_NAU8318),
+
+ /* Realtek */
+ CODEC_MAP_ENTRY("RT1011", "rt1011", RT1011_ACPI_HID, CODEC_RT1011),
+ CODEC_MAP_ENTRY("RT1015", "rt1015", RT1015_ACPI_HID, CODEC_RT1015),
+ CODEC_MAP_ENTRY("RT1015P", "rt1015", RT1015P_ACPI_HID, CODEC_RT1015P),
+ CODEC_MAP_ENTRY("RT1019P", "rt1019", RT1019P_ACPI_HID, CODEC_RT1019P),
+ CODEC_MAP_ENTRY("RT1308", "rt1308", RT1308_ACPI_HID, CODEC_RT1308),
+
+ /*
+ * Monolithic components
+ *
+ * Only put components that can serve as both the amp and the codec below this line.
+ * This will ensure that if the part is used just as a codec and there is an amp as well
+ * then the amp will be selected properly.
+ */
+ CODEC_MAP_ENTRY("RT5650", "rt5650", RT5650_ACPI_HID, CODEC_RT5650),
+};
+
+enum snd_soc_acpi_intel_codec
+snd_soc_acpi_intel_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(snd_soc_acpi_intel_detect_codec_type, "SND_SOC_ACPI_INTEL_MATCH");
+
+enum snd_soc_acpi_intel_codec
+snd_soc_acpi_intel_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(snd_soc_acpi_intel_detect_amp_type, "SND_SOC_ACPI_INTEL_MATCH");
+
+const char *
+snd_soc_acpi_intel_get_codec_name(enum snd_soc_acpi_intel_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(snd_soc_acpi_intel_get_codec_name, "SND_SOC_ACPI_INTEL_MATCH");
+
+const char *
+snd_soc_acpi_intel_get_codec_tplg_suffix(enum snd_soc_acpi_intel_codec codec_type)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(codecs); i++) {
+ if (codecs[i].codec_type != codec_type)
+ continue;
+
+ return codecs[i].tplg_suffix;
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_tplg_suffix, "SND_SOC_ACPI_INTEL_MATCH");
+
+const char *
+snd_soc_acpi_intel_get_amp_tplg_suffix(enum snd_soc_acpi_intel_codec codec_type)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(amps); i++) {
+ if (amps[i].codec_type != codec_type)
+ continue;
+
+ return amps[i].tplg_suffix;
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_amp_tplg_suffix, "SND_SOC_ACPI_INTEL_MATCH");
+
+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/common/soc-acpi-intel-tgl-match.c b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
index 0fba0a60d9c7..b77aafb0bfb6 100644
--- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
@@ -8,6 +8,7 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
+#include <sound/soc-acpi-intel-ssp-common.h>
#include "soc-acpi-intel-sdw-mockup-match.h"
static const struct snd_soc_acpi_codecs essx_83x6 = {
@@ -15,11 +16,6 @@ static const struct snd_soc_acpi_codecs essx_83x6 = {
.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
};
-static const struct snd_soc_acpi_codecs tgl_codecs = {
- .num_codecs = 1,
- .codecs = {"MX98357A"}
-};
-
static const struct snd_soc_acpi_endpoint single_endpoint = {
.num = 0,
.aggregated = 0,
@@ -414,11 +410,38 @@ static const struct snd_soc_acpi_link_adr tgl_712_only[] = {
{}
};
+static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
+ { /* Jack Playback Endpoint */
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* DMIC Capture Endpoint */
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Jack Capture Endpoint */
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ { /* Speaker Playback Endpoint */
+ .num = 3,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
static const struct snd_soc_acpi_adr_device cs42l43_3_adr[] = {
{
.adr = 0x00033001FA424301ull,
- .num_endpoints = 1,
- .endpoints = &single_endpoint,
+ .num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
+ .endpoints = cs42l43_endpoints,
.name_prefix = "cs42l43"
}
};
@@ -443,13 +466,13 @@ static const struct snd_soc_acpi_adr_device cs35l56_1_adr[] = {
.adr = 0x00013701FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_l_endpoint,
- .name_prefix = "AMP8"
+ .name_prefix = "AMP3"
},
{
.adr = 0x00013601FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_2_endpoint,
- .name_prefix = "AMP7"
+ .name_prefix = "AMP4"
}
};
@@ -472,19 +495,9 @@ static const struct snd_soc_acpi_link_adr tgl_cs42l43_cs35l56[] = {
{}
};
-static const struct snd_soc_acpi_codecs tgl_max98373_amp = {
- .num_codecs = 1,
- .codecs = {"MX98373"}
-};
-
-static const struct snd_soc_acpi_codecs tgl_rt1011_amp = {
- .num_codecs = 1,
- .codecs = {"10EC1011"}
-};
-
static const struct snd_soc_acpi_codecs tgl_rt5682_rt5682s_hp = {
.num_codecs = 2,
- .codecs = {"10EC5682", "RTL5682"},
+ .codecs = {RT5682_ACPI_HID, RT5682S_ACPI_HID},
};
static const struct snd_soc_acpi_codecs tgl_lt6911_hdmi = {
@@ -494,27 +507,6 @@ static const struct snd_soc_acpi_codecs tgl_lt6911_hdmi = {
struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = {
{
- .comp_ids = &tgl_rt5682_rt5682s_hp,
- .drv_name = "tgl_rt5682_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &tgl_codecs,
- .sof_tplg_filename = "sof-tgl-max98357a-rt5682.tplg",
- },
- {
- .comp_ids = &tgl_rt5682_rt5682s_hp,
- .drv_name = "tgl_rt5682_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &tgl_max98373_amp,
- .sof_tplg_filename = "sof-tgl-max98373-rt5682.tplg",
- },
- {
- .comp_ids = &tgl_rt5682_rt5682s_hp,
- .drv_name = "tgl_rt5682_def",
- .machine_quirk = snd_soc_acpi_codec_list,
- .quirk_data = &tgl_rt1011_amp,
- .sof_tplg_filename = "sof-tgl-rt1011-rt5682.tplg",
- },
- {
.comp_ids = &essx_83x6,
.drv_name = "sof-essx8336",
.sof_tplg_filename = "sof-tgl-es8336", /* the tplg suffix is added at run time */
@@ -522,6 +514,17 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = {
SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
+ /* place boards for each headphone codec: sof driver will complete the
+ * tplg name and machine driver will detect the amp type
+ */
+ {
+ .comp_ids = &tgl_rt5682_rt5682s_hp,
+ .drv_name = "tgl_rt5682_def",
+ .sof_tplg_filename = "sof-tgl", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME |
+ SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME,
+ },
+ /* place amp-only boards in the end of table */
{
.id = "10EC1308",
.drv_name = "tgl_rt1308_hdmi_ssp",
@@ -533,6 +536,194 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = {
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_machines);
+static const struct snd_soc_acpi_endpoint cs35l56_l_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 2,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_r_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 2,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_2_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 2,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 2,
+ .group_id = 2,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_3_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 3,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 3,
+ .group_id = 2,
+ },
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_4_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 4,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 4,
+ .group_id = 2,
+ }
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_5_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 5,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 5,
+ .group_id = 2,
+ }
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_6_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 6,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 6,
+ .group_id = 2,
+ }
+};
+
+static const struct snd_soc_acpi_endpoint cs35l56_7_fb_endpoints[] = {
+ { /* Speaker Playback Endpoint */
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 7,
+ .group_id = 1,
+ },
+ { /* Feedback Capture Endpoint */
+ .num = 1,
+ .aggregated = 1,
+ .group_position = 7,
+ .group_id = 2,
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_sdw_eight_1_4_fb_adr[] = {
+ {
+ .adr = 0x00003301fa355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_l_fb_endpoints),
+ .endpoints = cs35l56_l_fb_endpoints,
+ .name_prefix = "AMP1"
+ },
+ {
+ .adr = 0x00003201fa355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_2_fb_endpoints),
+ .endpoints = cs35l56_2_fb_endpoints,
+ .name_prefix = "AMP2"
+ },
+ {
+ .adr = 0x00003101fa355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_4_fb_endpoints),
+ .endpoints = cs35l56_4_fb_endpoints,
+ .name_prefix = "AMP3"
+ },
+ {
+ .adr = 0x00003001fa355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_6_fb_endpoints),
+ .endpoints = cs35l56_6_fb_endpoints,
+ .name_prefix = "AMP4"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_sdw_eight_5_8_fb_adr[] = {
+ {
+ .adr = 0x00013701fa355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_r_fb_endpoints),
+ .endpoints = cs35l56_r_fb_endpoints,
+ .name_prefix = "AMP8"
+ },
+ {
+ .adr = 0x00013601fa355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_3_fb_endpoints),
+ .endpoints = cs35l56_3_fb_endpoints,
+ .name_prefix = "AMP7"
+ },
+ {
+ .adr = 0x00013501fa355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_5_fb_endpoints),
+ .endpoints = cs35l56_5_fb_endpoints,
+ .name_prefix = "AMP6"
+ },
+ {
+ .adr = 0x00013401fa355601ull,
+ .num_endpoints = ARRAY_SIZE(cs35l56_7_fb_endpoints),
+ .endpoints = cs35l56_7_fb_endpoints,
+ .name_prefix = "AMP5"
+ },
+};
+
+static const struct snd_soc_acpi_link_adr up_extreme_cs35l56_sdw_eight[] = {
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs35l56_sdw_eight_5_8_fb_adr),
+ .adr_d = cs35l56_sdw_eight_5_8_fb_adr,
+ },
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs35l56_sdw_eight_1_4_fb_adr),
+ .adr_d = cs35l56_sdw_eight_1_4_fb_adr,
+ },
+ {}
+};
+
/* this table is used when there is no I2S codec present */
struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = {
/* mockup tests need to be first */
@@ -632,6 +823,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = {
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-tgl-rt711.tplg",
},
+ {
+ .link_mask = BIT(0) | BIT(1),
+ .links = up_extreme_cs35l56_sdw_eight,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-tgl-cs35l56-l01-fb8.tplg"
+ },
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_sdw_machines);
diff --git a/sound/soc/intel/common/soc-intel-quirks.h b/sound/soc/intel/common/soc-intel-quirks.h
index de4e550c5b34..42bd51456b94 100644
--- a/sound/soc/intel/common/soc-intel-quirks.h
+++ b/sound/soc/intel/common/soc-intel-quirks.h
@@ -11,7 +11,7 @@
#include <linux/platform_data/x86/soc.h>
-#if IS_ENABLED(CONFIG_X86)
+#if IS_REACHABLE(CONFIG_IOSF_MBI)
#include <linux/dmi.h>
#include <asm/iosf_mbi.h>
diff --git a/sound/soc/intel/common/sof-function-topology-lib.c b/sound/soc/intel/common/sof-function-topology-lib.c
new file mode 100644
index 000000000000..90fe7aa3df1c
--- /dev/null
+++ b/sound/soc/intel/common/sof-function-topology-lib.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2025 Intel Corporation.
+//
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/firmware.h>
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
+#include "sof-function-topology-lib.h"
+
+enum tplg_device_id {
+ TPLG_DEVICE_SDCA_JACK,
+ TPLG_DEVICE_SDCA_AMP,
+ TPLG_DEVICE_SDCA_MIC,
+ TPLG_DEVICE_INTEL_PCH_DMIC,
+ TPLG_DEVICE_HDMI,
+ TPLG_DEVICE_MAX
+};
+
+#define SDCA_DEVICE_MASK (BIT(TPLG_DEVICE_SDCA_JACK) | BIT(TPLG_DEVICE_SDCA_AMP) | \
+ BIT(TPLG_DEVICE_SDCA_MIC))
+
+#define SOF_INTEL_PLATFORM_NAME_MAX 4
+
+int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach,
+ const char *prefix, const char ***tplg_files)
+{
+ struct snd_soc_acpi_mach_params mach_params = mach->mach_params;
+ struct snd_soc_dai_link *dai_link;
+ const struct firmware *fw;
+ char platform[SOF_INTEL_PLATFORM_NAME_MAX];
+ unsigned long tplg_mask = 0;
+ int tplg_num = 0;
+ int tplg_dev;
+ int ret;
+ int i;
+
+ ret = sscanf(mach->sof_tplg_filename, "sof-%3s-*.tplg", platform);
+ if (ret != 1) {
+ dev_err(card->dev, "Invalid platform name %s of tplg %s\n",
+ platform, mach->sof_tplg_filename);
+ return -EINVAL;
+ }
+
+ for_each_card_prelinks(card, i, dai_link) {
+ char *tplg_dev_name;
+
+ dev_dbg(card->dev, "dai_link %s id %d\n", dai_link->name, dai_link->id);
+ if (strstr(dai_link->name, "SimpleJack")) {
+ tplg_dev = TPLG_DEVICE_SDCA_JACK;
+ tplg_dev_name = "sdca-jack";
+ } else if (strstr(dai_link->name, "SmartAmp")) {
+ tplg_dev = TPLG_DEVICE_SDCA_AMP;
+ tplg_dev_name = devm_kasprintf(card->dev, GFP_KERNEL,
+ "sdca-%damp", dai_link->num_cpus);
+ if (!tplg_dev_name)
+ return -ENOMEM;
+ } else if (strstr(dai_link->name, "SmartMic")) {
+ tplg_dev = TPLG_DEVICE_SDCA_MIC;
+ tplg_dev_name = "sdca-mic";
+ } else if (strstr(dai_link->name, "dmic")) {
+ switch (mach_params.dmic_num) {
+ case 2:
+ tplg_dev_name = "dmic-2ch";
+ break;
+ case 4:
+ tplg_dev_name = "dmic-4ch";
+ break;
+ default:
+ dev_warn(card->dev,
+ "only -2ch and -4ch are supported for dmic\n");
+ continue;
+ }
+ tplg_dev = TPLG_DEVICE_INTEL_PCH_DMIC;
+ } else if (strstr(dai_link->name, "iDisp")) {
+ tplg_dev = TPLG_DEVICE_HDMI;
+ tplg_dev_name = "hdmi-pcm5";
+
+ } else {
+ /* The dai link is not supported by separated tplg yet */
+ dev_dbg(card->dev,
+ "dai_link %s is not supported by separated tplg yet\n",
+ dai_link->name);
+ return 0;
+ }
+ if (tplg_mask & BIT(tplg_dev))
+ continue;
+
+ tplg_mask |= BIT(tplg_dev);
+
+ /*
+ * The tplg file naming rule is sof-<platform>-<function>-id<BE id number>.tplg
+ * where <platform> is only required for the DMIC function as the nhlt blob
+ * is platform dependent.
+ */
+ switch (tplg_dev) {
+ case TPLG_DEVICE_INTEL_PCH_DMIC:
+ (*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL,
+ "%s/sof-%s-%s-id%d.tplg",
+ prefix, platform,
+ tplg_dev_name, dai_link->id);
+ break;
+ default:
+ (*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL,
+ "%s/sof-%s-id%d.tplg",
+ prefix, tplg_dev_name,
+ dai_link->id);
+ break;
+ }
+ if (!(*tplg_files)[tplg_num])
+ return -ENOMEM;
+ tplg_num++;
+ }
+
+ dev_dbg(card->dev, "tplg_mask %#lx tplg_num %d\n", tplg_mask, tplg_num);
+
+ /* Check presence of sub-topologies */
+ for (i = 0; i < tplg_num; i++) {
+ ret = firmware_request_nowarn(&fw, (*tplg_files)[i], card->dev);
+ if (!ret) {
+ release_firmware(fw);
+ } else {
+ dev_dbg(card->dev, "Failed to open topology file: %s\n", (*tplg_files)[i]);
+ return 0;
+ }
+ }
+
+ return tplg_num;
+}
+
diff --git a/sound/soc/intel/common/sof-function-topology-lib.h b/sound/soc/intel/common/sof-function-topology-lib.h
new file mode 100644
index 000000000000..e7d0c39d0788
--- /dev/null
+++ b/sound/soc/intel/common/sof-function-topology-lib.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * soc-acpi-intel-get-tplg.h - get-tplg-files ops
+ *
+ * Copyright (c) 2025, Intel Corporation.
+ *
+ */
+
+#ifndef _SND_SOC_ACPI_INTEL_GET_TPLG_H
+#define _SND_SOC_ACPI_INTEL_GET_TPLG_H
+
+int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach,
+ const char *prefix, const char ***tplg_files);
+
+#endif
diff --git a/sound/soc/intel/common/sst-dsp-priv.h b/sound/soc/intel/common/sst-dsp-priv.h
deleted file mode 100644
index de2b44568feb..000000000000
--- a/sound/soc/intel/common/sst-dsp-priv.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Intel Smart Sound Technology
- *
- * Copyright (C) 2013, Intel Corporation. All rights reserved.
- */
-
-#ifndef __SOUND_SOC_SST_DSP_PRIV_H
-#define __SOUND_SOC_SST_DSP_PRIV_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/firmware.h>
-
-#include "../skylake/skl-sst-dsp.h"
-
-/*
- * DSP Operations exported by platform Audio DSP driver.
- */
-struct sst_ops {
- /* Shim IO */
- void (*write)(void __iomem *addr, u32 offset, u32 value);
- u32 (*read)(void __iomem *addr, u32 offset);
-
- /* IRQ handlers */
- irqreturn_t (*irq_handler)(int irq, void *context);
-
- /* SST init and free */
- int (*init)(struct sst_dsp *sst);
- void (*free)(struct sst_dsp *sst);
-};
-
-/*
- * Audio DSP memory offsets and addresses.
- */
-struct sst_addr {
- u32 sram0_base;
- u32 sram1_base;
- u32 w0_stat_sz;
- u32 w0_up_sz;
- void __iomem *lpe;
- void __iomem *shim;
-};
-
-/*
- * Audio DSP Mailbox configuration.
- */
-struct sst_mailbox {
- void __iomem *in_base;
- void __iomem *out_base;
- size_t in_size;
- size_t out_size;
-};
-
-/*
- * Generic SST Shim Interface.
- */
-struct sst_dsp {
-
- /* Shared for all platforms */
-
- /* runtime */
- struct sst_dsp_device *sst_dev;
- spinlock_t spinlock; /* IPC locking */
- struct mutex mutex; /* DSP FW lock */
- struct device *dev;
- void *thread_context;
- int irq;
- u32 id;
-
- /* operations */
- struct sst_ops *ops;
-
- /* debug FS */
- struct dentry *debugfs_root;
-
- /* base addresses */
- struct sst_addr addr;
-
- /* mailbox */
- struct sst_mailbox mailbox;
-
- /* SST FW files loaded and their modules */
- struct list_head module_list;
-
- /* SKL data */
-
- const char *fw_name;
-
- /* To allocate CL dma buffers */
- struct skl_dsp_loader_ops dsp_ops;
- struct skl_dsp_fw_ops fw_ops;
- int sst_state;
- struct skl_cl_dev cl_dev;
- u32 intr_status;
- const struct firmware *fw;
- struct snd_dma_buffer dmab;
-};
-
-#endif
diff --git a/sound/soc/intel/common/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c
deleted file mode 100644
index 229d09d61afb..000000000000
--- a/sound/soc/intel/common/sst-dsp.c
+++ /dev/null
@@ -1,250 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Intel Smart Sound Technology (SST) DSP Core Driver
- *
- * Copyright (C) 2013, Intel Corporation. All rights reserved.
- */
-
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/io-64-nonatomic-lo-hi.h>
-#include <linux/delay.h>
-
-#include "sst-dsp.h"
-#include "sst-dsp-priv.h"
-
-#define CREATE_TRACE_POINTS
-#include <trace/events/intel-sst.h>
-
-/* Internal generic low-level SST IO functions - can be overidden */
-void sst_shim32_write(void __iomem *addr, u32 offset, u32 value)
-{
- writel(value, addr + offset);
-}
-EXPORT_SYMBOL_GPL(sst_shim32_write);
-
-u32 sst_shim32_read(void __iomem *addr, u32 offset)
-{
- return readl(addr + offset);
-}
-EXPORT_SYMBOL_GPL(sst_shim32_read);
-
-void sst_shim32_write64(void __iomem *addr, u32 offset, u64 value)
-{
- writeq(value, addr + offset);
-}
-EXPORT_SYMBOL_GPL(sst_shim32_write64);
-
-u64 sst_shim32_read64(void __iomem *addr, u32 offset)
-{
- return readq(addr + offset);
-}
-EXPORT_SYMBOL_GPL(sst_shim32_read64);
-
-/* Public API */
-void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sst->spinlock, flags);
- sst->ops->write(sst->addr.shim, offset, value);
- spin_unlock_irqrestore(&sst->spinlock, flags);
-}
-EXPORT_SYMBOL_GPL(sst_dsp_shim_write);
-
-u32 sst_dsp_shim_read(struct sst_dsp *sst, u32 offset)
-{
- unsigned long flags;
- u32 val;
-
- spin_lock_irqsave(&sst->spinlock, flags);
- val = sst->ops->read(sst->addr.shim, offset);
- spin_unlock_irqrestore(&sst->spinlock, flags);
-
- return val;
-}
-EXPORT_SYMBOL_GPL(sst_dsp_shim_read);
-
-void sst_dsp_shim_write_unlocked(struct sst_dsp *sst, u32 offset, u32 value)
-{
- sst->ops->write(sst->addr.shim, offset, value);
-}
-EXPORT_SYMBOL_GPL(sst_dsp_shim_write_unlocked);
-
-u32 sst_dsp_shim_read_unlocked(struct sst_dsp *sst, u32 offset)
-{
- return sst->ops->read(sst->addr.shim, offset);
-}
-EXPORT_SYMBOL_GPL(sst_dsp_shim_read_unlocked);
-
-int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset,
- u32 mask, u32 value)
-{
- bool change;
- unsigned int old, new;
- u32 ret;
-
- ret = sst_dsp_shim_read_unlocked(sst, offset);
-
- old = ret;
- new = (old & (~mask)) | (value & mask);
-
- change = (old != new);
- if (change)
- sst_dsp_shim_write_unlocked(sst, offset, new);
-
- return change;
-}
-EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_unlocked);
-
-/* This is for registers bits with attribute RWC */
-void sst_dsp_shim_update_bits_forced_unlocked(struct sst_dsp *sst, u32 offset,
- u32 mask, u32 value)
-{
- unsigned int old, new;
- u32 ret;
-
- ret = sst_dsp_shim_read_unlocked(sst, offset);
-
- old = ret;
- new = (old & (~mask)) | (value & mask);
-
- sst_dsp_shim_write_unlocked(sst, offset, new);
-}
-EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_forced_unlocked);
-
-int sst_dsp_shim_update_bits(struct sst_dsp *sst, u32 offset,
- u32 mask, u32 value)
-{
- unsigned long flags;
- bool change;
-
- spin_lock_irqsave(&sst->spinlock, flags);
- change = sst_dsp_shim_update_bits_unlocked(sst, offset, mask, value);
- spin_unlock_irqrestore(&sst->spinlock, flags);
- return change;
-}
-EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits);
-
-/* This is for registers bits with attribute RWC */
-void sst_dsp_shim_update_bits_forced(struct sst_dsp *sst, u32 offset,
- u32 mask, u32 value)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sst->spinlock, flags);
- sst_dsp_shim_update_bits_forced_unlocked(sst, offset, mask, value);
- spin_unlock_irqrestore(&sst->spinlock, flags);
-}
-EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_forced);
-
-int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask,
- u32 target, u32 time, char *operation)
-{
- u32 reg;
- unsigned long timeout;
- int k = 0, s = 500;
-
- /*
- * split the loop into sleeps of varying resolution. more accurately,
- * the range of wakeups are:
- * Phase 1(first 5ms): min sleep 0.5ms; max sleep 1ms.
- * Phase 2:( 5ms to 10ms) : min sleep 0.5ms; max sleep 10ms
- * (usleep_range (500, 1000) and usleep_range(5000, 10000) are
- * both possible in this phase depending on whether k > 10 or not).
- * Phase 3: (beyond 10 ms) min sleep 5ms; max sleep 10ms.
- */
-
- timeout = jiffies + msecs_to_jiffies(time);
- while ((((reg = sst_dsp_shim_read_unlocked(ctx, offset)) & mask) != target)
- && time_before(jiffies, timeout)) {
- k++;
- if (k > 10)
- s = 5000;
-
- usleep_range(s, 2*s);
- }
-
- if ((reg & mask) == target) {
- dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s successful\n",
- reg, operation);
-
- return 0;
- }
-
- dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s timedout\n",
- reg, operation);
- return -ETIME;
-}
-EXPORT_SYMBOL_GPL(sst_dsp_register_poll);
-
-int sst_dsp_mailbox_init(struct sst_dsp *sst, u32 inbox_offset, size_t inbox_size,
- u32 outbox_offset, size_t outbox_size)
-{
- sst->mailbox.in_base = sst->addr.lpe + inbox_offset;
- sst->mailbox.out_base = sst->addr.lpe + outbox_offset;
- sst->mailbox.in_size = inbox_size;
- sst->mailbox.out_size = outbox_size;
- return 0;
-}
-EXPORT_SYMBOL_GPL(sst_dsp_mailbox_init);
-
-void sst_dsp_outbox_write(struct sst_dsp *sst, void *message, size_t bytes)
-{
- u32 i;
-
- trace_sst_ipc_outbox_write(bytes);
-
- memcpy_toio(sst->mailbox.out_base, message, bytes);
-
- for (i = 0; i < bytes; i += 4)
- trace_sst_ipc_outbox_wdata(i, *(u32 *)(message + i));
-}
-EXPORT_SYMBOL_GPL(sst_dsp_outbox_write);
-
-void sst_dsp_outbox_read(struct sst_dsp *sst, void *message, size_t bytes)
-{
- u32 i;
-
- trace_sst_ipc_outbox_read(bytes);
-
- memcpy_fromio(message, sst->mailbox.out_base, bytes);
-
- for (i = 0; i < bytes; i += 4)
- trace_sst_ipc_outbox_rdata(i, *(u32 *)(message + i));
-}
-EXPORT_SYMBOL_GPL(sst_dsp_outbox_read);
-
-void sst_dsp_inbox_write(struct sst_dsp *sst, void *message, size_t bytes)
-{
- u32 i;
-
- trace_sst_ipc_inbox_write(bytes);
-
- memcpy_toio(sst->mailbox.in_base, message, bytes);
-
- for (i = 0; i < bytes; i += 4)
- trace_sst_ipc_inbox_wdata(i, *(u32 *)(message + i));
-}
-EXPORT_SYMBOL_GPL(sst_dsp_inbox_write);
-
-void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes)
-{
- u32 i;
-
- trace_sst_ipc_inbox_read(bytes);
-
- memcpy_fromio(message, sst->mailbox.in_base, bytes);
-
- for (i = 0; i < bytes; i += 4)
- trace_sst_ipc_inbox_rdata(i, *(u32 *)(message + i));
-}
-EXPORT_SYMBOL_GPL(sst_dsp_inbox_read);
-
-/* Module information */
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_DESCRIPTION("Intel SST Core");
-MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/intel/common/sst-dsp.h b/sound/soc/intel/common/sst-dsp.h
deleted file mode 100644
index f111fd3f334b..000000000000
--- a/sound/soc/intel/common/sst-dsp.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Intel Smart Sound Technology (SST) Core
- *
- * Copyright (C) 2013, Intel Corporation. All rights reserved.
- */
-
-#ifndef __SOUND_SOC_SST_DSP_H
-#define __SOUND_SOC_SST_DSP_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-
-struct sst_dsp;
-
-/*
- * SST Device.
- *
- * This structure is populated by the SST core driver.
- */
-struct sst_dsp_device {
- /* Mandatory fields */
- struct sst_ops *ops;
- irqreturn_t (*thread)(int irq, void *context);
- void *thread_context;
-};
-
-/* SHIM Read / Write */
-void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value);
-u32 sst_dsp_shim_read(struct sst_dsp *sst, u32 offset);
-int sst_dsp_shim_update_bits(struct sst_dsp *sst, u32 offset,
- u32 mask, u32 value);
-void sst_dsp_shim_update_bits_forced(struct sst_dsp *sst, u32 offset,
- u32 mask, u32 value);
-
-/* SHIM Read / Write Unlocked for callers already holding sst lock */
-void sst_dsp_shim_write_unlocked(struct sst_dsp *sst, u32 offset, u32 value);
-u32 sst_dsp_shim_read_unlocked(struct sst_dsp *sst, u32 offset);
-int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset,
- u32 mask, u32 value);
-void sst_dsp_shim_update_bits_forced_unlocked(struct sst_dsp *sst, u32 offset,
- u32 mask, u32 value);
-
-/* Internal generic low-level SST IO functions - can be overidden */
-void sst_shim32_write(void __iomem *addr, u32 offset, u32 value);
-u32 sst_shim32_read(void __iomem *addr, u32 offset);
-void sst_shim32_write64(void __iomem *addr, u32 offset, u64 value);
-u64 sst_shim32_read64(void __iomem *addr, u32 offset);
-
-/* Mailbox management */
-int sst_dsp_mailbox_init(struct sst_dsp *sst, u32 inbox_offset,
- size_t inbox_size, u32 outbox_offset, size_t outbox_size);
-void sst_dsp_inbox_write(struct sst_dsp *sst, void *message, size_t bytes);
-void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes);
-void sst_dsp_outbox_write(struct sst_dsp *sst, void *message, size_t bytes);
-void sst_dsp_outbox_read(struct sst_dsp *sst, void *message, size_t bytes);
-int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask,
- u32 target, u32 time, char *operation);
-
-#endif
diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c
deleted file mode 100644
index 89c10724d2a3..000000000000
--- a/sound/soc/intel/common/sst-ipc.c
+++ /dev/null
@@ -1,294 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Intel SST generic IPC Support
- *
- * Copyright (C) 2015, Intel Corporation. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <sound/asound.h>
-
-#include "sst-dsp.h"
-#include "sst-dsp-priv.h"
-#include "sst-ipc.h"
-
-/* IPC message timeout (msecs) */
-#define IPC_TIMEOUT_MSECS 300
-
-#define IPC_EMPTY_LIST_SIZE 8
-
-/* locks held by caller */
-static struct ipc_message *msg_get_empty(struct sst_generic_ipc *ipc)
-{
- struct ipc_message *msg = NULL;
-
- if (!list_empty(&ipc->empty_list)) {
- msg = list_first_entry(&ipc->empty_list, struct ipc_message,
- list);
- list_del(&msg->list);
- }
-
- return msg;
-}
-
-static int tx_wait_done(struct sst_generic_ipc *ipc,
- struct ipc_message *msg, struct sst_ipc_message *reply)
-{
- unsigned long flags;
- int ret;
-
- /* wait for DSP completion (in all cases atm inc pending) */
- ret = wait_event_timeout(msg->waitq, msg->complete,
- msecs_to_jiffies(IPC_TIMEOUT_MSECS));
-
- spin_lock_irqsave(&ipc->dsp->spinlock, flags);
- if (ret == 0) {
- if (ipc->ops.shim_dbg != NULL)
- ipc->ops.shim_dbg(ipc, "message timeout");
-
- list_del(&msg->list);
- ret = -ETIMEDOUT;
- } else {
-
- /* copy the data returned from DSP */
- if (reply) {
- reply->header = msg->rx.header;
- if (reply->data)
- memcpy(reply->data, msg->rx.data, msg->rx.size);
- }
- ret = msg->errno;
- }
-
- list_add_tail(&msg->list, &ipc->empty_list);
- spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
- return ret;
-}
-
-static int ipc_tx_message(struct sst_generic_ipc *ipc,
- struct sst_ipc_message request,
- struct sst_ipc_message *reply, int wait)
-{
- struct ipc_message *msg;
- unsigned long flags;
-
- spin_lock_irqsave(&ipc->dsp->spinlock, flags);
-
- msg = msg_get_empty(ipc);
- if (msg == NULL) {
- spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
- return -EBUSY;
- }
-
- msg->tx.header = request.header;
- msg->tx.size = request.size;
- msg->rx.header = 0;
- msg->rx.size = reply ? reply->size : 0;
- msg->wait = wait;
- msg->errno = 0;
- msg->pending = false;
- msg->complete = false;
-
- if ((request.size) && (ipc->ops.tx_data_copy != NULL))
- ipc->ops.tx_data_copy(msg, request.data, request.size);
-
- list_add_tail(&msg->list, &ipc->tx_list);
- schedule_work(&ipc->kwork);
- spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
-
- if (wait)
- return tx_wait_done(ipc, msg, reply);
- else
- return 0;
-}
-
-static int msg_empty_list_init(struct sst_generic_ipc *ipc)
-{
- int i;
-
- ipc->msg = kcalloc(IPC_EMPTY_LIST_SIZE, sizeof(struct ipc_message),
- GFP_KERNEL);
- if (ipc->msg == NULL)
- return -ENOMEM;
-
- for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
- ipc->msg[i].tx.data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL);
- if (ipc->msg[i].tx.data == NULL)
- goto free_mem;
-
- ipc->msg[i].rx.data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL);
- if (ipc->msg[i].rx.data == NULL) {
- kfree(ipc->msg[i].tx.data);
- goto free_mem;
- }
-
- init_waitqueue_head(&ipc->msg[i].waitq);
- list_add(&ipc->msg[i].list, &ipc->empty_list);
- }
-
- return 0;
-
-free_mem:
- while (i > 0) {
- kfree(ipc->msg[i-1].tx.data);
- kfree(ipc->msg[i-1].rx.data);
- --i;
- }
- kfree(ipc->msg);
-
- return -ENOMEM;
-}
-
-static void ipc_tx_msgs(struct work_struct *work)
-{
- struct sst_generic_ipc *ipc =
- container_of(work, struct sst_generic_ipc, kwork);
- struct ipc_message *msg;
-
- spin_lock_irq(&ipc->dsp->spinlock);
-
- while (!list_empty(&ipc->tx_list) && !ipc->pending) {
- /* if the DSP is busy, we will TX messages after IRQ.
- * also postpone if we are in the middle of processing
- * completion irq
- */
- if (ipc->ops.is_dsp_busy && ipc->ops.is_dsp_busy(ipc->dsp)) {
- dev_dbg(ipc->dev, "ipc_tx_msgs dsp busy\n");
- break;
- }
-
- msg = list_first_entry(&ipc->tx_list, struct ipc_message, list);
- list_move(&msg->list, &ipc->rx_list);
-
- if (ipc->ops.tx_msg != NULL)
- ipc->ops.tx_msg(ipc, msg);
- }
-
- spin_unlock_irq(&ipc->dsp->spinlock);
-}
-
-int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc,
- struct sst_ipc_message request, struct sst_ipc_message *reply)
-{
- int ret;
-
- /*
- * DSP maybe in lower power active state, so
- * check if the DSP supports DSP lp On method
- * if so invoke that before sending IPC
- */
- if (ipc->ops.check_dsp_lp_on)
- if (ipc->ops.check_dsp_lp_on(ipc->dsp, true))
- return -EIO;
-
- ret = ipc_tx_message(ipc, request, reply, 1);
-
- if (ipc->ops.check_dsp_lp_on)
- if (ipc->ops.check_dsp_lp_on(ipc->dsp, false))
- return -EIO;
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait);
-
-int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc,
- struct sst_ipc_message request)
-{
- return ipc_tx_message(ipc, request, NULL, 0);
-}
-EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait);
-
-int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc,
- struct sst_ipc_message request, struct sst_ipc_message *reply)
-{
- return ipc_tx_message(ipc, request, reply, 1);
-}
-EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nopm);
-
-struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
- u64 header)
-{
- struct ipc_message *msg;
- u64 mask;
-
- if (ipc->ops.reply_msg_match != NULL)
- header = ipc->ops.reply_msg_match(header, &mask);
- else
- mask = (u64)-1;
-
- if (list_empty(&ipc->rx_list)) {
- dev_err(ipc->dev, "error: rx list empty but received 0x%llx\n",
- header);
- return NULL;
- }
-
- list_for_each_entry(msg, &ipc->rx_list, list) {
- if ((msg->tx.header & mask) == header)
- return msg;
- }
-
- return NULL;
-}
-EXPORT_SYMBOL_GPL(sst_ipc_reply_find_msg);
-
-/* locks held by caller */
-void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc,
- struct ipc_message *msg)
-{
- msg->complete = true;
-
- if (!msg->wait)
- list_add_tail(&msg->list, &ipc->empty_list);
- else
- wake_up(&msg->waitq);
-}
-EXPORT_SYMBOL_GPL(sst_ipc_tx_msg_reply_complete);
-
-int sst_ipc_init(struct sst_generic_ipc *ipc)
-{
- int ret;
-
- INIT_LIST_HEAD(&ipc->tx_list);
- INIT_LIST_HEAD(&ipc->rx_list);
- INIT_LIST_HEAD(&ipc->empty_list);
- init_waitqueue_head(&ipc->wait_txq);
-
- ret = msg_empty_list_init(ipc);
- if (ret < 0)
- return -ENOMEM;
-
- INIT_WORK(&ipc->kwork, ipc_tx_msgs);
- return 0;
-}
-EXPORT_SYMBOL_GPL(sst_ipc_init);
-
-void sst_ipc_fini(struct sst_generic_ipc *ipc)
-{
- int i;
-
- cancel_work_sync(&ipc->kwork);
-
- if (ipc->msg) {
- for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
- kfree(ipc->msg[i].tx.data);
- kfree(ipc->msg[i].rx.data);
- }
- kfree(ipc->msg);
- }
-}
-EXPORT_SYMBOL_GPL(sst_ipc_fini);
-
-/* Module information */
-MODULE_AUTHOR("Jin Yao");
-MODULE_DESCRIPTION("Intel SST IPC generic");
-MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h
deleted file mode 100644
index 77d651e888f9..000000000000
--- a/sound/soc/intel/common/sst-ipc.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Intel SST generic IPC Support
- *
- * Copyright (C) 2015, Intel Corporation. All rights reserved.
- */
-
-#ifndef __SST_GENERIC_IPC_H
-#define __SST_GENERIC_IPC_H
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <linux/workqueue.h>
-#include <linux/sched.h>
-
-struct sst_ipc_message {
- u64 header;
- void *data;
- size_t size;
-};
-
-struct ipc_message {
- struct list_head list;
- struct sst_ipc_message tx;
- struct sst_ipc_message rx;
-
- wait_queue_head_t waitq;
- bool pending;
- bool complete;
- bool wait;
- int errno;
-};
-
-struct sst_generic_ipc;
-struct sst_dsp;
-
-struct sst_plat_ipc_ops {
- void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *);
- void (*shim_dbg)(struct sst_generic_ipc *, const char *);
- void (*tx_data_copy)(struct ipc_message *, char *, size_t);
- u64 (*reply_msg_match)(u64 header, u64 *mask);
- bool (*is_dsp_busy)(struct sst_dsp *dsp);
- int (*check_dsp_lp_on)(struct sst_dsp *dsp, bool state);
-};
-
-/* SST generic IPC data */
-struct sst_generic_ipc {
- struct device *dev;
- struct sst_dsp *dsp;
-
- /* IPC messaging */
- struct list_head tx_list;
- struct list_head rx_list;
- struct list_head empty_list;
- wait_queue_head_t wait_txq;
- struct task_struct *tx_thread;
- struct work_struct kwork;
- bool pending;
- struct ipc_message *msg;
- int tx_data_max_size;
- int rx_data_max_size;
-
- struct sst_plat_ipc_ops ops;
-};
-
-int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc,
- struct sst_ipc_message request, struct sst_ipc_message *reply);
-
-int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc,
- struct sst_ipc_message request);
-
-int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc,
- struct sst_ipc_message request, struct sst_ipc_message *reply);
-
-struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
- u64 header);
-
-void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc,
- struct ipc_message *msg);
-
-int sst_ipc_init(struct sst_generic_ipc *ipc);
-void sst_ipc_fini(struct sst_generic_ipc *ipc);
-
-#endif
diff --git a/sound/soc/intel/keembay/Makefile b/sound/soc/intel/keembay/Makefile
index 9084e8c63854..3da9a6f9ba2a 100644
--- a/sound/soc/intel/keembay/Makefile
+++ b/sound/soc/intel/keembay/Makefile
@@ -1,4 +1,4 @@
-snd-soc-kmb_platform-objs := \
+snd-soc-kmb_platform-y := \
kmb_platform.o
obj-$(CONFIG_SND_SOC_INTEL_KEEMBAY) += snd-soc-kmb_platform.o
diff --git a/sound/soc/intel/keembay/kmb_platform.c b/sound/soc/intel/keembay/kmb_platform.c
index 37ea2e1d2e92..4ed71d11ad77 100644
--- a/sound/soc/intel/keembay/kmb_platform.c
+++ b/sound/soc/intel/keembay/kmb_platform.c
@@ -814,6 +814,7 @@ static const struct of_device_id kmb_plat_of_match[] = {
{ .compatible = "intel,keembay-tdm", .data = &intel_kmb_tdm_dai},
{}
};
+MODULE_DEVICE_TABLE(of, kmb_plat_of_match);
static int kmb_plat_dai_probe(struct platform_device *pdev)
{
@@ -868,7 +869,7 @@ static int kmb_plat_dai_probe(struct platform_device *pdev)
kmb_i2s->fifo_th = (1 << COMP1_FIFO_DEPTH(comp1_reg)) / 2;
- kmb_i2s->use_pio = !(of_property_read_bool(np, "dmas"));
+ kmb_i2s->use_pio = !of_property_present(np, "dmas");
if (kmb_i2s->use_pio) {
irq = platform_get_irq_optional(pdev, 0);
diff --git a/sound/soc/intel/skylake/Makefile b/sound/soc/intel/skylake/Makefile
deleted file mode 100644
index 1c4649bccec5..000000000000
--- a/sound/soc/intel/skylake/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o skl-topology.o \
- skl-sst-ipc.o skl-sst-dsp.o cnl-sst-dsp.o skl-sst-cldma.o \
- skl-sst.o bxt-sst.o cnl-sst.o skl-sst-utils.o
-
-ifdef CONFIG_DEBUG_FS
- snd-soc-skl-objs += skl-debug.o
-endif
-
-obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON) += snd-soc-skl.o
-
-#Skylake Clock device support
-snd-soc-skl-ssp-clk-objs := skl-ssp-clk.o
-
-obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE_SSP_CLK) += snd-soc-skl-ssp-clk.o
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
deleted file mode 100644
index fd4fdcb95224..000000000000
--- a/sound/soc/intel/skylake/bxt-sst.c
+++ /dev/null
@@ -1,629 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * bxt-sst.c - DSP library functions for BXT platform
- *
- * Copyright (C) 2015-16 Intel Corp
- * Author:Rafal Redzimski <rafal.f.redzimski@intel.com>
- * Jeeja KP <jeeja.kp@intel.com>
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/device.h>
-
-#include "../common/sst-dsp.h"
-#include "../common/sst-dsp-priv.h"
-#include "skl.h"
-
-#define BXT_BASEFW_TIMEOUT 3000
-#define BXT_ROM_INIT_TIMEOUT 70
-#define BXT_IPC_PURGE_FW 0x01004000
-
-#define BXT_ROM_INIT 0x5
-#define BXT_ADSP_SRAM0_BASE 0x80000
-
-/* Firmware status window */
-#define BXT_ADSP_FW_STATUS BXT_ADSP_SRAM0_BASE
-#define BXT_ADSP_ERROR_CODE (BXT_ADSP_FW_STATUS + 0x4)
-
-#define BXT_ADSP_SRAM1_BASE 0xA0000
-
-#define BXT_INSTANCE_ID 0
-#define BXT_BASE_FW_MODULE_ID 0
-
-#define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
-
-/* Delay before scheduling D0i3 entry */
-#define BXT_D0I3_DELAY 5000
-
-static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
-{
- return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
-}
-
-static int
-bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
-{
- struct snd_dma_buffer dmab;
- struct skl_dev *skl = ctx->thread_context;
- struct firmware stripped_fw;
- int ret = 0, i, dma_id, stream_tag;
-
- /* library indices start from 1 to N. 0 represents base FW */
- for (i = 1; i < lib_count; i++) {
- ret = skl_prepare_lib_load(skl, &skl->lib_info[i], &stripped_fw,
- BXT_ADSP_FW_BIN_HDR_OFFSET, i);
- if (ret < 0)
- goto load_library_failed;
-
- stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40,
- stripped_fw.size, &dmab);
- if (stream_tag <= 0) {
- dev_err(ctx->dev, "Lib prepare DMA err: %x\n",
- stream_tag);
- ret = stream_tag;
- goto load_library_failed;
- }
-
- dma_id = stream_tag - 1;
- memcpy(dmab.area, stripped_fw.data, stripped_fw.size);
-
- ctx->dsp_ops.trigger(ctx->dev, true, stream_tag);
- ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i, true);
- if (ret < 0)
- dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n",
- linfo[i].name, ret);
-
- ctx->dsp_ops.trigger(ctx->dev, false, stream_tag);
- ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag);
- }
-
- return ret;
-
-load_library_failed:
- skl_release_library(linfo, lib_count);
- return ret;
-}
-
-/*
- * First boot sequence has some extra steps. Core 0 waits for power
- * status on core 1, so power up core 1 also momentarily, keep it in
- * reset/stall and then turn it off
- */
-static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
- const void *fwdata, u32 fwsize)
-{
- int stream_tag, ret;
-
- stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, fwsize, &ctx->dmab);
- if (stream_tag <= 0) {
- dev_err(ctx->dev, "Failed to prepare DMA FW loading err: %x\n",
- stream_tag);
- return stream_tag;
- }
-
- ctx->dsp_ops.stream_tag = stream_tag;
- memcpy(ctx->dmab.area, fwdata, fwsize);
-
- /* Step 1: Power up core 0 and core1 */
- ret = skl_dsp_core_power_up(ctx, SKL_DSP_CORE0_MASK |
- SKL_DSP_CORE_MASK(1));
- if (ret < 0) {
- dev_err(ctx->dev, "dsp core0/1 power up failed\n");
- goto base_fw_load_failed;
- }
-
- /* Step 2: Purge FW request */
- sst_dsp_shim_write(ctx, SKL_ADSP_REG_HIPCI, SKL_ADSP_REG_HIPCI_BUSY |
- (BXT_IPC_PURGE_FW | ((stream_tag - 1) << 9)));
-
- /* Step 3: Unset core0 reset state & unstall/run core0 */
- ret = skl_dsp_start_core(ctx, SKL_DSP_CORE0_MASK);
- if (ret < 0) {
- dev_err(ctx->dev, "Start dsp core failed ret: %d\n", ret);
- ret = -EIO;
- goto base_fw_load_failed;
- }
-
- /* Step 4: Wait for DONE Bit */
- ret = sst_dsp_register_poll(ctx, SKL_ADSP_REG_HIPCIE,
- SKL_ADSP_REG_HIPCIE_DONE,
- SKL_ADSP_REG_HIPCIE_DONE,
- BXT_INIT_TIMEOUT, "HIPCIE Done");
- if (ret < 0) {
- dev_err(ctx->dev, "Timeout for Purge Request%d\n", ret);
- goto base_fw_load_failed;
- }
-
- /* Step 5: power down core1 */
- ret = skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1));
- if (ret < 0) {
- dev_err(ctx->dev, "dsp core1 power down failed\n");
- goto base_fw_load_failed;
- }
-
- /* Step 6: Enable Interrupt */
- skl_ipc_int_enable(ctx);
- skl_ipc_op_int_enable(ctx);
-
- /* Step 7: Wait for ROM init */
- ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK,
- SKL_FW_INIT, BXT_ROM_INIT_TIMEOUT, "ROM Load");
- if (ret < 0) {
- dev_err(ctx->dev, "Timeout for ROM init, ret:%d\n", ret);
- goto base_fw_load_failed;
- }
-
- return ret;
-
-base_fw_load_failed:
- ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, stream_tag);
- skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1));
- skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
- return ret;
-}
-
-static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
-{
- int ret;
-
- ctx->dsp_ops.trigger(ctx->dev, true, ctx->dsp_ops.stream_tag);
- ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK,
- BXT_ROM_INIT, BXT_BASEFW_TIMEOUT, "Firmware boot");
-
- ctx->dsp_ops.trigger(ctx->dev, false, ctx->dsp_ops.stream_tag);
- ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, ctx->dsp_ops.stream_tag);
-
- return ret;
-}
-
-static int bxt_load_base_firmware(struct sst_dsp *ctx)
-{
- struct firmware stripped_fw;
- struct skl_dev *skl = ctx->thread_context;
- int ret, i;
-
- if (ctx->fw == NULL) {
- ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
- if (ret < 0) {
- dev_err(ctx->dev, "Request firmware failed %d\n", ret);
- return ret;
- }
- }
-
- /* prase uuids on first boot */
- if (skl->is_first_boot) {
- ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0);
- if (ret < 0)
- goto sst_load_base_firmware_failed;
- }
-
- stripped_fw.data = ctx->fw->data;
- stripped_fw.size = ctx->fw->size;
- skl_dsp_strip_extended_manifest(&stripped_fw);
-
-
- for (i = 0; i < BXT_FW_ROM_INIT_RETRY; i++) {
- ret = sst_bxt_prepare_fw(ctx, stripped_fw.data, stripped_fw.size);
- if (ret == 0)
- break;
- }
-
- if (ret < 0) {
- dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n",
- sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE),
- sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS));
-
- dev_err(ctx->dev, "Core En/ROM load fail:%d\n", ret);
- goto sst_load_base_firmware_failed;
- }
-
- ret = sst_transfer_fw_host_dma(ctx);
- if (ret < 0) {
- dev_err(ctx->dev, "Transfer firmware failed %d\n", ret);
- dev_info(ctx->dev, "Error code=0x%x: FW status=0x%x\n",
- sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE),
- sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS));
-
- skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
- } else {
- dev_dbg(ctx->dev, "Firmware download successful\n");
- ret = wait_event_timeout(skl->boot_wait, skl->boot_complete,
- msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
- if (ret == 0) {
- dev_err(ctx->dev, "DSP boot fail, FW Ready timeout\n");
- skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
- ret = -EIO;
- } else {
- ret = 0;
- skl->fw_loaded = true;
- }
- }
-
- return ret;
-
-sst_load_base_firmware_failed:
- release_firmware(ctx->fw);
- ctx->fw = NULL;
- return ret;
-}
-
-/*
- * Decide the D0i3 state that can be targeted based on the usecase
- * ref counts and DSP state
- *
- * Decision Matrix: (X= dont care; state = target state)
- *
- * DSP state != SKL_DSP_RUNNING ; state = no d0i3
- *
- * DSP state == SKL_DSP_RUNNING , the following matrix applies
- * non_d0i3 >0; streaming =X; non_streaming =X; state = no d0i3
- * non_d0i3 =X; streaming =0; non_streaming =0; state = no d0i3
- * non_d0i3 =0; streaming >0; non_streaming =X; state = streaming d0i3
- * non_d0i3 =0; streaming =0; non_streaming =X; state = non-streaming d0i3
- */
-static int bxt_d0i3_target_state(struct sst_dsp *ctx)
-{
- struct skl_dev *skl = ctx->thread_context;
- struct skl_d0i3_data *d0i3 = &skl->d0i3;
-
- if (skl->cores.state[SKL_DSP_CORE0_ID] != SKL_DSP_RUNNING)
- return SKL_DSP_D0I3_NONE;
-
- if (d0i3->non_d0i3)
- return SKL_DSP_D0I3_NONE;
- else if (d0i3->streaming)
- return SKL_DSP_D0I3_STREAMING;
- else if (d0i3->non_streaming)
- return SKL_DSP_D0I3_NON_STREAMING;
- else
- return SKL_DSP_D0I3_NONE;
-}
-
-static void bxt_set_dsp_D0i3(struct work_struct *work)
-{
- int ret;
- struct skl_ipc_d0ix_msg msg;
- struct skl_dev *skl = container_of(work,
- struct skl_dev, d0i3.work.work);
- struct sst_dsp *ctx = skl->dsp;
- struct skl_d0i3_data *d0i3 = &skl->d0i3;
- int target_state;
-
- dev_dbg(ctx->dev, "In %s:\n", __func__);
-
- /* D0i3 entry allowed only if core 0 alone is running */
- if (skl_dsp_get_enabled_cores(ctx) != SKL_DSP_CORE0_MASK) {
- dev_warn(ctx->dev,
- "D0i3 allowed when only core0 running:Exit\n");
- return;
- }
-
- target_state = bxt_d0i3_target_state(ctx);
- if (target_state == SKL_DSP_D0I3_NONE)
- return;
-
- msg.instance_id = 0;
- msg.module_id = 0;
- msg.wake = 1;
- msg.streaming = 0;
- if (target_state == SKL_DSP_D0I3_STREAMING)
- msg.streaming = 1;
-
- ret = skl_ipc_set_d0ix(&skl->ipc, &msg);
-
- if (ret < 0) {
- dev_err(ctx->dev, "Failed to set DSP to D0i3 state\n");
- return;
- }
-
- /* Set Vendor specific register D0I3C.I3 to enable D0i3*/
- if (skl->update_d0i3c)
- skl->update_d0i3c(skl->dev, true);
-
- d0i3->state = target_state;
- skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING_D0I3;
-}
-
-static int bxt_schedule_dsp_D0i3(struct sst_dsp *ctx)
-{
- struct skl_dev *skl = ctx->thread_context;
- struct skl_d0i3_data *d0i3 = &skl->d0i3;
-
- /* Schedule D0i3 only if the usecase ref counts are appropriate */
- if (bxt_d0i3_target_state(ctx) != SKL_DSP_D0I3_NONE) {
-
- dev_dbg(ctx->dev, "%s: Schedule D0i3\n", __func__);
-
- schedule_delayed_work(&d0i3->work,
- msecs_to_jiffies(BXT_D0I3_DELAY));
- }
-
- return 0;
-}
-
-static int bxt_set_dsp_D0i0(struct sst_dsp *ctx)
-{
- int ret;
- struct skl_ipc_d0ix_msg msg;
- struct skl_dev *skl = ctx->thread_context;
-
- dev_dbg(ctx->dev, "In %s:\n", __func__);
-
- /* First Cancel any pending attempt to put DSP to D0i3 */
- cancel_delayed_work_sync(&skl->d0i3.work);
-
- /* If DSP is currently in D0i3, bring it to D0i0 */
- if (skl->cores.state[SKL_DSP_CORE0_ID] != SKL_DSP_RUNNING_D0I3)
- return 0;
-
- dev_dbg(ctx->dev, "Set DSP to D0i0\n");
-
- msg.instance_id = 0;
- msg.module_id = 0;
- msg.streaming = 0;
- msg.wake = 0;
-
- if (skl->d0i3.state == SKL_DSP_D0I3_STREAMING)
- msg.streaming = 1;
-
- /* Clear Vendor specific register D0I3C.I3 to disable D0i3*/
- if (skl->update_d0i3c)
- skl->update_d0i3c(skl->dev, false);
-
- ret = skl_ipc_set_d0ix(&skl->ipc, &msg);
- if (ret < 0) {
- dev_err(ctx->dev, "Failed to set DSP to D0i0\n");
- return ret;
- }
-
- skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING;
- skl->d0i3.state = SKL_DSP_D0I3_NONE;
-
- return 0;
-}
-
-static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
-{
- struct skl_dev *skl = ctx->thread_context;
- int ret;
- struct skl_ipc_dxstate_info dx;
- unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
-
- if (skl->fw_loaded == false) {
- skl->boot_complete = false;
- ret = bxt_load_base_firmware(ctx);
- if (ret < 0) {
- dev_err(ctx->dev, "reload fw failed: %d\n", ret);
- return ret;
- }
-
- if (skl->lib_count > 1) {
- ret = bxt_load_library(ctx, skl->lib_info,
- skl->lib_count);
- if (ret < 0) {
- dev_err(ctx->dev, "reload libs failed: %d\n", ret);
- return ret;
- }
- }
- skl->cores.state[core_id] = SKL_DSP_RUNNING;
- return ret;
- }
-
- /* If core 0 is being turned on, turn on core 1 as well */
- if (core_id == SKL_DSP_CORE0_ID)
- ret = skl_dsp_core_power_up(ctx, core_mask |
- SKL_DSP_CORE_MASK(1));
- else
- ret = skl_dsp_core_power_up(ctx, core_mask);
-
- if (ret < 0)
- goto err;
-
- if (core_id == SKL_DSP_CORE0_ID) {
-
- /*
- * Enable interrupt after SPA is set and before
- * DSP is unstalled
- */
- skl_ipc_int_enable(ctx);
- skl_ipc_op_int_enable(ctx);
- skl->boot_complete = false;
- }
-
- ret = skl_dsp_start_core(ctx, core_mask);
- if (ret < 0)
- goto err;
-
- if (core_id == SKL_DSP_CORE0_ID) {
- ret = wait_event_timeout(skl->boot_wait,
- skl->boot_complete,
- msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
-
- /* If core 1 was turned on for booting core 0, turn it off */
- skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1));
- if (ret == 0) {
- dev_err(ctx->dev, "%s: DSP boot timeout\n", __func__);
- dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n",
- sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE),
- sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS));
- dev_err(ctx->dev, "Failed to set core0 to D0 state\n");
- ret = -EIO;
- goto err;
- }
- }
-
- /* Tell FW if additional core in now On */
-
- if (core_id != SKL_DSP_CORE0_ID) {
- dx.core_mask = core_mask;
- dx.dx_mask = core_mask;
-
- ret = skl_ipc_set_dx(&skl->ipc, BXT_INSTANCE_ID,
- BXT_BASE_FW_MODULE_ID, &dx);
- if (ret < 0) {
- dev_err(ctx->dev, "IPC set_dx for core %d fail: %d\n",
- core_id, ret);
- goto err;
- }
- }
-
- skl->cores.state[core_id] = SKL_DSP_RUNNING;
- return 0;
-err:
- if (core_id == SKL_DSP_CORE0_ID)
- core_mask |= SKL_DSP_CORE_MASK(1);
- skl_dsp_disable_core(ctx, core_mask);
-
- return ret;
-}
-
-static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
-{
- int ret;
- struct skl_ipc_dxstate_info dx;
- struct skl_dev *skl = ctx->thread_context;
- unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
-
- dx.core_mask = core_mask;
- dx.dx_mask = SKL_IPC_D3_MASK;
-
- dev_dbg(ctx->dev, "core mask=%x dx_mask=%x\n",
- dx.core_mask, dx.dx_mask);
-
- ret = skl_ipc_set_dx(&skl->ipc, BXT_INSTANCE_ID,
- BXT_BASE_FW_MODULE_ID, &dx);
- if (ret < 0) {
- dev_err(ctx->dev,
- "Failed to set DSP to D3:core id = %d;Continue reset\n",
- core_id);
- /*
- * In case of D3 failure, re-download the firmware, so set
- * fw_loaded to false.
- */
- skl->fw_loaded = false;
- }
-
- if (core_id == SKL_DSP_CORE0_ID) {
- /* disable Interrupt */
- skl_ipc_op_int_disable(ctx);
- skl_ipc_int_disable(ctx);
- }
- ret = skl_dsp_disable_core(ctx, core_mask);
- if (ret < 0) {
- dev_err(ctx->dev, "Failed to disable core %d\n", ret);
- return ret;
- }
- skl->cores.state[core_id] = SKL_DSP_RESET;
- return 0;
-}
-
-static const struct skl_dsp_fw_ops bxt_fw_ops = {
- .set_state_D0 = bxt_set_dsp_D0,
- .set_state_D3 = bxt_set_dsp_D3,
- .set_state_D0i3 = bxt_schedule_dsp_D0i3,
- .set_state_D0i0 = bxt_set_dsp_D0i0,
- .load_fw = bxt_load_base_firmware,
- .get_fw_errcode = bxt_get_errorcode,
- .load_library = bxt_load_library,
-};
-
-static struct sst_ops skl_ops = {
- .irq_handler = skl_dsp_sst_interrupt,
- .write = sst_shim32_write,
- .read = sst_shim32_read,
- .free = skl_dsp_free,
-};
-
-static struct sst_dsp_device skl_dev = {
- .thread = skl_dsp_irq_thread_handler,
- .ops = &skl_ops,
-};
-
-int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
- const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
- struct skl_dev **dsp)
-{
- struct skl_dev *skl;
- struct sst_dsp *sst;
- int ret;
-
- ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &skl_dev);
- if (ret < 0) {
- dev_err(dev, "%s: no device\n", __func__);
- return ret;
- }
-
- skl = *dsp;
- sst = skl->dsp;
- sst->fw_ops = bxt_fw_ops;
- sst->addr.lpe = mmio_base;
- sst->addr.shim = mmio_base;
- sst->addr.sram0_base = BXT_ADSP_SRAM0_BASE;
- sst->addr.sram1_base = BXT_ADSP_SRAM1_BASE;
- sst->addr.w0_stat_sz = SKL_ADSP_W0_STAT_SZ;
- sst->addr.w0_up_sz = SKL_ADSP_W0_UP_SZ;
-
- sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ),
- SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
-
- ret = skl_ipc_init(dev, skl);
- if (ret) {
- skl_dsp_free(sst);
- return ret;
- }
-
- /* set the D0i3 check */
- skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0;
-
- skl->boot_complete = false;
- init_waitqueue_head(&skl->boot_wait);
- INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3);
- skl->d0i3.state = SKL_DSP_D0I3_NONE;
-
- return skl_dsp_acquire_irq(sst);
-}
-EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
-
-int bxt_sst_init_fw(struct device *dev, struct skl_dev *skl)
-{
- int ret;
- struct sst_dsp *sst = skl->dsp;
-
- ret = sst->fw_ops.load_fw(sst);
- if (ret < 0) {
- dev_err(dev, "Load base fw failed: %x\n", ret);
- return ret;
- }
-
- skl_dsp_init_core_state(sst);
-
- if (skl->lib_count > 1) {
- ret = sst->fw_ops.load_library(sst, skl->lib_info,
- skl->lib_count);
- if (ret < 0) {
- dev_err(dev, "Load Library failed : %x\n", ret);
- return ret;
- }
- }
- skl->is_first_boot = false;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
-
-void bxt_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl)
-{
-
- skl_release_library(skl->lib_info, skl->lib_count);
- if (skl->dsp->fw)
- release_firmware(skl->dsp->fw);
- skl_freeup_uuid_list(skl);
- skl_ipc_free(&skl->ipc);
- skl->dsp->ops->free(skl->dsp);
-}
-EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Intel Broxton IPC driver");
diff --git a/sound/soc/intel/skylake/cnl-sst-dsp.c b/sound/soc/intel/skylake/cnl-sst-dsp.c
deleted file mode 100644
index 3ef1b194add1..000000000000
--- a/sound/soc/intel/skylake/cnl-sst-dsp.c
+++ /dev/null
@@ -1,266 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * cnl-sst-dsp.c - CNL SST library generic function
- *
- * Copyright (C) 2016-17, Intel Corporation.
- * Author: Guneshwor Singh <guneshwor.o.singh@intel.com>
- *
- * Modified from:
- * SKL SST library generic function
- * Copyright (C) 2014-15, Intel Corporation.
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-#include <linux/device.h>
-#include "../common/sst-dsp.h"
-#include "../common/sst-ipc.h"
-#include "../common/sst-dsp-priv.h"
-#include "cnl-sst-dsp.h"
-
-/* various timeout values */
-#define CNL_DSP_PU_TO 50
-#define CNL_DSP_PD_TO 50
-#define CNL_DSP_RESET_TO 50
-
-static int
-cnl_dsp_core_set_reset_state(struct sst_dsp *ctx, unsigned int core_mask)
-{
- /* update bits */
- sst_dsp_shim_update_bits_unlocked(ctx,
- CNL_ADSP_REG_ADSPCS, CNL_ADSPCS_CRST(core_mask),
- CNL_ADSPCS_CRST(core_mask));
-
- /* poll with timeout to check if operation successful */
- return sst_dsp_register_poll(ctx,
- CNL_ADSP_REG_ADSPCS,
- CNL_ADSPCS_CRST(core_mask),
- CNL_ADSPCS_CRST(core_mask),
- CNL_DSP_RESET_TO,
- "Set reset");
-}
-
-static int
-cnl_dsp_core_unset_reset_state(struct sst_dsp *ctx, unsigned int core_mask)
-{
- /* update bits */
- sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS,
- CNL_ADSPCS_CRST(core_mask), 0);
-
- /* poll with timeout to check if operation successful */
- return sst_dsp_register_poll(ctx,
- CNL_ADSP_REG_ADSPCS,
- CNL_ADSPCS_CRST(core_mask),
- 0,
- CNL_DSP_RESET_TO,
- "Unset reset");
-}
-
-static bool is_cnl_dsp_core_enable(struct sst_dsp *ctx, unsigned int core_mask)
-{
- int val;
- bool is_enable;
-
- val = sst_dsp_shim_read_unlocked(ctx, CNL_ADSP_REG_ADSPCS);
-
- is_enable = (val & CNL_ADSPCS_CPA(core_mask)) &&
- (val & CNL_ADSPCS_SPA(core_mask)) &&
- !(val & CNL_ADSPCS_CRST(core_mask)) &&
- !(val & CNL_ADSPCS_CSTALL(core_mask));
-
- dev_dbg(ctx->dev, "DSP core(s) enabled? %d: core_mask %#x\n",
- is_enable, core_mask);
-
- return is_enable;
-}
-
-static int cnl_dsp_reset_core(struct sst_dsp *ctx, unsigned int core_mask)
-{
- /* stall core */
- sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS,
- CNL_ADSPCS_CSTALL(core_mask),
- CNL_ADSPCS_CSTALL(core_mask));
-
- /* set reset state */
- return cnl_dsp_core_set_reset_state(ctx, core_mask);
-}
-
-static int cnl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask)
-{
- int ret;
-
- /* unset reset state */
- ret = cnl_dsp_core_unset_reset_state(ctx, core_mask);
- if (ret < 0)
- return ret;
-
- /* run core */
- sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS,
- CNL_ADSPCS_CSTALL(core_mask), 0);
-
- if (!is_cnl_dsp_core_enable(ctx, core_mask)) {
- cnl_dsp_reset_core(ctx, core_mask);
- dev_err(ctx->dev, "DSP core mask %#x enable failed\n",
- core_mask);
- ret = -EIO;
- }
-
- return ret;
-}
-
-static int cnl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask)
-{
- /* update bits */
- sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS,
- CNL_ADSPCS_SPA(core_mask),
- CNL_ADSPCS_SPA(core_mask));
-
- /* poll with timeout to check if operation successful */
- return sst_dsp_register_poll(ctx, CNL_ADSP_REG_ADSPCS,
- CNL_ADSPCS_CPA(core_mask),
- CNL_ADSPCS_CPA(core_mask),
- CNL_DSP_PU_TO,
- "Power up");
-}
-
-static int cnl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask)
-{
- /* update bits */
- sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS,
- CNL_ADSPCS_SPA(core_mask), 0);
-
- /* poll with timeout to check if operation successful */
- return sst_dsp_register_poll(ctx,
- CNL_ADSP_REG_ADSPCS,
- CNL_ADSPCS_CPA(core_mask),
- 0,
- CNL_DSP_PD_TO,
- "Power down");
-}
-
-int cnl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask)
-{
- int ret;
-
- /* power up */
- ret = cnl_dsp_core_power_up(ctx, core_mask);
- if (ret < 0) {
- dev_dbg(ctx->dev, "DSP core mask %#x power up failed",
- core_mask);
- return ret;
- }
-
- return cnl_dsp_start_core(ctx, core_mask);
-}
-
-int cnl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask)
-{
- int ret;
-
- ret = cnl_dsp_reset_core(ctx, core_mask);
- if (ret < 0) {
- dev_err(ctx->dev, "DSP core mask %#x reset failed\n",
- core_mask);
- return ret;
- }
-
- /* power down core*/
- ret = cnl_dsp_core_power_down(ctx, core_mask);
- if (ret < 0) {
- dev_err(ctx->dev, "DSP core mask %#x power down failed\n",
- core_mask);
- return ret;
- }
-
- if (is_cnl_dsp_core_enable(ctx, core_mask)) {
- dev_err(ctx->dev, "DSP core mask %#x disable failed\n",
- core_mask);
- ret = -EIO;
- }
-
- return ret;
-}
-
-irqreturn_t cnl_dsp_sst_interrupt(int irq, void *dev_id)
-{
- struct sst_dsp *ctx = dev_id;
- u32 val;
- irqreturn_t ret = IRQ_NONE;
-
- spin_lock(&ctx->spinlock);
-
- val = sst_dsp_shim_read_unlocked(ctx, CNL_ADSP_REG_ADSPIS);
- ctx->intr_status = val;
-
- if (val == 0xffffffff) {
- spin_unlock(&ctx->spinlock);
- return IRQ_NONE;
- }
-
- if (val & CNL_ADSPIS_IPC) {
- cnl_ipc_int_disable(ctx);
- ret = IRQ_WAKE_THREAD;
- }
-
- spin_unlock(&ctx->spinlock);
-
- return ret;
-}
-
-void cnl_dsp_free(struct sst_dsp *dsp)
-{
- cnl_ipc_int_disable(dsp);
-
- free_irq(dsp->irq, dsp);
- cnl_ipc_op_int_disable(dsp);
- cnl_dsp_disable_core(dsp, SKL_DSP_CORE0_MASK);
-}
-EXPORT_SYMBOL_GPL(cnl_dsp_free);
-
-void cnl_ipc_int_enable(struct sst_dsp *ctx)
-{
- sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_ADSPIC,
- CNL_ADSPIC_IPC, CNL_ADSPIC_IPC);
-}
-
-void cnl_ipc_int_disable(struct sst_dsp *ctx)
-{
- sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPIC,
- CNL_ADSPIC_IPC, 0);
-}
-
-void cnl_ipc_op_int_enable(struct sst_dsp *ctx)
-{
- /* enable IPC DONE interrupt */
- sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL,
- CNL_ADSP_REG_HIPCCTL_DONE,
- CNL_ADSP_REG_HIPCCTL_DONE);
-
- /* enable IPC BUSY interrupt */
- sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL,
- CNL_ADSP_REG_HIPCCTL_BUSY,
- CNL_ADSP_REG_HIPCCTL_BUSY);
-}
-
-void cnl_ipc_op_int_disable(struct sst_dsp *ctx)
-{
- /* disable IPC DONE interrupt */
- sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL,
- CNL_ADSP_REG_HIPCCTL_DONE, 0);
-
- /* disable IPC BUSY interrupt */
- sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL,
- CNL_ADSP_REG_HIPCCTL_BUSY, 0);
-}
-
-bool cnl_ipc_int_status(struct sst_dsp *ctx)
-{
- return sst_dsp_shim_read_unlocked(ctx, CNL_ADSP_REG_ADSPIS) &
- CNL_ADSPIS_IPC;
-}
-
-void cnl_ipc_free(struct sst_generic_ipc *ipc)
-{
- cnl_ipc_op_int_disable(ipc->dsp);
- sst_ipc_fini(ipc);
-}
diff --git a/sound/soc/intel/skylake/cnl-sst-dsp.h b/sound/soc/intel/skylake/cnl-sst-dsp.h
deleted file mode 100644
index d3cf4bd1a070..000000000000
--- a/sound/soc/intel/skylake/cnl-sst-dsp.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Cannonlake SST DSP Support
- *
- * Copyright (C) 2016-17, Intel Corporation.
- */
-
-#ifndef __CNL_SST_DSP_H__
-#define __CNL_SST_DSP_H__
-
-struct sst_dsp;
-struct sst_dsp_device;
-struct sst_generic_ipc;
-
-/* Intel HD Audio General DSP Registers */
-#define CNL_ADSP_GEN_BASE 0x0
-#define CNL_ADSP_REG_ADSPCS (CNL_ADSP_GEN_BASE + 0x04)
-#define CNL_ADSP_REG_ADSPIC (CNL_ADSP_GEN_BASE + 0x08)
-#define CNL_ADSP_REG_ADSPIS (CNL_ADSP_GEN_BASE + 0x0c)
-
-/* Intel HD Audio Inter-Processor Communication Registers */
-#define CNL_ADSP_IPC_BASE 0xc0
-#define CNL_ADSP_REG_HIPCTDR (CNL_ADSP_IPC_BASE + 0x00)
-#define CNL_ADSP_REG_HIPCTDA (CNL_ADSP_IPC_BASE + 0x04)
-#define CNL_ADSP_REG_HIPCTDD (CNL_ADSP_IPC_BASE + 0x08)
-#define CNL_ADSP_REG_HIPCIDR (CNL_ADSP_IPC_BASE + 0x10)
-#define CNL_ADSP_REG_HIPCIDA (CNL_ADSP_IPC_BASE + 0x14)
-#define CNL_ADSP_REG_HIPCIDD (CNL_ADSP_IPC_BASE + 0x18)
-#define CNL_ADSP_REG_HIPCCTL (CNL_ADSP_IPC_BASE + 0x28)
-
-/* HIPCTDR */
-#define CNL_ADSP_REG_HIPCTDR_BUSY BIT(31)
-
-/* HIPCTDA */
-#define CNL_ADSP_REG_HIPCTDA_DONE BIT(31)
-
-/* HIPCIDR */
-#define CNL_ADSP_REG_HIPCIDR_BUSY BIT(31)
-
-/* HIPCIDA */
-#define CNL_ADSP_REG_HIPCIDA_DONE BIT(31)
-
-/* CNL HIPCCTL */
-#define CNL_ADSP_REG_HIPCCTL_DONE BIT(1)
-#define CNL_ADSP_REG_HIPCCTL_BUSY BIT(0)
-
-/* CNL HIPCT */
-#define CNL_ADSP_REG_HIPCT_BUSY BIT(31)
-
-/* Intel HD Audio SRAM Window 1 */
-#define CNL_ADSP_SRAM1_BASE 0xa0000
-
-#define CNL_ADSP_MMIO_LEN 0x10000
-
-#define CNL_ADSP_W0_STAT_SZ 0x1000
-
-#define CNL_ADSP_W0_UP_SZ 0x1000
-
-#define CNL_ADSP_W1_SZ 0x1000
-
-#define CNL_FW_STS_MASK 0xf
-
-#define CNL_ADSPIC_IPC 0x1
-#define CNL_ADSPIS_IPC 0x1
-
-#define CNL_DSP_CORES 4
-#define CNL_DSP_CORES_MASK ((1 << CNL_DSP_CORES) - 1)
-
-/* core reset - asserted high */
-#define CNL_ADSPCS_CRST_SHIFT 0
-#define CNL_ADSPCS_CRST(x) (x << CNL_ADSPCS_CRST_SHIFT)
-
-/* core run/stall - when set to 1 core is stalled */
-#define CNL_ADSPCS_CSTALL_SHIFT 8
-#define CNL_ADSPCS_CSTALL(x) (x << CNL_ADSPCS_CSTALL_SHIFT)
-
-/* set power active - when set to 1 turn core on */
-#define CNL_ADSPCS_SPA_SHIFT 16
-#define CNL_ADSPCS_SPA(x) (x << CNL_ADSPCS_SPA_SHIFT)
-
-/* current power active - power status of cores, set by hardware */
-#define CNL_ADSPCS_CPA_SHIFT 24
-#define CNL_ADSPCS_CPA(x) (x << CNL_ADSPCS_CPA_SHIFT)
-
-int cnl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask);
-int cnl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask);
-irqreturn_t cnl_dsp_sst_interrupt(int irq, void *dev_id);
-void cnl_dsp_free(struct sst_dsp *dsp);
-
-void cnl_ipc_int_enable(struct sst_dsp *ctx);
-void cnl_ipc_int_disable(struct sst_dsp *ctx);
-void cnl_ipc_op_int_enable(struct sst_dsp *ctx);
-void cnl_ipc_op_int_disable(struct sst_dsp *ctx);
-bool cnl_ipc_int_status(struct sst_dsp *ctx);
-void cnl_ipc_free(struct sst_generic_ipc *ipc);
-
-int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
- const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
- struct skl_dev **dsp);
-int cnl_sst_init_fw(struct device *dev, struct skl_dev *skl);
-void cnl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl);
-
-#endif /*__CNL_SST_DSP_H__*/
diff --git a/sound/soc/intel/skylake/cnl-sst.c b/sound/soc/intel/skylake/cnl-sst.c
deleted file mode 100644
index 1275c149acc0..000000000000
--- a/sound/soc/intel/skylake/cnl-sst.c
+++ /dev/null
@@ -1,508 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * cnl-sst.c - DSP library functions for CNL platform
- *
- * Copyright (C) 2016-17, Intel Corporation.
- *
- * Author: Guneshwor Singh <guneshwor.o.singh@intel.com>
- *
- * Modified from:
- * HDA DSP library functions for SKL platform
- * Copyright (C) 2014-15, Intel Corporation.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/device.h>
-
-#include "../common/sst-dsp.h"
-#include "../common/sst-dsp-priv.h"
-#include "../common/sst-ipc.h"
-#include "cnl-sst-dsp.h"
-#include "skl.h"
-
-#define CNL_FW_ROM_INIT 0x1
-#define CNL_FW_INIT 0x5
-#define CNL_IPC_PURGE 0x01004000
-#define CNL_INIT_TIMEOUT 300
-#define CNL_BASEFW_TIMEOUT 3000
-
-#define CNL_ADSP_SRAM0_BASE 0x80000
-
-/* Firmware status window */
-#define CNL_ADSP_FW_STATUS CNL_ADSP_SRAM0_BASE
-#define CNL_ADSP_ERROR_CODE (CNL_ADSP_FW_STATUS + 0x4)
-
-#define CNL_INSTANCE_ID 0
-#define CNL_BASE_FW_MODULE_ID 0
-#define CNL_ADSP_FW_HDR_OFFSET 0x2000
-#define CNL_ROM_CTRL_DMA_ID 0x9
-
-static int cnl_prepare_fw(struct sst_dsp *ctx, const void *fwdata, u32 fwsize)
-{
-
- int ret, stream_tag;
-
- stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, fwsize, &ctx->dmab);
- if (stream_tag <= 0) {
- dev_err(ctx->dev, "dma prepare failed: 0%#x\n", stream_tag);
- return stream_tag;
- }
-
- ctx->dsp_ops.stream_tag = stream_tag;
- memcpy(ctx->dmab.area, fwdata, fwsize);
-
- ret = skl_dsp_core_power_up(ctx, SKL_DSP_CORE0_MASK);
- if (ret < 0) {
- dev_err(ctx->dev, "dsp core0 power up failed\n");
- ret = -EIO;
- goto base_fw_load_failed;
- }
-
- /* purge FW request */
- sst_dsp_shim_write(ctx, CNL_ADSP_REG_HIPCIDR,
- CNL_ADSP_REG_HIPCIDR_BUSY | (CNL_IPC_PURGE |
- ((stream_tag - 1) << CNL_ROM_CTRL_DMA_ID)));
-
- ret = skl_dsp_start_core(ctx, SKL_DSP_CORE0_MASK);
- if (ret < 0) {
- dev_err(ctx->dev, "Start dsp core failed ret: %d\n", ret);
- ret = -EIO;
- goto base_fw_load_failed;
- }
-
- ret = sst_dsp_register_poll(ctx, CNL_ADSP_REG_HIPCIDA,
- CNL_ADSP_REG_HIPCIDA_DONE,
- CNL_ADSP_REG_HIPCIDA_DONE,
- BXT_INIT_TIMEOUT, "HIPCIDA Done");
- if (ret < 0) {
- dev_err(ctx->dev, "timeout for purge request: %d\n", ret);
- goto base_fw_load_failed;
- }
-
- /* enable interrupt */
- cnl_ipc_int_enable(ctx);
- cnl_ipc_op_int_enable(ctx);
-
- ret = sst_dsp_register_poll(ctx, CNL_ADSP_FW_STATUS, CNL_FW_STS_MASK,
- CNL_FW_ROM_INIT, CNL_INIT_TIMEOUT,
- "rom load");
- if (ret < 0) {
- dev_err(ctx->dev, "rom init timeout, ret: %d\n", ret);
- goto base_fw_load_failed;
- }
-
- return 0;
-
-base_fw_load_failed:
- ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, stream_tag);
- cnl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
-
- return ret;
-}
-
-static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
-{
- int ret;
-
- ctx->dsp_ops.trigger(ctx->dev, true, ctx->dsp_ops.stream_tag);
- ret = sst_dsp_register_poll(ctx, CNL_ADSP_FW_STATUS, CNL_FW_STS_MASK,
- CNL_FW_INIT, CNL_BASEFW_TIMEOUT,
- "firmware boot");
-
- ctx->dsp_ops.trigger(ctx->dev, false, ctx->dsp_ops.stream_tag);
- ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, ctx->dsp_ops.stream_tag);
-
- return ret;
-}
-
-static int cnl_load_base_firmware(struct sst_dsp *ctx)
-{
- struct firmware stripped_fw;
- struct skl_dev *cnl = ctx->thread_context;
- int ret, i;
-
- if (!ctx->fw) {
- ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
- if (ret < 0) {
- dev_err(ctx->dev, "request firmware failed: %d\n", ret);
- goto cnl_load_base_firmware_failed;
- }
- }
-
- /* parse uuids if first boot */
- if (cnl->is_first_boot) {
- ret = snd_skl_parse_uuids(ctx, ctx->fw,
- CNL_ADSP_FW_HDR_OFFSET, 0);
- if (ret < 0)
- goto cnl_load_base_firmware_failed;
- }
-
- stripped_fw.data = ctx->fw->data;
- stripped_fw.size = ctx->fw->size;
- skl_dsp_strip_extended_manifest(&stripped_fw);
-
- for (i = 0; i < BXT_FW_ROM_INIT_RETRY; i++) {
- ret = cnl_prepare_fw(ctx, stripped_fw.data, stripped_fw.size);
- if (!ret)
- break;
- dev_dbg(ctx->dev, "prepare firmware failed: %d\n", ret);
- }
-
- if (ret < 0)
- goto cnl_load_base_firmware_failed;
-
- ret = sst_transfer_fw_host_dma(ctx);
- if (ret < 0) {
- dev_err(ctx->dev, "transfer firmware failed: %d\n", ret);
- cnl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
- goto cnl_load_base_firmware_failed;
- }
-
- ret = wait_event_timeout(cnl->boot_wait, cnl->boot_complete,
- msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
- if (ret == 0) {
- dev_err(ctx->dev, "FW ready timed-out\n");
- cnl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
- ret = -EIO;
- goto cnl_load_base_firmware_failed;
- }
-
- cnl->fw_loaded = true;
-
- return 0;
-
-cnl_load_base_firmware_failed:
- dev_err(ctx->dev, "firmware load failed: %d\n", ret);
- release_firmware(ctx->fw);
- ctx->fw = NULL;
-
- return ret;
-}
-
-static int cnl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
-{
- struct skl_dev *cnl = ctx->thread_context;
- unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
- struct skl_ipc_dxstate_info dx;
- int ret;
-
- if (!cnl->fw_loaded) {
- cnl->boot_complete = false;
- ret = cnl_load_base_firmware(ctx);
- if (ret < 0) {
- dev_err(ctx->dev, "fw reload failed: %d\n", ret);
- return ret;
- }
-
- cnl->cores.state[core_id] = SKL_DSP_RUNNING;
- return ret;
- }
-
- ret = cnl_dsp_enable_core(ctx, core_mask);
- if (ret < 0) {
- dev_err(ctx->dev, "enable dsp core %d failed: %d\n",
- core_id, ret);
- goto err;
- }
-
- if (core_id == SKL_DSP_CORE0_ID) {
- /* enable interrupt */
- cnl_ipc_int_enable(ctx);
- cnl_ipc_op_int_enable(ctx);
- cnl->boot_complete = false;
-
- ret = wait_event_timeout(cnl->boot_wait, cnl->boot_complete,
- msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
- if (ret == 0) {
- dev_err(ctx->dev,
- "dsp boot timeout, status=%#x error=%#x\n",
- sst_dsp_shim_read(ctx, CNL_ADSP_FW_STATUS),
- sst_dsp_shim_read(ctx, CNL_ADSP_ERROR_CODE));
- ret = -ETIMEDOUT;
- goto err;
- }
- } else {
- dx.core_mask = core_mask;
- dx.dx_mask = core_mask;
-
- ret = skl_ipc_set_dx(&cnl->ipc, CNL_INSTANCE_ID,
- CNL_BASE_FW_MODULE_ID, &dx);
- if (ret < 0) {
- dev_err(ctx->dev, "set_dx failed, core: %d ret: %d\n",
- core_id, ret);
- goto err;
- }
- }
- cnl->cores.state[core_id] = SKL_DSP_RUNNING;
-
- return 0;
-err:
- cnl_dsp_disable_core(ctx, core_mask);
-
- return ret;
-}
-
-static int cnl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
-{
- struct skl_dev *cnl = ctx->thread_context;
- unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
- struct skl_ipc_dxstate_info dx;
- int ret;
-
- dx.core_mask = core_mask;
- dx.dx_mask = SKL_IPC_D3_MASK;
-
- ret = skl_ipc_set_dx(&cnl->ipc, CNL_INSTANCE_ID,
- CNL_BASE_FW_MODULE_ID, &dx);
- if (ret < 0) {
- dev_err(ctx->dev,
- "dsp core %d to d3 failed; continue reset\n",
- core_id);
- cnl->fw_loaded = false;
- }
-
- /* disable interrupts if core 0 */
- if (core_id == SKL_DSP_CORE0_ID) {
- skl_ipc_op_int_disable(ctx);
- skl_ipc_int_disable(ctx);
- }
-
- ret = cnl_dsp_disable_core(ctx, core_mask);
- if (ret < 0) {
- dev_err(ctx->dev, "disable dsp core %d failed: %d\n",
- core_id, ret);
- return ret;
- }
-
- cnl->cores.state[core_id] = SKL_DSP_RESET;
-
- return ret;
-}
-
-static unsigned int cnl_get_errno(struct sst_dsp *ctx)
-{
- return sst_dsp_shim_read(ctx, CNL_ADSP_ERROR_CODE);
-}
-
-static const struct skl_dsp_fw_ops cnl_fw_ops = {
- .set_state_D0 = cnl_set_dsp_D0,
- .set_state_D3 = cnl_set_dsp_D3,
- .load_fw = cnl_load_base_firmware,
- .get_fw_errcode = cnl_get_errno,
-};
-
-static struct sst_ops cnl_ops = {
- .irq_handler = cnl_dsp_sst_interrupt,
- .write = sst_shim32_write,
- .read = sst_shim32_read,
- .free = cnl_dsp_free,
-};
-
-#define CNL_IPC_GLB_NOTIFY_RSP_SHIFT 29
-#define CNL_IPC_GLB_NOTIFY_RSP_MASK 0x1
-#define CNL_IPC_GLB_NOTIFY_RSP_TYPE(x) (((x) >> CNL_IPC_GLB_NOTIFY_RSP_SHIFT) \
- & CNL_IPC_GLB_NOTIFY_RSP_MASK)
-
-static irqreturn_t cnl_dsp_irq_thread_handler(int irq, void *context)
-{
- struct sst_dsp *dsp = context;
- struct skl_dev *cnl = dsp->thread_context;
- struct sst_generic_ipc *ipc = &cnl->ipc;
- struct skl_ipc_header header = {0};
- u32 hipcida, hipctdr, hipctdd;
- int ipc_irq = 0;
-
- /* here we handle ipc interrupts only */
- if (!(dsp->intr_status & CNL_ADSPIS_IPC))
- return IRQ_NONE;
-
- hipcida = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCIDA);
- hipctdr = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCTDR);
- hipctdd = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCTDD);
-
- /* reply message from dsp */
- if (hipcida & CNL_ADSP_REG_HIPCIDA_DONE) {
- sst_dsp_shim_update_bits(dsp, CNL_ADSP_REG_HIPCCTL,
- CNL_ADSP_REG_HIPCCTL_DONE, 0);
-
- /* clear done bit - tell dsp operation is complete */
- sst_dsp_shim_update_bits_forced(dsp, CNL_ADSP_REG_HIPCIDA,
- CNL_ADSP_REG_HIPCIDA_DONE, CNL_ADSP_REG_HIPCIDA_DONE);
-
- ipc_irq = 1;
-
- /* unmask done interrupt */
- sst_dsp_shim_update_bits(dsp, CNL_ADSP_REG_HIPCCTL,
- CNL_ADSP_REG_HIPCCTL_DONE, CNL_ADSP_REG_HIPCCTL_DONE);
- }
-
- /* new message from dsp */
- if (hipctdr & CNL_ADSP_REG_HIPCTDR_BUSY) {
- header.primary = hipctdr;
- header.extension = hipctdd;
- dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x",
- header.primary);
- dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x",
- header.extension);
-
- if (CNL_IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) {
- /* Handle Immediate reply from DSP Core */
- skl_ipc_process_reply(ipc, header);
- } else {
- dev_dbg(dsp->dev, "IPC irq: Notification from firmware\n");
- skl_ipc_process_notification(ipc, header);
- }
- /* clear busy interrupt */
- sst_dsp_shim_update_bits_forced(dsp, CNL_ADSP_REG_HIPCTDR,
- CNL_ADSP_REG_HIPCTDR_BUSY, CNL_ADSP_REG_HIPCTDR_BUSY);
-
- /* set done bit to ack dsp */
- sst_dsp_shim_update_bits_forced(dsp, CNL_ADSP_REG_HIPCTDA,
- CNL_ADSP_REG_HIPCTDA_DONE, CNL_ADSP_REG_HIPCTDA_DONE);
- ipc_irq = 1;
- }
-
- if (ipc_irq == 0)
- return IRQ_NONE;
-
- cnl_ipc_int_enable(dsp);
-
- /* continue to send any remaining messages */
- schedule_work(&ipc->kwork);
-
- return IRQ_HANDLED;
-}
-
-static struct sst_dsp_device cnl_dev = {
- .thread = cnl_dsp_irq_thread_handler,
- .ops = &cnl_ops,
-};
-
-static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
-{
- struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header);
-
- if (msg->tx.size)
- sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
- sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD,
- header->extension);
- sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR,
- header->primary | CNL_ADSP_REG_HIPCIDR_BUSY);
-}
-
-static bool cnl_ipc_is_dsp_busy(struct sst_dsp *dsp)
-{
- u32 hipcidr;
-
- hipcidr = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCIDR);
-
- return (hipcidr & CNL_ADSP_REG_HIPCIDR_BUSY);
-}
-
-static int cnl_ipc_init(struct device *dev, struct skl_dev *cnl)
-{
- struct sst_generic_ipc *ipc;
- int err;
-
- ipc = &cnl->ipc;
- ipc->dsp = cnl->dsp;
- ipc->dev = dev;
-
- ipc->tx_data_max_size = CNL_ADSP_W1_SZ;
- ipc->rx_data_max_size = CNL_ADSP_W0_UP_SZ;
-
- err = sst_ipc_init(ipc);
- if (err)
- return err;
-
- /*
- * overriding tx_msg and is_dsp_busy since
- * ipc registers are different for cnl
- */
- ipc->ops.tx_msg = cnl_ipc_tx_msg;
- ipc->ops.tx_data_copy = skl_ipc_tx_data_copy;
- ipc->ops.is_dsp_busy = cnl_ipc_is_dsp_busy;
-
- return 0;
-}
-
-int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
- const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
- struct skl_dev **dsp)
-{
- struct skl_dev *cnl;
- struct sst_dsp *sst;
- int ret;
-
- ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &cnl_dev);
- if (ret < 0) {
- dev_err(dev, "%s: no device\n", __func__);
- return ret;
- }
-
- cnl = *dsp;
- sst = cnl->dsp;
- sst->fw_ops = cnl_fw_ops;
- sst->addr.lpe = mmio_base;
- sst->addr.shim = mmio_base;
- sst->addr.sram0_base = CNL_ADSP_SRAM0_BASE;
- sst->addr.sram1_base = CNL_ADSP_SRAM1_BASE;
- sst->addr.w0_stat_sz = CNL_ADSP_W0_STAT_SZ;
- sst->addr.w0_up_sz = CNL_ADSP_W0_UP_SZ;
-
- sst_dsp_mailbox_init(sst, (CNL_ADSP_SRAM0_BASE + CNL_ADSP_W0_STAT_SZ),
- CNL_ADSP_W0_UP_SZ, CNL_ADSP_SRAM1_BASE,
- CNL_ADSP_W1_SZ);
-
- ret = cnl_ipc_init(dev, cnl);
- if (ret) {
- skl_dsp_free(sst);
- return ret;
- }
-
- cnl->boot_complete = false;
- init_waitqueue_head(&cnl->boot_wait);
-
- return skl_dsp_acquire_irq(sst);
-}
-EXPORT_SYMBOL_GPL(cnl_sst_dsp_init);
-
-int cnl_sst_init_fw(struct device *dev, struct skl_dev *skl)
-{
- int ret;
- struct sst_dsp *sst = skl->dsp;
-
- ret = skl->dsp->fw_ops.load_fw(sst);
- if (ret < 0) {
- dev_err(dev, "load base fw failed: %d", ret);
- return ret;
- }
-
- skl_dsp_init_core_state(sst);
-
- skl->is_first_boot = false;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cnl_sst_init_fw);
-
-void cnl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl)
-{
- if (skl->dsp->fw)
- release_firmware(skl->dsp->fw);
-
- skl_freeup_uuid_list(skl);
- cnl_ipc_free(&skl->ipc);
-
- skl->dsp->ops->free(skl->dsp);
-}
-EXPORT_SYMBOL_GPL(cnl_sst_dsp_cleanup);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Intel Cannonlake IPC driver");
diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c
deleted file mode 100644
index a15aa2ffa681..000000000000
--- a/sound/soc/intel/skylake/skl-debug.c
+++ /dev/null
@@ -1,248 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * skl-debug.c - Debugfs for skl driver
- *
- * Copyright (C) 2016-17 Intel Corp
- */
-
-#include <linux/pci.h>
-#include <linux/debugfs.h>
-#include <uapi/sound/skl-tplg-interface.h>
-#include "skl.h"
-#include "skl-sst-dsp.h"
-#include "skl-sst-ipc.h"
-#include "skl-topology.h"
-#include "../common/sst-dsp.h"
-#include "../common/sst-dsp-priv.h"
-
-#define MOD_BUF PAGE_SIZE
-#define FW_REG_BUF PAGE_SIZE
-#define FW_REG_SIZE 0x60
-
-struct skl_debug {
- struct skl_dev *skl;
- struct device *dev;
-
- struct dentry *fs;
- struct dentry *modules;
- u8 fw_read_buff[FW_REG_BUF];
-};
-
-static ssize_t skl_print_pins(struct skl_module_pin *m_pin, char *buf,
- int max_pin, ssize_t size, bool direction)
-{
- int i;
- ssize_t ret = 0;
-
- for (i = 0; i < max_pin; i++) {
- ret += scnprintf(buf + size, MOD_BUF - size,
- "%s %d\n\tModule %d\n\tInstance %d\n\t"
- "In-used %s\n\tType %s\n"
- "\tState %d\n\tIndex %d\n",
- direction ? "Input Pin:" : "Output Pin:",
- i, m_pin[i].id.module_id,
- m_pin[i].id.instance_id,
- m_pin[i].in_use ? "Used" : "Unused",
- m_pin[i].is_dynamic ? "Dynamic" : "Static",
- m_pin[i].pin_state, i);
- size += ret;
- }
- return ret;
-}
-
-static ssize_t skl_print_fmt(struct skl_module_fmt *fmt, char *buf,
- ssize_t size, bool direction)
-{
- return scnprintf(buf + size, MOD_BUF - size,
- "%s\n\tCh %d\n\tFreq %d\n\tBit depth %d\n\t"
- "Valid bit depth %d\n\tCh config %#x\n\tInterleaving %d\n\t"
- "Sample Type %d\n\tCh Map %#x\n",
- direction ? "Input Format:" : "Output Format:",
- fmt->channels, fmt->s_freq, fmt->bit_depth,
- fmt->valid_bit_depth, fmt->ch_cfg,
- fmt->interleaving_style, fmt->sample_type,
- fmt->ch_map);
-}
-
-static ssize_t module_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct skl_module_cfg *mconfig = file->private_data;
- struct skl_module *module = mconfig->module;
- struct skl_module_res *res = &module->resources[mconfig->res_idx];
- char *buf;
- ssize_t ret;
-
- buf = kzalloc(MOD_BUF, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- ret = scnprintf(buf, MOD_BUF, "Module:\n\tUUID %pUL\n\tModule id %d\n"
- "\tInstance id %d\n\tPvt_id %d\n", mconfig->guid,
- mconfig->id.module_id, mconfig->id.instance_id,
- mconfig->id.pvt_id);
-
- ret += scnprintf(buf + ret, MOD_BUF - ret,
- "Resources:\n\tCPC %#x\n\tIBS %#x\n\tOBS %#x\t\n",
- res->cpc, res->ibs, res->obs);
-
- ret += scnprintf(buf + ret, MOD_BUF - ret,
- "Module data:\n\tCore %d\n\tIn queue %d\n\t"
- "Out queue %d\n\tType %s\n",
- mconfig->core_id, mconfig->max_in_queue,
- mconfig->max_out_queue,
- mconfig->is_loadable ? "loadable" : "inbuilt");
-
- ret += skl_print_fmt(mconfig->in_fmt, buf, ret, true);
- ret += skl_print_fmt(mconfig->out_fmt, buf, ret, false);
-
- ret += scnprintf(buf + ret, MOD_BUF - ret,
- "Fixup:\n\tParams %#x\n\tConverter %#x\n",
- mconfig->params_fixup, mconfig->converter);
-
- ret += scnprintf(buf + ret, MOD_BUF - ret,
- "Module Gateway:\n\tType %#x\n\tVbus %#x\n\tHW conn %#x\n\tSlot %#x\n",
- mconfig->dev_type, mconfig->vbus_id,
- mconfig->hw_conn_type, mconfig->time_slot);
-
- ret += scnprintf(buf + ret, MOD_BUF - ret,
- "Pipeline:\n\tID %d\n\tPriority %d\n\tConn Type %d\n\t"
- "Pages %#x\n", mconfig->pipe->ppl_id,
- mconfig->pipe->pipe_priority, mconfig->pipe->conn_type,
- mconfig->pipe->memory_pages);
-
- ret += scnprintf(buf + ret, MOD_BUF - ret,
- "\tParams:\n\t\tHost DMA %d\n\t\tLink DMA %d\n",
- mconfig->pipe->p_params->host_dma_id,
- mconfig->pipe->p_params->link_dma_id);
-
- ret += scnprintf(buf + ret, MOD_BUF - ret,
- "\tPCM params:\n\t\tCh %d\n\t\tFreq %d\n\t\tFormat %d\n",
- mconfig->pipe->p_params->ch,
- mconfig->pipe->p_params->s_freq,
- mconfig->pipe->p_params->s_fmt);
-
- ret += scnprintf(buf + ret, MOD_BUF - ret,
- "\tLink %#x\n\tStream %#x\n",
- mconfig->pipe->p_params->linktype,
- mconfig->pipe->p_params->stream);
-
- ret += scnprintf(buf + ret, MOD_BUF - ret,
- "\tState %d\n\tPassthru %s\n",
- mconfig->pipe->state,
- mconfig->pipe->passthru ? "true" : "false");
-
- ret += skl_print_pins(mconfig->m_in_pin, buf,
- mconfig->max_in_queue, ret, true);
- ret += skl_print_pins(mconfig->m_out_pin, buf,
- mconfig->max_out_queue, ret, false);
-
- ret += scnprintf(buf + ret, MOD_BUF - ret,
- "Other:\n\tDomain %d\n\tHomogeneous Input %s\n\t"
- "Homogeneous Output %s\n\tIn Queue Mask %d\n\t"
- "Out Queue Mask %d\n\tDMA ID %d\n\tMem Pages %d\n\t"
- "Module Type %d\n\tModule State %d\n",
- mconfig->domain,
- mconfig->homogenous_inputs ? "true" : "false",
- mconfig->homogenous_outputs ? "true" : "false",
- mconfig->in_queue_mask, mconfig->out_queue_mask,
- mconfig->dma_id, mconfig->mem_pages, mconfig->m_state,
- mconfig->m_type);
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
-
- kfree(buf);
- return ret;
-}
-
-static const struct file_operations mcfg_fops = {
- .open = simple_open,
- .read = module_read,
- .llseek = default_llseek,
-};
-
-
-void skl_debug_init_module(struct skl_debug *d,
- struct snd_soc_dapm_widget *w,
- struct skl_module_cfg *mconfig)
-{
- debugfs_create_file(w->name, 0444, d->modules, mconfig,
- &mcfg_fops);
-}
-
-static ssize_t fw_softreg_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct skl_debug *d = file->private_data;
- struct sst_dsp *sst = d->skl->dsp;
- size_t w0_stat_sz = sst->addr.w0_stat_sz;
- void __iomem *in_base = sst->mailbox.in_base;
- void __iomem *fw_reg_addr;
- unsigned int offset;
- char *tmp;
- ssize_t ret = 0;
-
- tmp = kzalloc(FW_REG_BUF, GFP_KERNEL);
- if (!tmp)
- return -ENOMEM;
-
- fw_reg_addr = in_base - w0_stat_sz;
- memset(d->fw_read_buff, 0, FW_REG_BUF);
-
- if (w0_stat_sz > 0)
- __ioread32_copy(d->fw_read_buff, fw_reg_addr, w0_stat_sz >> 2);
-
- for (offset = 0; offset < FW_REG_SIZE; offset += 16) {
- ret += scnprintf(tmp + ret, FW_REG_BUF - ret, "%#.4x: ", offset);
- hex_dump_to_buffer(d->fw_read_buff + offset, 16, 16, 4,
- tmp + ret, FW_REG_BUF - ret, 0);
- ret += strlen(tmp + ret);
-
- /* print newline for each offset */
- if (FW_REG_BUF - ret > 0)
- tmp[ret++] = '\n';
- }
-
- ret = simple_read_from_buffer(user_buf, count, ppos, tmp, ret);
- kfree(tmp);
-
- return ret;
-}
-
-static const struct file_operations soft_regs_ctrl_fops = {
- .open = simple_open,
- .read = fw_softreg_read,
- .llseek = default_llseek,
-};
-
-struct skl_debug *skl_debugfs_init(struct skl_dev *skl)
-{
- struct skl_debug *d;
-
- d = devm_kzalloc(&skl->pci->dev, sizeof(*d), GFP_KERNEL);
- if (!d)
- return NULL;
-
- /* create the debugfs dir with platform component's debugfs as parent */
- d->fs = debugfs_create_dir("dsp", skl->component->debugfs_root);
-
- d->skl = skl;
- d->dev = &skl->pci->dev;
-
- /* now create the module dir */
- d->modules = debugfs_create_dir("modules", d->fs);
-
- debugfs_create_file("fw_soft_regs_rd", 0444, d->fs, d,
- &soft_regs_ctrl_fops);
-
- return d;
-}
-
-void skl_debugfs_exit(struct skl_dev *skl)
-{
- struct skl_debug *d = skl->debugfs;
-
- debugfs_remove_recursive(d->fs);
-
- d = NULL;
-}
diff --git a/sound/soc/intel/skylake/skl-i2s.h b/sound/soc/intel/skylake/skl-i2s.h
deleted file mode 100644
index dfce91e11be1..000000000000
--- a/sound/soc/intel/skylake/skl-i2s.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * skl-i2s.h - i2s blob mapping
- *
- * Copyright (C) 2017 Intel Corp
- * Author: Subhransu S. Prusty < subhransu.s.prusty@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#ifndef __SOUND_SOC_SKL_I2S_H
-#define __SOUND_SOC_SKL_I2S_H
-
-#define SKL_I2S_MAX_TIME_SLOTS 8
-#define SKL_MCLK_DIV_CLK_SRC_MASK GENMASK(17, 16)
-
-#define SKL_MNDSS_DIV_CLK_SRC_MASK GENMASK(21, 20)
-#define SKL_SHIFT(x) (ffs(x) - 1)
-#define SKL_MCLK_DIV_RATIO_MASK GENMASK(11, 0)
-
-#define is_legacy_blob(x) (x.signature != 0xEE)
-#define ext_to_legacy_blob(i2s_config_blob_ext) \
- ((struct skl_i2s_config_blob_legacy *) i2s_config_blob_ext)
-
-#define get_clk_src(mclk, mask) \
- ((mclk.mdivctrl & mask) >> SKL_SHIFT(mask))
-struct skl_i2s_config {
- u32 ssc0;
- u32 ssc1;
- u32 sscto;
- u32 sspsp;
- u32 sstsa;
- u32 ssrsa;
- u32 ssc2;
- u32 sspsp2;
- u32 ssc3;
- u32 ssioc;
-} __packed;
-
-struct skl_i2s_config_mclk {
- u32 mdivctrl;
- u32 mdivr;
-};
-
-struct skl_i2s_config_mclk_ext {
- u32 mdivctrl;
- u32 mdivr_count;
- u32 mdivr[];
-} __packed;
-
-struct skl_i2s_config_blob_signature {
- u32 minor_ver : 8;
- u32 major_ver : 8;
- u32 resvdz : 8;
- u32 signature : 8;
-} __packed;
-
-struct skl_i2s_config_blob_header {
- struct skl_i2s_config_blob_signature sig;
- u32 size;
-};
-
-/**
- * struct skl_i2s_config_blob_legacy - Structure defines I2S Gateway
- * configuration legacy blob
- *
- * @gtw_attr: Gateway attribute for the I2S Gateway
- * @tdm_ts_group: TDM slot mapping against channels in the Gateway.
- * @i2s_cfg: I2S HW registers
- * @mclk: MCLK clock source and divider values
- */
-struct skl_i2s_config_blob_legacy {
- u32 gtw_attr;
- u32 tdm_ts_group[SKL_I2S_MAX_TIME_SLOTS];
- struct skl_i2s_config i2s_cfg;
- struct skl_i2s_config_mclk mclk;
-};
-
-struct skl_i2s_config_blob_ext {
- u32 gtw_attr;
- struct skl_i2s_config_blob_header hdr;
- u32 tdm_ts_group[SKL_I2S_MAX_TIME_SLOTS];
- struct skl_i2s_config i2s_cfg;
- struct skl_i2s_config_mclk_ext mclk;
-} __packed;
-#endif /* __SOUND_SOC_SKL_I2S_H */
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
deleted file mode 100644
index fc2eb04da172..000000000000
--- a/sound/soc/intel/skylake/skl-messages.c
+++ /dev/null
@@ -1,1419 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * skl-message.c - HDA DSP interface for FW registration, Pipe and Module
- * configurations
- *
- * Copyright (C) 2015 Intel Corp
- * Author:Rafal Redzimski <rafal.f.redzimski@intel.com>
- * Jeeja KP <jeeja.kp@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <uapi/sound/skl-tplg-interface.h>
-#include "skl-sst-dsp.h"
-#include "cnl-sst-dsp.h"
-#include "skl-sst-ipc.h"
-#include "skl.h"
-#include "../common/sst-dsp.h"
-#include "../common/sst-dsp-priv.h"
-#include "skl-topology.h"
-
-static int skl_alloc_dma_buf(struct device *dev,
- struct snd_dma_buffer *dmab, size_t size)
-{
- return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, dmab);
-}
-
-static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab)
-{
- snd_dma_free_pages(dmab);
- return 0;
-}
-
-#define SKL_ASTATE_PARAM_ID 4
-
-void skl_dsp_set_astate_cfg(struct skl_dev *skl, u32 cnt, void *data)
-{
- struct skl_ipc_large_config_msg msg = {0};
-
- msg.large_param_id = SKL_ASTATE_PARAM_ID;
- msg.param_data_size = (cnt * sizeof(struct skl_astate_param) +
- sizeof(cnt));
-
- skl_ipc_set_large_config(&skl->ipc, &msg, data);
-}
-
-static int skl_dsp_setup_spib(struct device *dev, unsigned int size,
- int stream_tag, int enable)
-{
- struct hdac_bus *bus = dev_get_drvdata(dev);
- struct hdac_stream *stream = snd_hdac_get_stream(bus,
- SNDRV_PCM_STREAM_PLAYBACK, stream_tag);
-
- if (!stream)
- return -EINVAL;
-
- /* enable/disable SPIB for this hdac stream */
- snd_hdac_stream_spbcap_enable(bus, enable, stream->index);
-
- /* set the spib value */
- snd_hdac_stream_set_spib(bus, stream, size);
-
- return 0;
-}
-
-static int skl_dsp_prepare(struct device *dev, unsigned int format,
- unsigned int size, struct snd_dma_buffer *dmab)
-{
- struct hdac_bus *bus = dev_get_drvdata(dev);
- struct hdac_ext_stream *estream;
- struct hdac_stream *stream;
- struct snd_pcm_substream substream;
- int ret;
-
- if (!bus)
- return -ENODEV;
-
- memset(&substream, 0, sizeof(substream));
- substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
-
- estream = snd_hdac_ext_stream_assign(bus, &substream,
- HDAC_EXT_STREAM_TYPE_HOST);
- if (!estream)
- return -ENODEV;
-
- stream = hdac_stream(estream);
-
- /* assign decouple host dma channel */
- ret = snd_hdac_dsp_prepare(stream, format, size, dmab);
- if (ret < 0)
- return ret;
-
- skl_dsp_setup_spib(dev, size, stream->stream_tag, true);
-
- return stream->stream_tag;
-}
-
-static int skl_dsp_trigger(struct device *dev, bool start, int stream_tag)
-{
- struct hdac_bus *bus = dev_get_drvdata(dev);
- struct hdac_stream *stream;
-
- if (!bus)
- return -ENODEV;
-
- stream = snd_hdac_get_stream(bus,
- SNDRV_PCM_STREAM_PLAYBACK, stream_tag);
- if (!stream)
- return -EINVAL;
-
- snd_hdac_dsp_trigger(stream, start);
-
- return 0;
-}
-
-static int skl_dsp_cleanup(struct device *dev,
- struct snd_dma_buffer *dmab, int stream_tag)
-{
- struct hdac_bus *bus = dev_get_drvdata(dev);
- struct hdac_stream *stream;
- struct hdac_ext_stream *estream;
-
- if (!bus)
- return -ENODEV;
-
- stream = snd_hdac_get_stream(bus,
- SNDRV_PCM_STREAM_PLAYBACK, stream_tag);
- if (!stream)
- return -EINVAL;
-
- estream = stream_to_hdac_ext_stream(stream);
- skl_dsp_setup_spib(dev, 0, stream_tag, false);
- snd_hdac_ext_stream_release(estream, HDAC_EXT_STREAM_TYPE_HOST);
-
- snd_hdac_dsp_cleanup(stream, dmab);
-
- return 0;
-}
-
-static struct skl_dsp_loader_ops skl_get_loader_ops(void)
-{
- struct skl_dsp_loader_ops loader_ops;
-
- memset(&loader_ops, 0, sizeof(struct skl_dsp_loader_ops));
-
- loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
- loader_ops.free_dma_buf = skl_free_dma_buf;
-
- return loader_ops;
-};
-
-static struct skl_dsp_loader_ops bxt_get_loader_ops(void)
-{
- struct skl_dsp_loader_ops loader_ops;
-
- memset(&loader_ops, 0, sizeof(loader_ops));
-
- loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
- loader_ops.free_dma_buf = skl_free_dma_buf;
- loader_ops.prepare = skl_dsp_prepare;
- loader_ops.trigger = skl_dsp_trigger;
- loader_ops.cleanup = skl_dsp_cleanup;
-
- return loader_ops;
-};
-
-static const struct skl_dsp_ops dsp_ops[] = {
- {
- .id = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
- .num_cores = 2,
- .loader_ops = skl_get_loader_ops,
- .init = skl_sst_dsp_init,
- .init_fw = skl_sst_init_fw,
- .cleanup = skl_sst_dsp_cleanup
- },
- {
- .id = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
- .num_cores = 2,
- .loader_ops = skl_get_loader_ops,
- .init = skl_sst_dsp_init,
- .init_fw = skl_sst_init_fw,
- .cleanup = skl_sst_dsp_cleanup
- },
- {
- .id = PCI_DEVICE_ID_INTEL_HDA_APL,
- .num_cores = 2,
- .loader_ops = bxt_get_loader_ops,
- .init = bxt_sst_dsp_init,
- .init_fw = bxt_sst_init_fw,
- .cleanup = bxt_sst_dsp_cleanup
- },
- {
- .id = PCI_DEVICE_ID_INTEL_HDA_GML,
- .num_cores = 2,
- .loader_ops = bxt_get_loader_ops,
- .init = bxt_sst_dsp_init,
- .init_fw = bxt_sst_init_fw,
- .cleanup = bxt_sst_dsp_cleanup
- },
- {
- .id = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,
- .num_cores = 4,
- .loader_ops = bxt_get_loader_ops,
- .init = cnl_sst_dsp_init,
- .init_fw = cnl_sst_init_fw,
- .cleanup = cnl_sst_dsp_cleanup
- },
- {
- .id = PCI_DEVICE_ID_INTEL_HDA_CNL_H,
- .num_cores = 4,
- .loader_ops = bxt_get_loader_ops,
- .init = cnl_sst_dsp_init,
- .init_fw = cnl_sst_init_fw,
- .cleanup = cnl_sst_dsp_cleanup
- },
- {
- .id = PCI_DEVICE_ID_INTEL_HDA_CML_LP,
- .num_cores = 4,
- .loader_ops = bxt_get_loader_ops,
- .init = cnl_sst_dsp_init,
- .init_fw = cnl_sst_init_fw,
- .cleanup = cnl_sst_dsp_cleanup
- },
- {
- .id = PCI_DEVICE_ID_INTEL_HDA_CML_H,
- .num_cores = 4,
- .loader_ops = bxt_get_loader_ops,
- .init = cnl_sst_dsp_init,
- .init_fw = cnl_sst_init_fw,
- .cleanup = cnl_sst_dsp_cleanup
- },
-};
-
-const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) {
- if (dsp_ops[i].id == pci_id)
- return &dsp_ops[i];
- }
-
- return NULL;
-}
-
-int skl_init_dsp(struct skl_dev *skl)
-{
- void __iomem *mmio_base;
- struct hdac_bus *bus = skl_to_bus(skl);
- struct skl_dsp_loader_ops loader_ops;
- int irq = bus->irq;
- const struct skl_dsp_ops *ops;
- struct skl_dsp_cores *cores;
- int ret;
-
- /* enable ppcap interrupt */
- snd_hdac_ext_bus_ppcap_enable(bus, true);
- snd_hdac_ext_bus_ppcap_int_enable(bus, true);
-
- /* read the BAR of the ADSP MMIO */
- mmio_base = pci_ioremap_bar(skl->pci, 4);
- if (mmio_base == NULL) {
- dev_err(bus->dev, "ioremap error\n");
- return -ENXIO;
- }
-
- ops = skl_get_dsp_ops(skl->pci->device);
- if (!ops) {
- ret = -EIO;
- goto unmap_mmio;
- }
-
- loader_ops = ops->loader_ops();
- ret = ops->init(bus->dev, mmio_base, irq,
- skl->fw_name, loader_ops,
- &skl);
-
- if (ret < 0)
- goto unmap_mmio;
-
- skl->dsp_ops = ops;
- cores = &skl->cores;
- cores->count = ops->num_cores;
-
- cores->state = kcalloc(cores->count, sizeof(*cores->state), GFP_KERNEL);
- if (!cores->state) {
- ret = -ENOMEM;
- goto unmap_mmio;
- }
-
- cores->usage_count = kcalloc(cores->count, sizeof(*cores->usage_count),
- GFP_KERNEL);
- if (!cores->usage_count) {
- ret = -ENOMEM;
- goto free_core_state;
- }
-
- dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
-
- return 0;
-
-free_core_state:
- kfree(cores->state);
-
-unmap_mmio:
- iounmap(mmio_base);
-
- return ret;
-}
-
-int skl_free_dsp(struct skl_dev *skl)
-{
- struct hdac_bus *bus = skl_to_bus(skl);
-
- /* disable ppcap interrupt */
- snd_hdac_ext_bus_ppcap_int_enable(bus, false);
-
- skl->dsp_ops->cleanup(bus->dev, skl);
-
- kfree(skl->cores.state);
- kfree(skl->cores.usage_count);
-
- if (skl->dsp->addr.lpe)
- iounmap(skl->dsp->addr.lpe);
-
- return 0;
-}
-
-/*
- * In the case of "suspend_active" i.e, the Audio IP being active
- * during system suspend, immediately excecute any pending D0i3 work
- * before suspending. This is needed for the IP to work in low power
- * mode during system suspend. In the case of normal suspend, cancel
- * any pending D0i3 work.
- */
-int skl_suspend_late_dsp(struct skl_dev *skl)
-{
- struct delayed_work *dwork;
-
- if (!skl)
- return 0;
-
- dwork = &skl->d0i3.work;
-
- if (dwork->work.func) {
- if (skl->supend_active)
- flush_delayed_work(dwork);
- else
- cancel_delayed_work_sync(dwork);
- }
-
- return 0;
-}
-
-int skl_suspend_dsp(struct skl_dev *skl)
-{
- struct hdac_bus *bus = skl_to_bus(skl);
- int ret;
-
- /* if ppcap is not supported return 0 */
- if (!bus->ppcap)
- return 0;
-
- ret = skl_dsp_sleep(skl->dsp);
- if (ret < 0)
- return ret;
-
- /* disable ppcap interrupt */
- snd_hdac_ext_bus_ppcap_int_enable(bus, false);
- snd_hdac_ext_bus_ppcap_enable(bus, false);
-
- return 0;
-}
-
-int skl_resume_dsp(struct skl_dev *skl)
-{
- struct hdac_bus *bus = skl_to_bus(skl);
- int ret;
-
- /* if ppcap is not supported return 0 */
- if (!bus->ppcap)
- return 0;
-
- /* enable ppcap interrupt */
- snd_hdac_ext_bus_ppcap_enable(bus, true);
- snd_hdac_ext_bus_ppcap_int_enable(bus, true);
-
- /* check if DSP 1st boot is done */
- if (skl->is_first_boot)
- return 0;
-
- /*
- * Disable dynamic clock and power gating during firmware
- * and library download
- */
- skl->enable_miscbdcge(skl->dev, false);
- skl->clock_power_gating(skl->dev, false);
-
- ret = skl_dsp_wake(skl->dsp);
- skl->enable_miscbdcge(skl->dev, true);
- skl->clock_power_gating(skl->dev, true);
- if (ret < 0)
- return ret;
-
- if (skl->cfg.astate_cfg != NULL) {
- skl_dsp_set_astate_cfg(skl, skl->cfg.astate_cfg->count,
- skl->cfg.astate_cfg);
- }
- return ret;
-}
-
-enum skl_bitdepth skl_get_bit_depth(int params)
-{
- switch (params) {
- case 8:
- return SKL_DEPTH_8BIT;
-
- case 16:
- return SKL_DEPTH_16BIT;
-
- case 24:
- return SKL_DEPTH_24BIT;
-
- case 32:
- return SKL_DEPTH_32BIT;
-
- default:
- return SKL_DEPTH_INVALID;
-
- }
-}
-
-/*
- * Each module in DSP expects a base module configuration, which consists of
- * PCM format information, which we calculate in driver and resource values
- * which are read from widget information passed through topology binary
- * This is send when we create a module with INIT_INSTANCE IPC msg
- */
-static void skl_set_base_module_format(struct skl_dev *skl,
- struct skl_module_cfg *mconfig,
- struct skl_base_cfg *base_cfg)
-{
- struct skl_module *module = mconfig->module;
- struct skl_module_res *res = &module->resources[mconfig->res_idx];
- struct skl_module_iface *fmt = &module->formats[mconfig->fmt_idx];
- struct skl_module_fmt *format = &fmt->inputs[0].fmt;
-
- base_cfg->audio_fmt.number_of_channels = format->channels;
-
- base_cfg->audio_fmt.s_freq = format->s_freq;
- base_cfg->audio_fmt.bit_depth = format->bit_depth;
- base_cfg->audio_fmt.valid_bit_depth = format->valid_bit_depth;
- base_cfg->audio_fmt.ch_cfg = format->ch_cfg;
- base_cfg->audio_fmt.sample_type = format->sample_type;
-
- dev_dbg(skl->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n",
- format->bit_depth, format->valid_bit_depth,
- format->ch_cfg);
-
- base_cfg->audio_fmt.channel_map = format->ch_map;
-
- base_cfg->audio_fmt.interleaving = format->interleaving_style;
-
- base_cfg->cpc = res->cpc;
- base_cfg->ibs = res->ibs;
- base_cfg->obs = res->obs;
- base_cfg->is_pages = res->is_pages;
-}
-
-static void fill_pin_params(struct skl_audio_data_format *pin_fmt,
- struct skl_module_fmt *format)
-{
- pin_fmt->number_of_channels = format->channels;
- pin_fmt->s_freq = format->s_freq;
- pin_fmt->bit_depth = format->bit_depth;
- pin_fmt->valid_bit_depth = format->valid_bit_depth;
- pin_fmt->ch_cfg = format->ch_cfg;
- pin_fmt->sample_type = format->sample_type;
- pin_fmt->channel_map = format->ch_map;
- pin_fmt->interleaving = format->interleaving_style;
-}
-
-/*
- * Any module configuration begins with a base module configuration but
- * can be followed by a generic extension containing audio format for all
- * module's pins that are in use.
- */
-static void skl_set_base_ext_module_format(struct skl_dev *skl,
- struct skl_module_cfg *mconfig,
- struct skl_base_cfg_ext *base_cfg_ext)
-{
- struct skl_module *module = mconfig->module;
- struct skl_module_pin_resources *pin_res;
- struct skl_module_iface *fmt = &module->formats[mconfig->fmt_idx];
- struct skl_module_res *res = &module->resources[mconfig->res_idx];
- struct skl_module_fmt *format;
- struct skl_pin_format *pin_fmt;
- char *params;
- int i;
-
- base_cfg_ext->nr_input_pins = res->nr_input_pins;
- base_cfg_ext->nr_output_pins = res->nr_output_pins;
- base_cfg_ext->priv_param_length =
- mconfig->formats_config[SKL_PARAM_INIT].caps_size;
-
- for (i = 0; i < res->nr_input_pins; i++) {
- pin_res = &res->input[i];
- pin_fmt = &base_cfg_ext->pins_fmt[i];
-
- pin_fmt->pin_idx = pin_res->pin_index;
- pin_fmt->buf_size = pin_res->buf_size;
-
- format = &fmt->inputs[pin_res->pin_index].fmt;
- fill_pin_params(&pin_fmt->audio_fmt, format);
- }
-
- for (i = 0; i < res->nr_output_pins; i++) {
- pin_res = &res->output[i];
- pin_fmt = &base_cfg_ext->pins_fmt[res->nr_input_pins + i];
-
- pin_fmt->pin_idx = pin_res->pin_index;
- pin_fmt->buf_size = pin_res->buf_size;
-
- format = &fmt->outputs[pin_res->pin_index].fmt;
- fill_pin_params(&pin_fmt->audio_fmt, format);
- }
-
- if (!base_cfg_ext->priv_param_length)
- return;
-
- params = (char *)base_cfg_ext + sizeof(struct skl_base_cfg_ext);
- params += (base_cfg_ext->nr_input_pins + base_cfg_ext->nr_output_pins) *
- sizeof(struct skl_pin_format);
-
- memcpy(params, mconfig->formats_config[SKL_PARAM_INIT].caps,
- mconfig->formats_config[SKL_PARAM_INIT].caps_size);
-}
-
-/*
- * Copies copier capabilities into copier module and updates copier module
- * config size.
- */
-static void skl_copy_copier_caps(struct skl_module_cfg *mconfig,
- struct skl_cpr_cfg *cpr_mconfig)
-{
- if (mconfig->formats_config[SKL_PARAM_INIT].caps_size == 0)
- return;
-
- memcpy(&cpr_mconfig->gtw_cfg.config_data,
- mconfig->formats_config[SKL_PARAM_INIT].caps,
- mconfig->formats_config[SKL_PARAM_INIT].caps_size);
-
- cpr_mconfig->gtw_cfg.config_length =
- (mconfig->formats_config[SKL_PARAM_INIT].caps_size) / 4;
-}
-
-#define SKL_NON_GATEWAY_CPR_NODE_ID 0xFFFFFFFF
-/*
- * Calculate the gatewat settings required for copier module, type of
- * gateway and index of gateway to use
- */
-static u32 skl_get_node_id(struct skl_dev *skl,
- struct skl_module_cfg *mconfig)
-{
- union skl_connector_node_id node_id = {0};
- union skl_ssp_dma_node ssp_node = {0};
- struct skl_pipe_params *params = mconfig->pipe->p_params;
-
- switch (mconfig->dev_type) {
- case SKL_DEVICE_BT:
- node_id.node.dma_type =
- (SKL_CONN_SOURCE == mconfig->hw_conn_type) ?
- SKL_DMA_I2S_LINK_OUTPUT_CLASS :
- SKL_DMA_I2S_LINK_INPUT_CLASS;
- node_id.node.vindex = params->host_dma_id +
- (mconfig->vbus_id << 3);
- break;
-
- case SKL_DEVICE_I2S:
- node_id.node.dma_type =
- (SKL_CONN_SOURCE == mconfig->hw_conn_type) ?
- SKL_DMA_I2S_LINK_OUTPUT_CLASS :
- SKL_DMA_I2S_LINK_INPUT_CLASS;
- ssp_node.dma_node.time_slot_index = mconfig->time_slot;
- ssp_node.dma_node.i2s_instance = mconfig->vbus_id;
- node_id.node.vindex = ssp_node.val;
- break;
-
- case SKL_DEVICE_DMIC:
- node_id.node.dma_type = SKL_DMA_DMIC_LINK_INPUT_CLASS;
- node_id.node.vindex = mconfig->vbus_id +
- (mconfig->time_slot);
- break;
-
- case SKL_DEVICE_HDALINK:
- node_id.node.dma_type =
- (SKL_CONN_SOURCE == mconfig->hw_conn_type) ?
- SKL_DMA_HDA_LINK_OUTPUT_CLASS :
- SKL_DMA_HDA_LINK_INPUT_CLASS;
- node_id.node.vindex = params->link_dma_id;
- break;
-
- case SKL_DEVICE_HDAHOST:
- node_id.node.dma_type =
- (SKL_CONN_SOURCE == mconfig->hw_conn_type) ?
- SKL_DMA_HDA_HOST_OUTPUT_CLASS :
- SKL_DMA_HDA_HOST_INPUT_CLASS;
- node_id.node.vindex = params->host_dma_id;
- break;
-
- default:
- node_id.val = 0xFFFFFFFF;
- break;
- }
-
- return node_id.val;
-}
-
-static void skl_setup_cpr_gateway_cfg(struct skl_dev *skl,
- struct skl_module_cfg *mconfig,
- struct skl_cpr_cfg *cpr_mconfig)
-{
- u32 dma_io_buf;
- struct skl_module_res *res;
- int res_idx = mconfig->res_idx;
-
- cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(skl, mconfig);
-
- if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) {
- cpr_mconfig->cpr_feature_mask = 0;
- return;
- }
-
- if (skl->nr_modules) {
- res = &mconfig->module->resources[mconfig->res_idx];
- cpr_mconfig->gtw_cfg.dma_buffer_size = res->dma_buffer_size;
- goto skip_buf_size_calc;
- } else {
- res = &mconfig->module->resources[res_idx];
- }
-
- switch (mconfig->hw_conn_type) {
- case SKL_CONN_SOURCE:
- if (mconfig->dev_type == SKL_DEVICE_HDAHOST)
- dma_io_buf = res->ibs;
- else
- dma_io_buf = res->obs;
- break;
-
- case SKL_CONN_SINK:
- if (mconfig->dev_type == SKL_DEVICE_HDAHOST)
- dma_io_buf = res->obs;
- else
- dma_io_buf = res->ibs;
- break;
-
- default:
- dev_warn(skl->dev, "wrong connection type: %d\n",
- mconfig->hw_conn_type);
- return;
- }
-
- cpr_mconfig->gtw_cfg.dma_buffer_size =
- mconfig->dma_buffer_size * dma_io_buf;
-
- /* fallback to 2ms default value */
- if (!cpr_mconfig->gtw_cfg.dma_buffer_size) {
- if (mconfig->hw_conn_type == SKL_CONN_SOURCE)
- cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * res->obs;
- else
- cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * res->ibs;
- }
-
-skip_buf_size_calc:
- cpr_mconfig->cpr_feature_mask = 0;
- cpr_mconfig->gtw_cfg.config_length = 0;
-
- skl_copy_copier_caps(mconfig, cpr_mconfig);
-}
-
-#define DMA_CONTROL_ID 5
-#define DMA_I2S_BLOB_SIZE 21
-
-int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps,
- u32 caps_size, u32 node_id)
-{
- struct skl_dma_control *dma_ctrl;
- struct skl_ipc_large_config_msg msg = {0};
- int err = 0;
-
-
- /*
- * if blob size zero, then return
- */
- if (caps_size == 0)
- return 0;
-
- msg.large_param_id = DMA_CONTROL_ID;
- msg.param_data_size = sizeof(struct skl_dma_control) + caps_size;
-
- dma_ctrl = kzalloc(msg.param_data_size, GFP_KERNEL);
- if (dma_ctrl == NULL)
- return -ENOMEM;
-
- dma_ctrl->node_id = node_id;
-
- /*
- * NHLT blob may contain additional configs along with i2s blob.
- * firmware expects only the i2s blob size as the config_length.
- * So fix to i2s blob size.
- * size in dwords.
- */
- dma_ctrl->config_length = DMA_I2S_BLOB_SIZE;
-
- memcpy(dma_ctrl->config_data, caps, caps_size);
-
- err = skl_ipc_set_large_config(&skl->ipc, &msg, (u32 *)dma_ctrl);
-
- kfree(dma_ctrl);
- return err;
-}
-EXPORT_SYMBOL_GPL(skl_dsp_set_dma_control);
-
-static void skl_setup_out_format(struct skl_dev *skl,
- struct skl_module_cfg *mconfig,
- struct skl_audio_data_format *out_fmt)
-{
- struct skl_module *module = mconfig->module;
- struct skl_module_iface *fmt = &module->formats[mconfig->fmt_idx];
- struct skl_module_fmt *format = &fmt->outputs[0].fmt;
-
- out_fmt->number_of_channels = (u8)format->channels;
- out_fmt->s_freq = format->s_freq;
- out_fmt->bit_depth = format->bit_depth;
- out_fmt->valid_bit_depth = format->valid_bit_depth;
- out_fmt->ch_cfg = format->ch_cfg;
-
- out_fmt->channel_map = format->ch_map;
- out_fmt->interleaving = format->interleaving_style;
- out_fmt->sample_type = format->sample_type;
-
- dev_dbg(skl->dev, "copier out format chan=%d fre=%d bitdepth=%d\n",
- out_fmt->number_of_channels, format->s_freq, format->bit_depth);
-}
-
-/*
- * DSP needs SRC module for frequency conversion, SRC takes base module
- * configuration and the target frequency as extra parameter passed as src
- * config
- */
-static void skl_set_src_format(struct skl_dev *skl,
- struct skl_module_cfg *mconfig,
- struct skl_src_module_cfg *src_mconfig)
-{
- struct skl_module *module = mconfig->module;
- struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx];
- struct skl_module_fmt *fmt = &iface->outputs[0].fmt;
-
- skl_set_base_module_format(skl, mconfig,
- (struct skl_base_cfg *)src_mconfig);
-
- src_mconfig->src_cfg = fmt->s_freq;
-}
-
-/*
- * DSP needs updown module to do channel conversion. updown module take base
- * module configuration and channel configuration
- * It also take coefficients and now we have defaults applied here
- */
-static void skl_set_updown_mixer_format(struct skl_dev *skl,
- struct skl_module_cfg *mconfig,
- struct skl_up_down_mixer_cfg *mixer_mconfig)
-{
- struct skl_module *module = mconfig->module;
- struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx];
- struct skl_module_fmt *fmt = &iface->outputs[0].fmt;
-
- skl_set_base_module_format(skl, mconfig,
- (struct skl_base_cfg *)mixer_mconfig);
- mixer_mconfig->out_ch_cfg = fmt->ch_cfg;
- mixer_mconfig->ch_map = fmt->ch_map;
-}
-
-/*
- * 'copier' is DSP internal module which copies data from Host DMA (HDA host
- * dma) or link (hda link, SSP, PDM)
- * Here we calculate the copier module parameters, like PCM format, output
- * format, gateway settings
- * copier_module_config is sent as input buffer with INIT_INSTANCE IPC msg
- */
-static void skl_set_copier_format(struct skl_dev *skl,
- struct skl_module_cfg *mconfig,
- struct skl_cpr_cfg *cpr_mconfig)
-{
- struct skl_audio_data_format *out_fmt = &cpr_mconfig->out_fmt;
- struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)cpr_mconfig;
-
- skl_set_base_module_format(skl, mconfig, base_cfg);
-
- skl_setup_out_format(skl, mconfig, out_fmt);
- skl_setup_cpr_gateway_cfg(skl, mconfig, cpr_mconfig);
-}
-
-/*
- * Mic select module allows selecting one or many input channels, thus
- * acting as a demux.
- *
- * Mic select module take base module configuration and out-format
- * configuration
- */
-static void skl_set_base_outfmt_format(struct skl_dev *skl,
- struct skl_module_cfg *mconfig,
- struct skl_base_outfmt_cfg *base_outfmt_mcfg)
-{
- struct skl_audio_data_format *out_fmt = &base_outfmt_mcfg->out_fmt;
- struct skl_base_cfg *base_cfg =
- (struct skl_base_cfg *)base_outfmt_mcfg;
-
- skl_set_base_module_format(skl, mconfig, base_cfg);
- skl_setup_out_format(skl, mconfig, out_fmt);
-}
-
-static u16 skl_get_module_param_size(struct skl_dev *skl,
- struct skl_module_cfg *mconfig)
-{
- struct skl_module_res *res;
- struct skl_module *module = mconfig->module;
- u16 param_size;
-
- switch (mconfig->m_type) {
- case SKL_MODULE_TYPE_COPIER:
- param_size = sizeof(struct skl_cpr_cfg);
- param_size += mconfig->formats_config[SKL_PARAM_INIT].caps_size;
- return param_size;
-
- case SKL_MODULE_TYPE_SRCINT:
- return sizeof(struct skl_src_module_cfg);
-
- case SKL_MODULE_TYPE_UPDWMIX:
- return sizeof(struct skl_up_down_mixer_cfg);
-
- case SKL_MODULE_TYPE_BASE_OUTFMT:
- case SKL_MODULE_TYPE_MIC_SELECT:
- return sizeof(struct skl_base_outfmt_cfg);
-
- case SKL_MODULE_TYPE_MIXER:
- case SKL_MODULE_TYPE_KPB:
- return sizeof(struct skl_base_cfg);
-
- case SKL_MODULE_TYPE_ALGO:
- default:
- res = &module->resources[mconfig->res_idx];
-
- param_size = sizeof(struct skl_base_cfg) + sizeof(struct skl_base_cfg_ext);
- param_size += (res->nr_input_pins + res->nr_output_pins) *
- sizeof(struct skl_pin_format);
- param_size += mconfig->formats_config[SKL_PARAM_INIT].caps_size;
-
- return param_size;
- }
-
- return 0;
-}
-
-/*
- * DSP firmware supports various modules like copier, SRC, updown etc.
- * These modules required various parameters to be calculated and sent for
- * the module initialization to DSP. By default a generic module needs only
- * base module format configuration
- */
-
-static int skl_set_module_format(struct skl_dev *skl,
- struct skl_module_cfg *module_config,
- u16 *module_config_size,
- void **param_data)
-{
- u16 param_size;
-
- param_size = skl_get_module_param_size(skl, module_config);
-
- *param_data = kzalloc(param_size, GFP_KERNEL);
- if (NULL == *param_data)
- return -ENOMEM;
-
- *module_config_size = param_size;
-
- switch (module_config->m_type) {
- case SKL_MODULE_TYPE_COPIER:
- skl_set_copier_format(skl, module_config, *param_data);
- break;
-
- case SKL_MODULE_TYPE_SRCINT:
- skl_set_src_format(skl, module_config, *param_data);
- break;
-
- case SKL_MODULE_TYPE_UPDWMIX:
- skl_set_updown_mixer_format(skl, module_config, *param_data);
- break;
-
- case SKL_MODULE_TYPE_BASE_OUTFMT:
- case SKL_MODULE_TYPE_MIC_SELECT:
- skl_set_base_outfmt_format(skl, module_config, *param_data);
- break;
-
- case SKL_MODULE_TYPE_MIXER:
- case SKL_MODULE_TYPE_KPB:
- skl_set_base_module_format(skl, module_config, *param_data);
- break;
-
- case SKL_MODULE_TYPE_ALGO:
- default:
- skl_set_base_module_format(skl, module_config, *param_data);
- skl_set_base_ext_module_format(skl, module_config,
- *param_data +
- sizeof(struct skl_base_cfg));
- break;
- }
-
- dev_dbg(skl->dev, "Module type=%d id=%d config size: %d bytes\n",
- module_config->m_type, module_config->id.module_id,
- param_size);
- print_hex_dump_debug("Module params:", DUMP_PREFIX_OFFSET, 8, 4,
- *param_data, param_size, false);
- return 0;
-}
-
-static int skl_get_queue_index(struct skl_module_pin *mpin,
- struct skl_module_inst_id id, int max)
-{
- int i;
-
- for (i = 0; i < max; i++) {
- if (mpin[i].id.module_id == id.module_id &&
- mpin[i].id.instance_id == id.instance_id)
- return i;
- }
-
- return -EINVAL;
-}
-
-/*
- * Allocates queue for each module.
- * if dynamic, the pin_index is allocated 0 to max_pin.
- * In static, the pin_index is fixed based on module_id and instance id
- */
-static int skl_alloc_queue(struct skl_module_pin *mpin,
- struct skl_module_cfg *tgt_cfg, int max)
-{
- int i;
- struct skl_module_inst_id id = tgt_cfg->id;
- /*
- * if pin in dynamic, find first free pin
- * otherwise find match module and instance id pin as topology will
- * ensure a unique pin is assigned to this so no need to
- * allocate/free
- */
- for (i = 0; i < max; i++) {
- if (mpin[i].is_dynamic) {
- if (!mpin[i].in_use &&
- mpin[i].pin_state == SKL_PIN_UNBIND) {
-
- mpin[i].in_use = true;
- mpin[i].id.module_id = id.module_id;
- mpin[i].id.instance_id = id.instance_id;
- mpin[i].id.pvt_id = id.pvt_id;
- mpin[i].tgt_mcfg = tgt_cfg;
- return i;
- }
- } else {
- if (mpin[i].id.module_id == id.module_id &&
- mpin[i].id.instance_id == id.instance_id &&
- mpin[i].pin_state == SKL_PIN_UNBIND) {
-
- mpin[i].tgt_mcfg = tgt_cfg;
- return i;
- }
- }
- }
-
- return -EINVAL;
-}
-
-static void skl_free_queue(struct skl_module_pin *mpin, int q_index)
-{
- if (mpin[q_index].is_dynamic) {
- mpin[q_index].in_use = false;
- mpin[q_index].id.module_id = 0;
- mpin[q_index].id.instance_id = 0;
- mpin[q_index].id.pvt_id = 0;
- }
- mpin[q_index].pin_state = SKL_PIN_UNBIND;
- mpin[q_index].tgt_mcfg = NULL;
-}
-
-/* Module state will be set to unint, if all the out pin state is UNBIND */
-
-static void skl_clear_module_state(struct skl_module_pin *mpin, int max,
- struct skl_module_cfg *mcfg)
-{
- int i;
- bool found = false;
-
- for (i = 0; i < max; i++) {
- if (mpin[i].pin_state == SKL_PIN_UNBIND)
- continue;
- found = true;
- break;
- }
-
- if (!found)
- mcfg->m_state = SKL_MODULE_INIT_DONE;
- return;
-}
-
-/*
- * A module needs to be instanataited in DSP. A mdoule is present in a
- * collection of module referred as a PIPE.
- * We first calculate the module format, based on module type and then
- * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper
- */
-int skl_init_module(struct skl_dev *skl,
- struct skl_module_cfg *mconfig)
-{
- u16 module_config_size = 0;
- void *param_data = NULL;
- int ret;
- struct skl_ipc_init_instance_msg msg;
-
- dev_dbg(skl->dev, "%s: module_id = %d instance=%d\n", __func__,
- mconfig->id.module_id, mconfig->id.pvt_id);
-
- if (mconfig->pipe->state != SKL_PIPE_CREATED) {
- dev_err(skl->dev, "Pipe not created state= %d pipe_id= %d\n",
- mconfig->pipe->state, mconfig->pipe->ppl_id);
- return -EIO;
- }
-
- ret = skl_set_module_format(skl, mconfig,
- &module_config_size, &param_data);
- if (ret < 0) {
- dev_err(skl->dev, "Failed to set module format ret=%d\n", ret);
- return ret;
- }
-
- msg.module_id = mconfig->id.module_id;
- msg.instance_id = mconfig->id.pvt_id;
- msg.ppl_instance_id = mconfig->pipe->ppl_id;
- msg.param_data_size = module_config_size;
- msg.core_id = mconfig->core_id;
- msg.domain = mconfig->domain;
-
- ret = skl_ipc_init_instance(&skl->ipc, &msg, param_data);
- if (ret < 0) {
- dev_err(skl->dev, "Failed to init instance ret=%d\n", ret);
- kfree(param_data);
- return ret;
- }
- mconfig->m_state = SKL_MODULE_INIT_DONE;
- kfree(param_data);
- return ret;
-}
-
-static void skl_dump_bind_info(struct skl_dev *skl, struct skl_module_cfg
- *src_module, struct skl_module_cfg *dst_module)
-{
- dev_dbg(skl->dev, "%s: src module_id = %d src_instance=%d\n",
- __func__, src_module->id.module_id, src_module->id.pvt_id);
- dev_dbg(skl->dev, "%s: dst_module=%d dst_instance=%d\n", __func__,
- dst_module->id.module_id, dst_module->id.pvt_id);
-
- dev_dbg(skl->dev, "src_module state = %d dst module state = %d\n",
- src_module->m_state, dst_module->m_state);
-}
-
-/*
- * On module freeup, we need to unbind the module with modules
- * it is already bind.
- * Find the pin allocated and unbind then using bind_unbind IPC
- */
-int skl_unbind_modules(struct skl_dev *skl,
- struct skl_module_cfg *src_mcfg,
- struct skl_module_cfg *dst_mcfg)
-{
- int ret;
- struct skl_ipc_bind_unbind_msg msg;
- struct skl_module_inst_id src_id = src_mcfg->id;
- struct skl_module_inst_id dst_id = dst_mcfg->id;
- int in_max = dst_mcfg->module->max_input_pins;
- int out_max = src_mcfg->module->max_output_pins;
- int src_index, dst_index, src_pin_state, dst_pin_state;
-
- skl_dump_bind_info(skl, src_mcfg, dst_mcfg);
-
- /* get src queue index */
- src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max);
- if (src_index < 0)
- return 0;
-
- msg.src_queue = src_index;
-
- /* get dst queue index */
- dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max);
- if (dst_index < 0)
- return 0;
-
- msg.dst_queue = dst_index;
-
- src_pin_state = src_mcfg->m_out_pin[src_index].pin_state;
- dst_pin_state = dst_mcfg->m_in_pin[dst_index].pin_state;
-
- if (src_pin_state != SKL_PIN_BIND_DONE ||
- dst_pin_state != SKL_PIN_BIND_DONE)
- return 0;
-
- msg.module_id = src_mcfg->id.module_id;
- msg.instance_id = src_mcfg->id.pvt_id;
- msg.dst_module_id = dst_mcfg->id.module_id;
- msg.dst_instance_id = dst_mcfg->id.pvt_id;
- msg.bind = false;
-
- ret = skl_ipc_bind_unbind(&skl->ipc, &msg);
- if (!ret) {
- /* free queue only if unbind is success */
- skl_free_queue(src_mcfg->m_out_pin, src_index);
- skl_free_queue(dst_mcfg->m_in_pin, dst_index);
-
- /*
- * check only if src module bind state, bind is
- * always from src -> sink
- */
- skl_clear_module_state(src_mcfg->m_out_pin, out_max, src_mcfg);
- }
-
- return ret;
-}
-
-#define CPR_SINK_FMT_PARAM_ID 2
-
-/*
- * Once a module is instantiated it need to be 'bind' with other modules in
- * the pipeline. For binding we need to find the module pins which are bind
- * together
- * This function finds the pins and then sends bund_unbind IPC message to
- * DSP using IPC helper
- */
-int skl_bind_modules(struct skl_dev *skl,
- struct skl_module_cfg *src_mcfg,
- struct skl_module_cfg *dst_mcfg)
-{
- int ret = 0;
- struct skl_ipc_bind_unbind_msg msg;
- int in_max = dst_mcfg->module->max_input_pins;
- int out_max = src_mcfg->module->max_output_pins;
- int src_index, dst_index;
- struct skl_module_fmt *format;
- struct skl_cpr_pin_fmt pin_fmt;
- struct skl_module *module;
- struct skl_module_iface *fmt;
-
- skl_dump_bind_info(skl, src_mcfg, dst_mcfg);
-
- if (src_mcfg->m_state < SKL_MODULE_INIT_DONE ||
- dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
- return 0;
-
- src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_mcfg, out_max);
- if (src_index < 0)
- return -EINVAL;
-
- msg.src_queue = src_index;
- dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_mcfg, in_max);
- if (dst_index < 0) {
- skl_free_queue(src_mcfg->m_out_pin, src_index);
- return -EINVAL;
- }
-
- /*
- * Copier module requires the separate large_config_set_ipc to
- * configure the pins other than 0
- */
- if (src_mcfg->m_type == SKL_MODULE_TYPE_COPIER && src_index > 0) {
- pin_fmt.sink_id = src_index;
- module = src_mcfg->module;
- fmt = &module->formats[src_mcfg->fmt_idx];
-
- /* Input fmt is same as that of src module input cfg */
- format = &fmt->inputs[0].fmt;
- fill_pin_params(&(pin_fmt.src_fmt), format);
-
- format = &fmt->outputs[src_index].fmt;
- fill_pin_params(&(pin_fmt.dst_fmt), format);
- ret = skl_set_module_params(skl, (void *)&pin_fmt,
- sizeof(struct skl_cpr_pin_fmt),
- CPR_SINK_FMT_PARAM_ID, src_mcfg);
-
- if (ret < 0)
- goto out;
- }
-
- msg.dst_queue = dst_index;
-
- dev_dbg(skl->dev, "src queue = %d dst queue =%d\n",
- msg.src_queue, msg.dst_queue);
-
- msg.module_id = src_mcfg->id.module_id;
- msg.instance_id = src_mcfg->id.pvt_id;
- msg.dst_module_id = dst_mcfg->id.module_id;
- msg.dst_instance_id = dst_mcfg->id.pvt_id;
- msg.bind = true;
-
- ret = skl_ipc_bind_unbind(&skl->ipc, &msg);
-
- if (!ret) {
- src_mcfg->m_state = SKL_MODULE_BIND_DONE;
- src_mcfg->m_out_pin[src_index].pin_state = SKL_PIN_BIND_DONE;
- dst_mcfg->m_in_pin[dst_index].pin_state = SKL_PIN_BIND_DONE;
- return ret;
- }
-out:
- /* error case , if IPC fails, clear the queue index */
- skl_free_queue(src_mcfg->m_out_pin, src_index);
- skl_free_queue(dst_mcfg->m_in_pin, dst_index);
-
- return ret;
-}
-
-static int skl_set_pipe_state(struct skl_dev *skl, struct skl_pipe *pipe,
- enum skl_ipc_pipeline_state state)
-{
- dev_dbg(skl->dev, "%s: pipe_state = %d\n", __func__, state);
-
- return skl_ipc_set_pipeline_state(&skl->ipc, pipe->ppl_id, state);
-}
-
-/*
- * A pipeline is a collection of modules. Before a module in instantiated a
- * pipeline needs to be created for it.
- * This function creates pipeline, by sending create pipeline IPC messages
- * to FW
- */
-int skl_create_pipeline(struct skl_dev *skl, struct skl_pipe *pipe)
-{
- int ret;
-
- dev_dbg(skl->dev, "%s: pipe_id = %d\n", __func__, pipe->ppl_id);
-
- ret = skl_ipc_create_pipeline(&skl->ipc, pipe->memory_pages,
- pipe->pipe_priority, pipe->ppl_id,
- pipe->lp_mode);
- if (ret < 0) {
- dev_err(skl->dev, "Failed to create pipeline\n");
- return ret;
- }
-
- pipe->state = SKL_PIPE_CREATED;
-
- return 0;
-}
-
-/*
- * A pipeline needs to be deleted on cleanup. If a pipeline is running,
- * then pause it first. Before actual deletion, pipeline should enter
- * reset state. Finish the procedure by sending delete pipeline IPC.
- * DSP will stop the DMA engines and release resources
- */
-int skl_delete_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
-{
- int ret;
-
- dev_dbg(skl->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
-
- /* If pipe was not created in FW, do not try to delete it */
- if (pipe->state < SKL_PIPE_CREATED)
- return 0;
-
- /* If pipe is started, do stop the pipe in FW. */
- if (pipe->state >= SKL_PIPE_STARTED) {
- ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED);
- if (ret < 0) {
- dev_err(skl->dev, "Failed to stop pipeline\n");
- return ret;
- }
-
- pipe->state = SKL_PIPE_PAUSED;
- }
-
- /* reset pipe state before deletion */
- ret = skl_set_pipe_state(skl, pipe, PPL_RESET);
- if (ret < 0) {
- dev_err(skl->dev, "Failed to reset pipe ret=%d\n", ret);
- return ret;
- }
-
- pipe->state = SKL_PIPE_RESET;
-
- ret = skl_ipc_delete_pipeline(&skl->ipc, pipe->ppl_id);
- if (ret < 0) {
- dev_err(skl->dev, "Failed to delete pipeline\n");
- return ret;
- }
-
- pipe->state = SKL_PIPE_INVALID;
-
- return ret;
-}
-
-/*
- * A pipeline is also a scheduling entity in DSP which can be run, stopped
- * For processing data the pipe need to be run by sending IPC set pipe state
- * to DSP
- */
-int skl_run_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
-{
- int ret;
-
- dev_dbg(skl->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
-
- /* If pipe was not created in FW, do not try to pause or delete */
- if (pipe->state < SKL_PIPE_CREATED)
- return 0;
-
- /* Pipe has to be paused before it is started */
- ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED);
- if (ret < 0) {
- dev_err(skl->dev, "Failed to pause pipe\n");
- return ret;
- }
-
- pipe->state = SKL_PIPE_PAUSED;
-
- ret = skl_set_pipe_state(skl, pipe, PPL_RUNNING);
- if (ret < 0) {
- dev_err(skl->dev, "Failed to start pipe\n");
- return ret;
- }
-
- pipe->state = SKL_PIPE_STARTED;
-
- return 0;
-}
-
-/*
- * Stop the pipeline by sending set pipe state IPC
- * DSP doesnt implement stop so we always send pause message
- */
-int skl_stop_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
-{
- int ret;
-
- dev_dbg(skl->dev, "In %s pipe=%d\n", __func__, pipe->ppl_id);
-
- /* If pipe was not created in FW, do not try to pause or delete */
- if (pipe->state < SKL_PIPE_PAUSED)
- return 0;
-
- ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED);
- if (ret < 0) {
- dev_dbg(skl->dev, "Failed to stop pipe\n");
- return ret;
- }
-
- pipe->state = SKL_PIPE_PAUSED;
-
- return 0;
-}
-
-/*
- * Reset the pipeline by sending set pipe state IPC this will reset the DMA
- * from the DSP side
- */
-int skl_reset_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
-{
- int ret;
-
- /* If pipe was not created in FW, do not try to pause or delete */
- if (pipe->state < SKL_PIPE_PAUSED)
- return 0;
-
- ret = skl_set_pipe_state(skl, pipe, PPL_RESET);
- if (ret < 0) {
- dev_dbg(skl->dev, "Failed to reset pipe ret=%d\n", ret);
- return ret;
- }
-
- pipe->state = SKL_PIPE_RESET;
-
- return 0;
-}
-
-/* Algo parameter set helper function */
-int skl_set_module_params(struct skl_dev *skl, u32 *params, int size,
- u32 param_id, struct skl_module_cfg *mcfg)
-{
- struct skl_ipc_large_config_msg msg;
-
- msg.module_id = mcfg->id.module_id;
- msg.instance_id = mcfg->id.pvt_id;
- msg.param_data_size = size;
- msg.large_param_id = param_id;
-
- return skl_ipc_set_large_config(&skl->ipc, &msg, params);
-}
-
-int skl_get_module_params(struct skl_dev *skl, u32 *params, int size,
- u32 param_id, struct skl_module_cfg *mcfg)
-{
- struct skl_ipc_large_config_msg msg;
- size_t bytes = size;
-
- msg.module_id = mcfg->id.module_id;
- msg.instance_id = mcfg->id.pvt_id;
- msg.param_data_size = size;
- msg.large_param_id = param_id;
-
- return skl_ipc_get_large_config(&skl->ipc, &msg, &params, &bytes);
-}
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
deleted file mode 100644
index e617b4c335a4..000000000000
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ /dev/null
@@ -1,269 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * skl-nhlt.c - Intel SKL Platform NHLT parsing
- *
- * Copyright (C) 2015 Intel Corp
- * Author: Sanjiv Kumar <sanjiv.kumar@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-#include <linux/pci.h>
-#include <sound/intel-nhlt.h>
-#include "skl.h"
-#include "skl-i2s.h"
-
-static void skl_nhlt_trim_space(char *trim)
-{
- char *s = trim;
- int cnt;
- int i;
-
- cnt = 0;
- for (i = 0; s[i]; i++) {
- if (!isspace(s[i]))
- s[cnt++] = s[i];
- }
-
- s[cnt] = '\0';
-}
-
-int skl_nhlt_update_topology_bin(struct skl_dev *skl)
-{
- struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
- struct hdac_bus *bus = skl_to_bus(skl);
- struct device *dev = bus->dev;
-
- dev_dbg(dev, "oem_id %.6s, oem_table_id %.8s oem_revision %d\n",
- nhlt->header.oem_id, nhlt->header.oem_table_id,
- nhlt->header.oem_revision);
-
- snprintf(skl->tplg_name, sizeof(skl->tplg_name), "%x-%.6s-%.8s-%d%s",
- skl->pci_id, nhlt->header.oem_id, nhlt->header.oem_table_id,
- nhlt->header.oem_revision, "-tplg.bin");
-
- skl_nhlt_trim_space(skl->tplg_name);
-
- return 0;
-}
-
-static ssize_t platform_id_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct pci_dev *pci = to_pci_dev(dev);
- struct hdac_bus *bus = pci_get_drvdata(pci);
- struct skl_dev *skl = bus_to_skl(bus);
- struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
- char platform_id[32];
-
- sprintf(platform_id, "%x-%.6s-%.8s-%d", skl->pci_id,
- nhlt->header.oem_id, nhlt->header.oem_table_id,
- nhlt->header.oem_revision);
-
- skl_nhlt_trim_space(platform_id);
- return sysfs_emit(buf, "%s\n", platform_id);
-}
-
-static DEVICE_ATTR_RO(platform_id);
-
-int skl_nhlt_create_sysfs(struct skl_dev *skl)
-{
- struct device *dev = &skl->pci->dev;
-
- if (sysfs_create_file(&dev->kobj, &dev_attr_platform_id.attr))
- dev_warn(dev, "Error creating sysfs entry\n");
-
- return 0;
-}
-
-void skl_nhlt_remove_sysfs(struct skl_dev *skl)
-{
- struct device *dev = &skl->pci->dev;
-
- if (skl->nhlt)
- sysfs_remove_file(&dev->kobj, &dev_attr_platform_id.attr);
-}
-
-/*
- * Queries NHLT for all the fmt configuration for a particular endpoint and
- * stores all possible rates supported in a rate table for the corresponding
- * sclk/sclkfs.
- */
-static void skl_get_ssp_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks,
- struct nhlt_fmt *fmt, u8 id)
-{
- struct skl_i2s_config_blob_ext *i2s_config_ext;
- struct skl_i2s_config_blob_legacy *i2s_config;
- struct skl_clk_parent_src *parent;
- struct skl_ssp_clk *sclk, *sclkfs;
- struct nhlt_fmt_cfg *fmt_cfg;
- struct wav_fmt_ext *wav_fmt;
- unsigned long rate;
- int rate_index = 0;
- u16 channels, bps;
- u8 clk_src;
- int i, j;
- u32 fs;
-
- sclk = &ssp_clks[SKL_SCLK_OFS];
- sclkfs = &ssp_clks[SKL_SCLKFS_OFS];
-
- if (fmt->fmt_count == 0)
- return;
-
- fmt_cfg = (struct nhlt_fmt_cfg *)fmt->fmt_config;
- for (i = 0; i < fmt->fmt_count; i++) {
- struct nhlt_fmt_cfg *saved_fmt_cfg = fmt_cfg;
- bool present = false;
-
- wav_fmt = &saved_fmt_cfg->fmt_ext;
-
- channels = wav_fmt->fmt.channels;
- bps = wav_fmt->fmt.bits_per_sample;
- fs = wav_fmt->fmt.samples_per_sec;
-
- /*
- * In case of TDM configuration on a ssp, there can
- * be more than one blob in which channel masks are
- * different for each usecase for a specific rate and bps.
- * But the sclk rate will be generated for the total
- * number of channels used for that endpoint.
- *
- * So for the given fs and bps, choose blob which has
- * the superset of all channels for that endpoint and
- * derive the rate.
- */
- for (j = i; j < fmt->fmt_count; j++) {
- struct nhlt_fmt_cfg *tmp_fmt_cfg = fmt_cfg;
-
- wav_fmt = &tmp_fmt_cfg->fmt_ext;
- if ((fs == wav_fmt->fmt.samples_per_sec) &&
- (bps == wav_fmt->fmt.bits_per_sample)) {
- channels = max_t(u16, channels,
- wav_fmt->fmt.channels);
- saved_fmt_cfg = tmp_fmt_cfg;
- }
- /* Move to the next nhlt_fmt_cfg */
- tmp_fmt_cfg = (struct nhlt_fmt_cfg *)(tmp_fmt_cfg->config.caps +
- tmp_fmt_cfg->config.size);
- }
-
- rate = channels * bps * fs;
-
- /* check if the rate is added already to the given SSP's sclk */
- for (j = 0; (j < SKL_MAX_CLK_RATES) &&
- (sclk[id].rate_cfg[j].rate != 0); j++) {
- if (sclk[id].rate_cfg[j].rate == rate) {
- present = true;
- break;
- }
- }
-
- /* Fill rate and parent for sclk/sclkfs */
- if (!present) {
- struct nhlt_fmt_cfg *first_fmt_cfg;
-
- first_fmt_cfg = (struct nhlt_fmt_cfg *)fmt->fmt_config;
- i2s_config_ext = (struct skl_i2s_config_blob_ext *)
- first_fmt_cfg->config.caps;
-
- /* MCLK Divider Source Select */
- if (is_legacy_blob(i2s_config_ext->hdr.sig)) {
- i2s_config = ext_to_legacy_blob(i2s_config_ext);
- clk_src = get_clk_src(i2s_config->mclk,
- SKL_MNDSS_DIV_CLK_SRC_MASK);
- } else {
- clk_src = get_clk_src(i2s_config_ext->mclk,
- SKL_MNDSS_DIV_CLK_SRC_MASK);
- }
-
- parent = skl_get_parent_clk(clk_src);
-
- /* Move to the next nhlt_fmt_cfg */
- fmt_cfg = (struct nhlt_fmt_cfg *)(fmt_cfg->config.caps +
- fmt_cfg->config.size);
- /*
- * Do not copy the config data if there is no parent
- * clock available for this clock source select
- */
- if (!parent)
- continue;
-
- sclk[id].rate_cfg[rate_index].rate = rate;
- sclk[id].rate_cfg[rate_index].config = saved_fmt_cfg;
- sclkfs[id].rate_cfg[rate_index].rate = rate;
- sclkfs[id].rate_cfg[rate_index].config = saved_fmt_cfg;
- sclk[id].parent_name = parent->name;
- sclkfs[id].parent_name = parent->name;
-
- rate_index++;
- }
- }
-}
-
-static void skl_get_mclk(struct skl_dev *skl, struct skl_ssp_clk *mclk,
- struct nhlt_fmt *fmt, u8 id)
-{
- struct skl_i2s_config_blob_ext *i2s_config_ext;
- struct skl_i2s_config_blob_legacy *i2s_config;
- struct nhlt_fmt_cfg *fmt_cfg;
- struct skl_clk_parent_src *parent;
- u32 clkdiv, div_ratio;
- u8 clk_src;
-
- fmt_cfg = (struct nhlt_fmt_cfg *)fmt->fmt_config;
- i2s_config_ext = (struct skl_i2s_config_blob_ext *)fmt_cfg->config.caps;
-
- /* MCLK Divider Source Select and divider */
- if (is_legacy_blob(i2s_config_ext->hdr.sig)) {
- i2s_config = ext_to_legacy_blob(i2s_config_ext);
- clk_src = get_clk_src(i2s_config->mclk,
- SKL_MCLK_DIV_CLK_SRC_MASK);
- clkdiv = i2s_config->mclk.mdivr &
- SKL_MCLK_DIV_RATIO_MASK;
- } else {
- clk_src = get_clk_src(i2s_config_ext->mclk,
- SKL_MCLK_DIV_CLK_SRC_MASK);
- clkdiv = i2s_config_ext->mclk.mdivr[0] &
- SKL_MCLK_DIV_RATIO_MASK;
- }
-
- /* bypass divider */
- div_ratio = 1;
-
- if (clkdiv != SKL_MCLK_DIV_RATIO_MASK)
- /* Divider is 2 + clkdiv */
- div_ratio = clkdiv + 2;
-
- /* Calculate MCLK rate from source using div value */
- parent = skl_get_parent_clk(clk_src);
- if (!parent)
- return;
-
- mclk[id].rate_cfg[0].rate = parent->rate/div_ratio;
- mclk[id].rate_cfg[0].config = fmt_cfg;
- mclk[id].parent_name = parent->name;
-}
-
-void skl_get_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks)
-{
- struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
- struct nhlt_endpoint *epnt;
- struct nhlt_fmt *fmt;
- int i;
- u8 id;
-
- epnt = (struct nhlt_endpoint *)nhlt->desc;
- for (i = 0; i < nhlt->endpoint_count; i++) {
- if (epnt->linktype == NHLT_LINK_SSP) {
- id = epnt->virtual_bus_id;
-
- fmt = (struct nhlt_fmt *)(epnt->config.caps
- + epnt->config.size);
-
- skl_get_ssp_clks(skl, ssp_clks, fmt, id);
- skl_get_mclk(skl, ssp_clks, fmt, id);
- }
- epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
- }
-}
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
deleted file mode 100644
index 613b27b8da13..000000000000
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ /dev/null
@@ -1,1507 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * skl-pcm.c -ASoC HDA Platform driver file implementing PCM functionality
- *
- * Copyright (C) 2014-2015 Intel Corp
- * Author: Jeeja KP <jeeja.kp@intel.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/pci.h>
-#include <linux/pm_runtime.h>
-#include <linux/delay.h>
-#include <sound/hdaudio.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include "skl.h"
-#include "skl-topology.h"
-#include "skl-sst-dsp.h"
-#include "skl-sst-ipc.h"
-
-#define HDA_MONO 1
-#define HDA_STEREO 2
-#define HDA_QUAD 4
-#define HDA_MAX 8
-
-static const struct snd_pcm_hardware azx_pcm_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_HAS_WALL_CLOCK | /* legacy */
- SNDRV_PCM_INFO_HAS_LINK_ATIME |
- SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
- .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_8000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 8,
- .buffer_bytes_max = AZX_MAX_BUF_SIZE,
- .period_bytes_min = 128,
- .period_bytes_max = AZX_MAX_BUF_SIZE / 2,
- .periods_min = 2,
- .periods_max = AZX_MAX_FRAG,
- .fifo_size = 0,
-};
-
-static inline
-struct hdac_ext_stream *get_hdac_ext_stream(struct snd_pcm_substream *substream)
-{
- return substream->runtime->private_data;
-}
-
-static struct hdac_bus *get_bus_ctx(struct snd_pcm_substream *substream)
-{
- struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
- struct hdac_stream *hstream = hdac_stream(stream);
- struct hdac_bus *bus = hstream->bus;
- return bus;
-}
-
-static int skl_substream_alloc_pages(struct hdac_bus *bus,
- struct snd_pcm_substream *substream,
- size_t size)
-{
- struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
-
- hdac_stream(stream)->bufsize = 0;
- hdac_stream(stream)->period_bytes = 0;
- hdac_stream(stream)->format_val = 0;
-
- return 0;
-}
-
-static void skl_set_pcm_constrains(struct hdac_bus *bus,
- struct snd_pcm_runtime *runtime)
-{
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
-
- /* avoid wrap-around with wall-clock */
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME,
- 20, 178000000);
-}
-
-static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_bus *bus)
-{
- if (bus->ppcap)
- return HDAC_EXT_STREAM_TYPE_HOST;
- else
- return HDAC_EXT_STREAM_TYPE_COUPLED;
-}
-
-/*
- * check if the stream opened is marked as ignore_suspend by machine, if so
- * then enable suspend_active refcount
- *
- * The count supend_active does not need lock as it is used in open/close
- * and suspend context
- */
-static void skl_set_suspend_active(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai, bool enable)
-{
- struct hdac_bus *bus = dev_get_drvdata(dai->dev);
- struct snd_soc_dapm_widget *w;
- struct skl_dev *skl = bus_to_skl(bus);
-
- w = snd_soc_dai_get_widget(dai, substream->stream);
-
- if (w->ignore_suspend && enable)
- skl->supend_active++;
- else if (w->ignore_suspend && !enable)
- skl->supend_active--;
-}
-
-int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params)
-{
- struct hdac_bus *bus = dev_get_drvdata(dev);
- unsigned int format_val;
- struct hdac_stream *hstream;
- struct hdac_ext_stream *stream;
- unsigned int bits;
- int err;
-
- hstream = snd_hdac_get_stream(bus, params->stream,
- params->host_dma_id + 1);
- if (!hstream)
- return -EINVAL;
-
- stream = stream_to_hdac_ext_stream(hstream);
- snd_hdac_ext_stream_decouple(bus, stream, true);
-
- bits = snd_hdac_stream_format_bits(params->format, SNDRV_PCM_SUBFORMAT_STD,
- params->host_bps);
- format_val = snd_hdac_stream_format(params->ch, bits, params->s_freq);
-
- dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
- format_val, params->s_freq, params->ch, params->format);
-
- snd_hdac_stream_reset(hdac_stream(stream));
- err = snd_hdac_stream_set_params(hdac_stream(stream), format_val);
- if (err < 0)
- return err;
-
- err = snd_hdac_ext_host_stream_setup(stream, false);
- if (err < 0)
- return err;
-
- hdac_stream(stream)->prepared = 1;
-
- return 0;
-}
-
-int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params)
-{
- struct hdac_bus *bus = dev_get_drvdata(dev);
- unsigned int format_val;
- struct hdac_stream *hstream;
- struct hdac_ext_stream *stream;
- struct hdac_ext_link *link;
- unsigned char stream_tag;
- unsigned int bits;
-
- hstream = snd_hdac_get_stream(bus, params->stream,
- params->link_dma_id + 1);
- if (!hstream)
- return -EINVAL;
-
- stream = stream_to_hdac_ext_stream(hstream);
- snd_hdac_ext_stream_decouple(bus, stream, true);
-
- bits = snd_hdac_stream_format_bits(params->format, SNDRV_PCM_SUBFORMAT_STD,
- params->link_bps);
- format_val = snd_hdac_stream_format(params->ch, bits, params->s_freq);
-
- dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
- format_val, params->s_freq, params->ch, params->format);
-
- snd_hdac_ext_stream_reset(stream);
-
- snd_hdac_ext_stream_setup(stream, format_val);
-
- stream_tag = hstream->stream_tag;
- if (stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) {
- list_for_each_entry(link, &bus->hlink_list, list) {
- if (link->index == params->link_index)
- snd_hdac_ext_bus_link_set_stream_id(link,
- stream_tag);
- }
- }
-
- stream->link_prepared = 1;
-
- return 0;
-}
-
-static int skl_pcm_open(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct hdac_bus *bus = dev_get_drvdata(dai->dev);
- struct hdac_ext_stream *stream;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct skl_dma_params *dma_params;
- struct skl_dev *skl = get_skl_ctx(dai->dev);
- struct skl_module_cfg *mconfig;
-
- dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
-
- stream = snd_hdac_ext_stream_assign(bus, substream,
- skl_get_host_stream_type(bus));
- if (stream == NULL)
- return -EBUSY;
-
- skl_set_pcm_constrains(bus, runtime);
-
- /*
- * disable WALLCLOCK timestamps for capture streams
- * until we figure out how to handle digital inputs
- */
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK; /* legacy */
- runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_LINK_ATIME;
- }
-
- runtime->private_data = stream;
-
- dma_params = kzalloc(sizeof(*dma_params), GFP_KERNEL);
- if (!dma_params)
- return -ENOMEM;
-
- dma_params->stream_tag = hdac_stream(stream)->stream_tag;
- snd_soc_dai_set_dma_data(dai, substream, dma_params);
-
- dev_dbg(dai->dev, "stream tag set in dma params=%d\n",
- dma_params->stream_tag);
- skl_set_suspend_active(substream, dai, true);
- snd_pcm_set_sync(substream);
-
- mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
- if (!mconfig) {
- kfree(dma_params);
- return -EINVAL;
- }
-
- skl_tplg_d0i3_get(skl, mconfig->d0i3_caps);
-
- return 0;
-}
-
-static int skl_pcm_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct skl_dev *skl = get_skl_ctx(dai->dev);
- struct skl_module_cfg *mconfig;
- int ret;
-
- dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
-
- mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
-
- /*
- * In case of XRUN recovery or in the case when the application
- * calls prepare another time, reset the FW pipe to clean state
- */
- if (mconfig &&
- (substream->runtime->state == SNDRV_PCM_STATE_XRUN ||
- mconfig->pipe->state == SKL_PIPE_CREATED ||
- mconfig->pipe->state == SKL_PIPE_PAUSED)) {
-
- ret = skl_reset_pipe(skl, mconfig->pipe);
-
- if (ret < 0)
- return ret;
-
- ret = skl_pcm_host_dma_prepare(dai->dev,
- mconfig->pipe->p_params);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-static int skl_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct hdac_bus *bus = dev_get_drvdata(dai->dev);
- struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct skl_pipe_params p_params = {0};
- struct skl_module_cfg *m_cfg;
- int ret, dma_id;
-
- dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
- ret = skl_substream_alloc_pages(bus, substream,
- params_buffer_bytes(params));
- if (ret < 0)
- return ret;
-
- dev_dbg(dai->dev, "format_val, rate=%d, ch=%d, format=%d\n",
- runtime->rate, runtime->channels, runtime->format);
-
- dma_id = hdac_stream(stream)->stream_tag - 1;
- dev_dbg(dai->dev, "dma_id=%d\n", dma_id);
-
- p_params.s_fmt = snd_pcm_format_width(params_format(params));
- p_params.s_cont = snd_pcm_format_physical_width(params_format(params));
- p_params.ch = params_channels(params);
- p_params.s_freq = params_rate(params);
- p_params.host_dma_id = dma_id;
- p_params.stream = substream->stream;
- p_params.format = params_format(params);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- p_params.host_bps = dai->driver->playback.sig_bits;
- else
- p_params.host_bps = dai->driver->capture.sig_bits;
-
-
- m_cfg = skl_tplg_fe_get_cpr_module(dai, p_params.stream);
- if (m_cfg)
- skl_tplg_update_pipe_params(dai->dev, m_cfg, &p_params);
-
- return 0;
-}
-
-static void skl_pcm_close(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
- struct hdac_bus *bus = dev_get_drvdata(dai->dev);
- struct skl_dma_params *dma_params = NULL;
- struct skl_dev *skl = bus_to_skl(bus);
- struct skl_module_cfg *mconfig;
-
- dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
-
- snd_hdac_ext_stream_release(stream, skl_get_host_stream_type(bus));
-
- dma_params = snd_soc_dai_get_dma_data(dai, substream);
- /*
- * now we should set this to NULL as we are freeing by the
- * dma_params
- */
- snd_soc_dai_set_dma_data(dai, substream, NULL);
- skl_set_suspend_active(substream, dai, false);
-
- /*
- * check if close is for "Reference Pin" and set back the
- * CGCTL.MISCBDCGE if disabled by driver
- */
- if (!strncmp(dai->name, "Reference Pin", 13) &&
- skl->miscbdcg_disabled) {
- skl->enable_miscbdcge(dai->dev, true);
- skl->miscbdcg_disabled = false;
- }
-
- mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
- if (mconfig)
- skl_tplg_d0i3_put(skl, mconfig->d0i3_caps);
-
- kfree(dma_params);
-}
-
-static int skl_pcm_hw_free(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
- struct skl_dev *skl = get_skl_ctx(dai->dev);
- struct skl_module_cfg *mconfig;
- int ret;
-
- dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
-
- mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
-
- if (mconfig) {
- ret = skl_reset_pipe(skl, mconfig->pipe);
- if (ret < 0)
- dev_err(dai->dev, "%s:Reset failed ret =%d",
- __func__, ret);
- }
-
- snd_hdac_stream_cleanup(hdac_stream(stream));
- hdac_stream(stream)->prepared = 0;
-
- return 0;
-}
-
-static int skl_be_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct skl_pipe_params p_params = {0};
-
- p_params.s_fmt = snd_pcm_format_width(params_format(params));
- p_params.s_cont = snd_pcm_format_physical_width(params_format(params));
- p_params.ch = params_channels(params);
- p_params.s_freq = params_rate(params);
- p_params.stream = substream->stream;
-
- return skl_tplg_be_update_params(dai, &p_params);
-}
-
-static int skl_decoupled_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct hdac_bus *bus = get_bus_ctx(substream);
- struct hdac_ext_stream *stream;
- int start;
- unsigned long cookie;
- struct hdac_stream *hstr;
-
- stream = get_hdac_ext_stream(substream);
- hstr = hdac_stream(stream);
-
- if (!hstr->prepared)
- return -EPIPE;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- start = 1;
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_STOP:
- start = 0;
- break;
-
- default:
- return -EINVAL;
- }
-
- spin_lock_irqsave(&bus->reg_lock, cookie);
-
- if (start) {
- snd_hdac_stream_start(hdac_stream(stream));
- snd_hdac_stream_timecounter_init(hstr, 0);
- } else {
- snd_hdac_stream_stop(hdac_stream(stream));
- }
-
- spin_unlock_irqrestore(&bus->reg_lock, cookie);
-
- return 0;
-}
-
-static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct skl_dev *skl = get_skl_ctx(dai->dev);
- struct skl_module_cfg *mconfig;
- struct hdac_bus *bus = get_bus_ctx(substream);
- struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
- struct hdac_stream *hstream = hdac_stream(stream);
- struct snd_soc_dapm_widget *w;
- int ret;
-
- mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
- if (!mconfig)
- return -EIO;
-
- w = snd_soc_dai_get_widget(dai, substream->stream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_RESUME:
- if (!w->ignore_suspend) {
- /*
- * enable DMA Resume enable bit for the stream, set the
- * dpib & lpib position to resume before starting the
- * DMA
- */
- snd_hdac_stream_drsm_enable(bus, true, hstream->index);
- snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib);
- snd_hdac_stream_set_lpib(hstream, hstream->lpib);
- }
- fallthrough;
-
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- /*
- * Start HOST DMA and Start FE Pipe.This is to make sure that
- * there are no underrun/overrun in the case when the FE
- * pipeline is started but there is a delay in starting the
- * DMA channel on the host.
- */
- ret = skl_decoupled_trigger(substream, cmd);
- if (ret < 0)
- return ret;
- return skl_run_pipe(skl, mconfig->pipe);
-
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_STOP:
- /*
- * Stop FE Pipe first and stop DMA. This is to make sure that
- * there are no underrun/overrun in the case if there is a delay
- * between the two operations.
- */
- ret = skl_stop_pipe(skl, mconfig->pipe);
- if (ret < 0)
- return ret;
-
- ret = skl_decoupled_trigger(substream, cmd);
- if (ret < 0)
- return ret;
-
- if ((cmd == SNDRV_PCM_TRIGGER_SUSPEND) && !w->ignore_suspend) {
- /* save the dpib and lpib positions */
- hstream->dpib = readl(bus->remap_addr +
- AZX_REG_VS_SDXDPIB_XBASE +
- (AZX_REG_VS_SDXDPIB_XINTERVAL *
- hstream->index));
-
- hstream->lpib = snd_hdac_stream_get_pos_lpib(hstream);
-
- snd_hdac_ext_stream_decouple(bus, stream, false);
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-static int skl_link_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct hdac_bus *bus = dev_get_drvdata(dai->dev);
- struct hdac_ext_stream *link_dev;
- 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);
- struct skl_pipe_params p_params = {0};
- struct hdac_ext_link *link;
- int stream_tag;
-
- link_dev = snd_hdac_ext_stream_assign(bus, substream,
- HDAC_EXT_STREAM_TYPE_LINK);
- if (!link_dev)
- return -EBUSY;
-
- snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
-
- link = snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name);
- if (!link)
- return -EINVAL;
-
- stream_tag = hdac_stream(link_dev)->stream_tag;
-
- /* set the hdac_stream in the codec dai */
- snd_soc_dai_set_stream(codec_dai, hdac_stream(link_dev), substream->stream);
-
- p_params.s_fmt = snd_pcm_format_width(params_format(params));
- p_params.s_cont = snd_pcm_format_physical_width(params_format(params));
- p_params.ch = params_channels(params);
- p_params.s_freq = params_rate(params);
- p_params.stream = substream->stream;
- p_params.link_dma_id = stream_tag - 1;
- p_params.link_index = link->index;
- p_params.format = params_format(params);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- p_params.link_bps = codec_dai->driver->playback.sig_bits;
- else
- p_params.link_bps = codec_dai->driver->capture.sig_bits;
-
- return skl_tplg_be_update_params(dai, &p_params);
-}
-
-static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct skl_dev *skl = get_skl_ctx(dai->dev);
- struct skl_module_cfg *mconfig = NULL;
-
- /* In case of XRUN recovery, reset the FW pipe to clean state */
- mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream);
- if (mconfig && !mconfig->pipe->passthru &&
- (substream->runtime->state == SNDRV_PCM_STATE_XRUN))
- skl_reset_pipe(skl, mconfig->pipe);
-
- return 0;
-}
-
-static int skl_link_pcm_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
-{
- struct hdac_ext_stream *link_dev =
- snd_soc_dai_get_dma_data(dai, substream);
- struct hdac_bus *bus = get_bus_ctx(substream);
- struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
-
- dev_dbg(dai->dev, "In %s cmd=%d\n", __func__, cmd);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- snd_hdac_ext_stream_start(link_dev);
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_STOP:
- snd_hdac_ext_stream_clear(link_dev);
- if (cmd == SNDRV_PCM_TRIGGER_SUSPEND)
- snd_hdac_ext_stream_decouple(bus, stream, false);
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int skl_link_hw_free(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct hdac_bus *bus = dev_get_drvdata(dai->dev);
- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct hdac_ext_stream *link_dev =
- snd_soc_dai_get_dma_data(dai, substream);
- struct hdac_ext_link *link;
- unsigned char stream_tag;
-
- dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
-
- link_dev->link_prepared = 0;
-
- link = snd_hdac_ext_bus_get_hlink_by_name(bus, snd_soc_rtd_to_codec(rtd, 0)->component->name);
- if (!link)
- return -EINVAL;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- stream_tag = hdac_stream(link_dev)->stream_tag;
- snd_hdac_ext_bus_link_clear_stream_id(link, stream_tag);
- }
-
- snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK);
- return 0;
-}
-
-static const struct snd_soc_dai_ops skl_pcm_dai_ops = {
- .startup = skl_pcm_open,
- .shutdown = skl_pcm_close,
- .prepare = skl_pcm_prepare,
- .hw_params = skl_pcm_hw_params,
- .hw_free = skl_pcm_hw_free,
- .trigger = skl_pcm_trigger,
-};
-
-static const struct snd_soc_dai_ops skl_dmic_dai_ops = {
- .hw_params = skl_be_hw_params,
-};
-
-static const struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
- .hw_params = skl_be_hw_params,
-};
-
-static const struct snd_soc_dai_ops skl_link_dai_ops = {
- .prepare = skl_link_pcm_prepare,
- .hw_params = skl_link_hw_params,
- .hw_free = skl_link_hw_free,
- .trigger = skl_link_pcm_trigger,
-};
-
-static struct snd_soc_dai_driver skl_fe_dai[] = {
-{
- .name = "System Pin",
- .ops = &skl_pcm_dai_ops,
- .playback = {
- .stream_name = "System Playback",
- .channels_min = HDA_MONO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
- .sig_bits = 32,
- },
- .capture = {
- .stream_name = "System Capture",
- .channels_min = HDA_MONO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
- .sig_bits = 32,
- },
-},
-{
- .name = "System Pin2",
- .ops = &skl_pcm_dai_ops,
- .playback = {
- .stream_name = "Headset Playback",
- .channels_min = HDA_MONO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
- },
-},
-{
- .name = "Echoref Pin",
- .ops = &skl_pcm_dai_ops,
- .capture = {
- .stream_name = "Echoreference Capture",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
- },
-},
-{
- .name = "Reference Pin",
- .ops = &skl_pcm_dai_ops,
- .capture = {
- .stream_name = "Reference Capture",
- .channels_min = HDA_MONO,
- .channels_max = HDA_QUAD,
- .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
- .sig_bits = 32,
- },
-},
-{
- .name = "Deepbuffer Pin",
- .ops = &skl_pcm_dai_ops,
- .playback = {
- .stream_name = "Deepbuffer Playback",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
- .sig_bits = 32,
- },
-},
-{
- .name = "LowLatency Pin",
- .ops = &skl_pcm_dai_ops,
- .playback = {
- .stream_name = "Low Latency Playback",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
- .sig_bits = 32,
- },
-},
-{
- .name = "DMIC Pin",
- .ops = &skl_pcm_dai_ops,
- .capture = {
- .stream_name = "DMIC Capture",
- .channels_min = HDA_MONO,
- .channels_max = HDA_QUAD,
- .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
- .sig_bits = 32,
- },
-},
-{
- .name = "HDMI1 Pin",
- .ops = &skl_pcm_dai_ops,
- .playback = {
- .stream_name = "HDMI1 Playback",
- .channels_min = HDA_STEREO,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
- SNDRV_PCM_RATE_192000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- .sig_bits = 32,
- },
-},
-{
- .name = "HDMI2 Pin",
- .ops = &skl_pcm_dai_ops,
- .playback = {
- .stream_name = "HDMI2 Playback",
- .channels_min = HDA_STEREO,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
- SNDRV_PCM_RATE_192000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- .sig_bits = 32,
- },
-},
-{
- .name = "HDMI3 Pin",
- .ops = &skl_pcm_dai_ops,
- .playback = {
- .stream_name = "HDMI3 Playback",
- .channels_min = HDA_STEREO,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
- SNDRV_PCM_RATE_192000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- .sig_bits = 32,
- },
-},
-};
-
-/* BE CPU Dais */
-static struct snd_soc_dai_driver skl_platform_dai[] = {
-{
- .name = "SSP0 Pin",
- .ops = &skl_be_ssp_dai_ops,
- .playback = {
- .stream_name = "ssp0 Tx",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .stream_name = "ssp0 Rx",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
-},
-{
- .name = "SSP1 Pin",
- .ops = &skl_be_ssp_dai_ops,
- .playback = {
- .stream_name = "ssp1 Tx",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .stream_name = "ssp1 Rx",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
-},
-{
- .name = "SSP2 Pin",
- .ops = &skl_be_ssp_dai_ops,
- .playback = {
- .stream_name = "ssp2 Tx",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .stream_name = "ssp2 Rx",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
-},
-{
- .name = "SSP3 Pin",
- .ops = &skl_be_ssp_dai_ops,
- .playback = {
- .stream_name = "ssp3 Tx",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .stream_name = "ssp3 Rx",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
-},
-{
- .name = "SSP4 Pin",
- .ops = &skl_be_ssp_dai_ops,
- .playback = {
- .stream_name = "ssp4 Tx",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .stream_name = "ssp4 Rx",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
-},
-{
- .name = "SSP5 Pin",
- .ops = &skl_be_ssp_dai_ops,
- .playback = {
- .stream_name = "ssp5 Tx",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .stream_name = "ssp5 Rx",
- .channels_min = HDA_STEREO,
- .channels_max = HDA_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
-},
-{
- .name = "iDisp1 Pin",
- .ops = &skl_link_dai_ops,
- .playback = {
- .stream_name = "iDisp1 Tx",
- .channels_min = HDA_STEREO,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
- },
-},
-{
- .name = "iDisp2 Pin",
- .ops = &skl_link_dai_ops,
- .playback = {
- .stream_name = "iDisp2 Tx",
- .channels_min = HDA_STEREO,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|
- SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
- },
-},
-{
- .name = "iDisp3 Pin",
- .ops = &skl_link_dai_ops,
- .playback = {
- .stream_name = "iDisp3 Tx",
- .channels_min = HDA_STEREO,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|
- SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
- },
-},
-{
- .name = "DMIC01 Pin",
- .ops = &skl_dmic_dai_ops,
- .capture = {
- .stream_name = "DMIC01 Rx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_QUAD,
- .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
- },
-},
-{
- .name = "DMIC16k Pin",
- .ops = &skl_dmic_dai_ops,
- .capture = {
- .stream_name = "DMIC16k Rx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_QUAD,
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
-},
-{
- .name = "Analog CPU DAI",
- .ops = &skl_link_dai_ops,
- .playback = {
- .stream_name = "Analog CPU Playback",
- .channels_min = HDA_MONO,
- .channels_max = HDA_MAX,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
- .capture = {
- .stream_name = "Analog CPU Capture",
- .channels_min = HDA_MONO,
- .channels_max = HDA_MAX,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
-},
-{
- .name = "Alt Analog CPU DAI",
- .ops = &skl_link_dai_ops,
- .playback = {
- .stream_name = "Alt Analog CPU Playback",
- .channels_min = HDA_MONO,
- .channels_max = HDA_MAX,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
- .capture = {
- .stream_name = "Alt Analog CPU Capture",
- .channels_min = HDA_MONO,
- .channels_max = HDA_MAX,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
-},
-{
- .name = "Digital CPU DAI",
- .ops = &skl_link_dai_ops,
- .playback = {
- .stream_name = "Digital CPU Playback",
- .channels_min = HDA_MONO,
- .channels_max = HDA_MAX,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
- .capture = {
- .stream_name = "Digital CPU Capture",
- .channels_min = HDA_MONO,
- .channels_max = HDA_MAX,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
-},
-};
-
-int skl_dai_load(struct snd_soc_component *cmp, int index,
- struct snd_soc_dai_driver *dai_drv,
- struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai)
-{
- dai_drv->ops = &skl_pcm_dai_ops;
-
- return 0;
-}
-
-static int skl_platform_soc_open(struct snd_soc_component *component,
- struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct snd_soc_dai_link *dai_link = rtd->dai_link;
-
- dev_dbg(snd_soc_rtd_to_cpu(rtd, 0)->dev, "In %s:%s\n", __func__,
- dai_link->cpus->dai_name);
-
- snd_soc_set_runtime_hwparams(substream, &azx_pcm_hw);
-
- return 0;
-}
-
-static int skl_coupled_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct hdac_bus *bus = get_bus_ctx(substream);
- struct hdac_ext_stream *stream;
- struct snd_pcm_substream *s;
- bool start;
- int sbits = 0;
- unsigned long cookie;
- struct hdac_stream *hstr;
-
- stream = get_hdac_ext_stream(substream);
- hstr = hdac_stream(stream);
-
- dev_dbg(bus->dev, "In %s cmd=%d\n", __func__, cmd);
-
- if (!hstr->prepared)
- return -EPIPE;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- start = true;
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_STOP:
- start = false;
- break;
-
- default:
- return -EINVAL;
- }
-
- snd_pcm_group_for_each_entry(s, substream) {
- if (s->pcm->card != substream->pcm->card)
- continue;
- stream = get_hdac_ext_stream(s);
- sbits |= 1 << hdac_stream(stream)->index;
- snd_pcm_trigger_done(s, substream);
- }
-
- spin_lock_irqsave(&bus->reg_lock, cookie);
-
- /* first, set SYNC bits of corresponding streams */
- snd_hdac_stream_sync_trigger(hstr, true, sbits, AZX_REG_SSYNC);
-
- snd_pcm_group_for_each_entry(s, substream) {
- if (s->pcm->card != substream->pcm->card)
- continue;
- stream = get_hdac_ext_stream(s);
- if (start)
- snd_hdac_stream_start(hdac_stream(stream));
- else
- snd_hdac_stream_stop(hdac_stream(stream));
- }
- spin_unlock_irqrestore(&bus->reg_lock, cookie);
-
- snd_hdac_stream_sync(hstr, start, sbits);
-
- spin_lock_irqsave(&bus->reg_lock, cookie);
-
- /* reset SYNC bits */
- snd_hdac_stream_sync_trigger(hstr, false, sbits, AZX_REG_SSYNC);
- if (start)
- snd_hdac_stream_timecounter_init(hstr, sbits);
- spin_unlock_irqrestore(&bus->reg_lock, cookie);
-
- return 0;
-}
-
-static int skl_platform_soc_trigger(struct snd_soc_component *component,
- struct snd_pcm_substream *substream,
- int cmd)
-{
- struct hdac_bus *bus = get_bus_ctx(substream);
-
- if (!bus->ppcap)
- return skl_coupled_trigger(substream, cmd);
-
- return 0;
-}
-
-static snd_pcm_uframes_t skl_platform_soc_pointer(
- struct snd_soc_component *component,
- struct snd_pcm_substream *substream)
-{
- struct hdac_ext_stream *hstream = get_hdac_ext_stream(substream);
- struct hdac_bus *bus = get_bus_ctx(substream);
- unsigned int pos;
-
- /*
- * Use DPIB for Playback stream as the periodic DMA Position-in-
- * Buffer Writes may be scheduled at the same time or later than
- * the MSI and does not guarantee to reflect the Position of the
- * last buffer that was transferred. Whereas DPIB register in
- * HAD space reflects the actual data that is transferred.
- * Use the position buffer for capture, as DPIB write gets
- * completed earlier than the actual data written to the DDR.
- *
- * For capture stream following workaround is required to fix the
- * incorrect position reporting.
- *
- * 1. Wait for 20us before reading the DMA position in buffer once
- * the interrupt is generated for stream completion as update happens
- * on the HDA frame boundary i.e. 20.833uSec.
- * 2. Read DPIB register to flush the DMA position value. This dummy
- * read is required to flush DMA position value.
- * 3. Read the DMA Position-in-Buffer. This value now will be equal to
- * or greater than period boundary.
- */
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- pos = readl(bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
- (AZX_REG_VS_SDXDPIB_XINTERVAL *
- hdac_stream(hstream)->index));
- } else {
- udelay(20);
- readl(bus->remap_addr +
- AZX_REG_VS_SDXDPIB_XBASE +
- (AZX_REG_VS_SDXDPIB_XINTERVAL *
- hdac_stream(hstream)->index));
- pos = snd_hdac_stream_get_pos_posbuf(hdac_stream(hstream));
- }
-
- if (pos >= hdac_stream(hstream)->bufsize)
- pos = 0;
-
- return bytes_to_frames(substream->runtime, pos);
-}
-
-static u64 skl_adjust_codec_delay(struct snd_pcm_substream *substream,
- u64 nsec)
-{
- 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);
- u64 codec_frames, codec_nsecs;
-
- if (!codec_dai->driver->ops->delay)
- return nsec;
-
- codec_frames = codec_dai->driver->ops->delay(substream, codec_dai);
- codec_nsecs = div_u64(codec_frames * 1000000000LL,
- substream->runtime->rate);
-
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- return nsec + codec_nsecs;
-
- return (nsec > codec_nsecs) ? nsec - codec_nsecs : 0;
-}
-
-static int skl_platform_soc_get_time_info(
- struct snd_soc_component *component,
- struct snd_pcm_substream *substream,
- struct timespec64 *system_ts, struct timespec64 *audio_ts,
- struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
- struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
-{
- struct hdac_ext_stream *sstream = get_hdac_ext_stream(substream);
- struct hdac_stream *hstr = hdac_stream(sstream);
- u64 nsec;
-
- if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) &&
- (audio_tstamp_config->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK)) {
-
- snd_pcm_gettime(substream->runtime, system_ts);
-
- nsec = timecounter_read(&hstr->tc);
- if (audio_tstamp_config->report_delay)
- nsec = skl_adjust_codec_delay(substream, nsec);
-
- *audio_ts = ns_to_timespec64(nsec);
-
- audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK;
- audio_tstamp_report->accuracy_report = 1; /* rest of struct is valid */
- audio_tstamp_report->accuracy = 42; /* 24MHzWallClk == 42ns resolution */
-
- } else {
- audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT;
- }
-
- return 0;
-}
-
-#define MAX_PREALLOC_SIZE (32 * 1024 * 1024)
-
-static int skl_platform_soc_new(struct snd_soc_component *component,
- struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
- struct hdac_bus *bus = dev_get_drvdata(dai->dev);
- struct snd_pcm *pcm = rtd->pcm;
- unsigned int size;
- struct skl_dev *skl = bus_to_skl(bus);
-
- if (dai->driver->playback.channels_min ||
- dai->driver->capture.channels_min) {
- /* buffer pre-allocation */
- size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
- if (size > MAX_PREALLOC_SIZE)
- size = MAX_PREALLOC_SIZE;
- snd_pcm_set_managed_buffer_all(pcm,
- SNDRV_DMA_TYPE_DEV_SG,
- &skl->pci->dev,
- size, MAX_PREALLOC_SIZE);
- }
-
- return 0;
-}
-
-static int skl_get_module_info(struct skl_dev *skl,
- struct skl_module_cfg *mconfig)
-{
- struct skl_module_inst_id *pin_id;
- guid_t *uuid_mod, *uuid_tplg;
- struct skl_module *skl_module;
- struct uuid_module *module;
- int i, ret = -EIO;
-
- uuid_mod = (guid_t *)mconfig->guid;
-
- if (list_empty(&skl->uuid_list)) {
- dev_err(skl->dev, "Module list is empty\n");
- return -EIO;
- }
-
- for (i = 0; i < skl->nr_modules; i++) {
- skl_module = skl->modules[i];
- uuid_tplg = &skl_module->uuid;
- if (guid_equal(uuid_mod, uuid_tplg)) {
- mconfig->module = skl_module;
- ret = 0;
- break;
- }
- }
-
- if (skl->nr_modules && ret)
- return ret;
-
- ret = -EIO;
- list_for_each_entry(module, &skl->uuid_list, list) {
- if (guid_equal(uuid_mod, &module->uuid)) {
- mconfig->id.module_id = module->id;
- mconfig->module->loadable = module->is_loadable;
- ret = 0;
- }
-
- for (i = 0; i < MAX_IN_QUEUE; i++) {
- pin_id = &mconfig->m_in_pin[i].id;
- if (guid_equal(&pin_id->mod_uuid, &module->uuid))
- pin_id->module_id = module->id;
- }
-
- for (i = 0; i < MAX_OUT_QUEUE; i++) {
- pin_id = &mconfig->m_out_pin[i].id;
- if (guid_equal(&pin_id->mod_uuid, &module->uuid))
- pin_id->module_id = module->id;
- }
- }
-
- return ret;
-}
-
-static int skl_populate_modules(struct skl_dev *skl)
-{
- struct skl_pipeline *p;
- struct skl_pipe_module *m;
- struct snd_soc_dapm_widget *w;
- struct skl_module_cfg *mconfig;
- int ret = 0;
-
- list_for_each_entry(p, &skl->ppl_list, node) {
- list_for_each_entry(m, &p->pipe->w_list, node) {
- w = m->w;
- mconfig = w->priv;
-
- ret = skl_get_module_info(skl, mconfig);
- if (ret < 0) {
- dev_err(skl->dev,
- "query module info failed\n");
- return ret;
- }
-
- skl_tplg_add_moduleid_in_bind_params(skl, w);
- }
- }
-
- return ret;
-}
-
-static int skl_platform_soc_probe(struct snd_soc_component *component)
-{
- struct hdac_bus *bus = dev_get_drvdata(component->dev);
- struct skl_dev *skl = bus_to_skl(bus);
- const struct skl_dsp_ops *ops;
- int ret;
-
- ret = pm_runtime_resume_and_get(component->dev);
- if (ret < 0 && ret != -EACCES)
- return ret;
-
- if (bus->ppcap) {
- skl->component = component;
-
- /* init debugfs */
- skl->debugfs = skl_debugfs_init(skl);
-
- ret = skl_tplg_init(component, bus);
- if (ret < 0) {
- dev_err(component->dev, "Failed to init topology!\n");
- return ret;
- }
-
- /* load the firmwares, since all is set */
- ops = skl_get_dsp_ops(skl->pci->device);
- if (!ops)
- return -EIO;
-
- /*
- * Disable dynamic clock and power gating during firmware
- * and library download
- */
- skl->enable_miscbdcge(component->dev, false);
- skl->clock_power_gating(component->dev, false);
-
- ret = ops->init_fw(component->dev, skl);
- skl->enable_miscbdcge(component->dev, true);
- skl->clock_power_gating(component->dev, true);
- if (ret < 0) {
- dev_err(component->dev, "Failed to boot first fw: %d\n", ret);
- return ret;
- }
- skl_populate_modules(skl);
- skl->update_d0i3c = skl_update_d0i3c;
-
- if (skl->cfg.astate_cfg != NULL) {
- skl_dsp_set_astate_cfg(skl,
- skl->cfg.astate_cfg->count,
- skl->cfg.astate_cfg);
- }
- }
- pm_runtime_mark_last_busy(component->dev);
- pm_runtime_put_autosuspend(component->dev);
-
- return 0;
-}
-
-static void skl_platform_soc_remove(struct snd_soc_component *component)
-{
- struct hdac_bus *bus = dev_get_drvdata(component->dev);
- struct skl_dev *skl = bus_to_skl(bus);
-
- skl_tplg_exit(component, bus);
-
- skl_debugfs_exit(skl);
-}
-
-static const struct snd_soc_component_driver skl_component = {
- .name = "pcm",
- .probe = skl_platform_soc_probe,
- .remove = skl_platform_soc_remove,
- .open = skl_platform_soc_open,
- .trigger = skl_platform_soc_trigger,
- .pointer = skl_platform_soc_pointer,
- .get_time_info = skl_platform_soc_get_time_info,
- .pcm_construct = skl_platform_soc_new,
- .module_get_upon_open = 1, /* increment refcount when a pcm is opened */
-};
-
-int skl_platform_register(struct device *dev)
-{
- int ret;
- struct snd_soc_dai_driver *dais;
- int num_dais = ARRAY_SIZE(skl_platform_dai);
- struct hdac_bus *bus = dev_get_drvdata(dev);
- struct skl_dev *skl = bus_to_skl(bus);
-
- skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai),
- GFP_KERNEL);
- if (!skl->dais) {
- ret = -ENOMEM;
- goto err;
- }
-
- if (!skl->use_tplg_pcm) {
- dais = krealloc(skl->dais, sizeof(skl_fe_dai) +
- sizeof(skl_platform_dai), GFP_KERNEL);
- if (!dais) {
- kfree(skl->dais);
- ret = -ENOMEM;
- goto err;
- }
-
- skl->dais = dais;
- memcpy(&skl->dais[ARRAY_SIZE(skl_platform_dai)], skl_fe_dai,
- sizeof(skl_fe_dai));
- num_dais += ARRAY_SIZE(skl_fe_dai);
- }
-
- ret = devm_snd_soc_register_component(dev, &skl_component,
- skl->dais, num_dais);
- if (ret) {
- kfree(skl->dais);
- dev_err(dev, "soc component registration failed %d\n", ret);
- }
-err:
- return ret;
-}
-
-int skl_platform_unregister(struct device *dev)
-{
- struct hdac_bus *bus = dev_get_drvdata(dev);
- struct skl_dev *skl = bus_to_skl(bus);
- struct skl_module_deferred_bind *modules, *tmp;
-
- list_for_each_entry_safe(modules, tmp, &skl->bind_list, node) {
- list_del(&modules->node);
- kfree(modules);
- }
-
- kfree(skl->dais);
-
- return 0;
-}
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.c b/sound/soc/intel/skylake/skl-ssp-clk.c
deleted file mode 100644
index 50e93c3707e8..000000000000
--- a/sound/soc/intel/skylake/skl-ssp-clk.c
+++ /dev/null
@@ -1,428 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-// Copyright(c) 2015-17 Intel Corporation
-
-/*
- * skl-ssp-clk.c - ASoC skylake ssp clock driver
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/clk-provider.h>
-#include <linux/clkdev.h>
-#include <sound/intel-nhlt.h>
-#include "skl.h"
-#include "skl-ssp-clk.h"
-#include "skl-topology.h"
-
-#define to_skl_clk(_hw) container_of(_hw, struct skl_clk, hw)
-
-struct skl_clk_parent {
- struct clk_hw *hw;
- struct clk_lookup *lookup;
-};
-
-struct skl_clk {
- struct clk_hw hw;
- struct clk_lookup *lookup;
- unsigned long rate;
- struct skl_clk_pdata *pdata;
- u32 id;
-};
-
-struct skl_clk_data {
- struct skl_clk_parent parent[SKL_MAX_CLK_SRC];
- struct skl_clk *clk[SKL_MAX_CLK_CNT];
- u8 avail_clk_cnt;
-};
-
-static int skl_get_clk_type(u32 index)
-{
- switch (index) {
- case 0 ... (SKL_SCLK_OFS - 1):
- return SKL_MCLK;
-
- case SKL_SCLK_OFS ... (SKL_SCLKFS_OFS - 1):
- return SKL_SCLK;
-
- case SKL_SCLKFS_OFS ... (SKL_MAX_CLK_CNT - 1):
- return SKL_SCLK_FS;
-
- default:
- return -EINVAL;
- }
-}
-
-static int skl_get_vbus_id(u32 index, u8 clk_type)
-{
- switch (clk_type) {
- case SKL_MCLK:
- return index;
-
- case SKL_SCLK:
- return index - SKL_SCLK_OFS;
-
- case SKL_SCLK_FS:
- return index - SKL_SCLKFS_OFS;
-
- default:
- return -EINVAL;
- }
-}
-
-static void skl_fill_clk_ipc(struct skl_clk_rate_cfg_table *rcfg, u8 clk_type)
-{
- struct nhlt_fmt_cfg *fmt_cfg;
- union skl_clk_ctrl_ipc *ipc;
- struct wav_fmt *wfmt;
-
- if (!rcfg)
- return;
-
- ipc = &rcfg->dma_ctl_ipc;
- if (clk_type == SKL_SCLK_FS) {
- fmt_cfg = (struct nhlt_fmt_cfg *)rcfg->config;
- wfmt = &fmt_cfg->fmt_ext.fmt;
-
- /* Remove TLV Header size */
- ipc->sclk_fs.hdr.size = sizeof(struct skl_dmactrl_sclkfs_cfg) -
- sizeof(struct skl_tlv_hdr);
- ipc->sclk_fs.sampling_frequency = wfmt->samples_per_sec;
- ipc->sclk_fs.bit_depth = wfmt->bits_per_sample;
- ipc->sclk_fs.valid_bit_depth =
- fmt_cfg->fmt_ext.sample.valid_bits_per_sample;
- ipc->sclk_fs.number_of_channels = wfmt->channels;
- } else {
- ipc->mclk.hdr.type = DMA_CLK_CONTROLS;
- /* Remove TLV Header size */
- ipc->mclk.hdr.size = sizeof(struct skl_dmactrl_mclk_cfg) -
- sizeof(struct skl_tlv_hdr);
- }
-}
-
-/* Sends dma control IPC to turn the clock ON/OFF */
-static int skl_send_clk_dma_control(struct skl_dev *skl,
- struct skl_clk_rate_cfg_table *rcfg,
- u32 vbus_id, u8 clk_type,
- bool enable)
-{
- struct nhlt_specific_cfg *sp_cfg;
- u32 i2s_config_size, node_id = 0;
- struct nhlt_fmt_cfg *fmt_cfg;
- union skl_clk_ctrl_ipc *ipc;
- void *i2s_config = NULL;
- u8 *data, size;
- int ret;
-
- if (!rcfg)
- return -EIO;
-
- ipc = &rcfg->dma_ctl_ipc;
- fmt_cfg = (struct nhlt_fmt_cfg *)rcfg->config;
- sp_cfg = &fmt_cfg->config;
-
- if (clk_type == SKL_SCLK_FS) {
- ipc->sclk_fs.hdr.type =
- enable ? DMA_TRANSMITION_START : DMA_TRANSMITION_STOP;
- data = (u8 *)&ipc->sclk_fs;
- size = sizeof(struct skl_dmactrl_sclkfs_cfg);
- } else {
- /* 1 to enable mclk, 0 to enable sclk */
- if (clk_type == SKL_SCLK)
- ipc->mclk.mclk = 0;
- else
- ipc->mclk.mclk = 1;
-
- ipc->mclk.keep_running = enable;
- ipc->mclk.warm_up_over = enable;
- ipc->mclk.clk_stop_over = !enable;
- data = (u8 *)&ipc->mclk;
- size = sizeof(struct skl_dmactrl_mclk_cfg);
- }
-
- i2s_config_size = sp_cfg->size + size;
- i2s_config = kzalloc(i2s_config_size, GFP_KERNEL);
- if (!i2s_config)
- return -ENOMEM;
-
- /* copy blob */
- memcpy(i2s_config, sp_cfg->caps, sp_cfg->size);
-
- /* copy additional dma controls information */
- memcpy(i2s_config + sp_cfg->size, data, size);
-
- node_id = ((SKL_DMA_I2S_LINK_INPUT_CLASS << 8) | (vbus_id << 4));
- ret = skl_dsp_set_dma_control(skl, (u32 *)i2s_config,
- i2s_config_size, node_id);
- kfree(i2s_config);
-
- return ret;
-}
-
-static struct skl_clk_rate_cfg_table *skl_get_rate_cfg(
- struct skl_clk_rate_cfg_table *rcfg,
- unsigned long rate)
-{
- int i;
-
- for (i = 0; (i < SKL_MAX_CLK_RATES) && rcfg[i].rate; i++) {
- if (rcfg[i].rate == rate)
- return &rcfg[i];
- }
-
- return NULL;
-}
-
-static int skl_clk_change_status(struct skl_clk *clkdev,
- bool enable)
-{
- struct skl_clk_rate_cfg_table *rcfg;
- int vbus_id, clk_type;
-
- clk_type = skl_get_clk_type(clkdev->id);
- if (clk_type < 0)
- return clk_type;
-
- vbus_id = skl_get_vbus_id(clkdev->id, clk_type);
- if (vbus_id < 0)
- return vbus_id;
-
- rcfg = skl_get_rate_cfg(clkdev->pdata->ssp_clks[clkdev->id].rate_cfg,
- clkdev->rate);
- if (!rcfg)
- return -EINVAL;
-
- return skl_send_clk_dma_control(clkdev->pdata->pvt_data, rcfg,
- vbus_id, clk_type, enable);
-}
-
-static int skl_clk_prepare(struct clk_hw *hw)
-{
- struct skl_clk *clkdev = to_skl_clk(hw);
-
- return skl_clk_change_status(clkdev, true);
-}
-
-static void skl_clk_unprepare(struct clk_hw *hw)
-{
- struct skl_clk *clkdev = to_skl_clk(hw);
-
- skl_clk_change_status(clkdev, false);
-}
-
-static int skl_clk_set_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long parent_rate)
-{
- struct skl_clk *clkdev = to_skl_clk(hw);
- struct skl_clk_rate_cfg_table *rcfg;
- int clk_type;
-
- if (!rate)
- return -EINVAL;
-
- rcfg = skl_get_rate_cfg(clkdev->pdata->ssp_clks[clkdev->id].rate_cfg,
- rate);
- if (!rcfg)
- return -EINVAL;
-
- clk_type = skl_get_clk_type(clkdev->id);
- if (clk_type < 0)
- return clk_type;
-
- skl_fill_clk_ipc(rcfg, clk_type);
- clkdev->rate = rate;
-
- return 0;
-}
-
-static unsigned long skl_clk_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
-{
- struct skl_clk *clkdev = to_skl_clk(hw);
-
- if (clkdev->rate)
- return clkdev->rate;
-
- return 0;
-}
-
-/* Not supported by clk driver. Implemented to satisfy clk fw */
-static long skl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
-{
- return rate;
-}
-
-/*
- * prepare/unprepare are used instead of enable/disable as IPC will be sent
- * in non-atomic context.
- */
-static const struct clk_ops skl_clk_ops = {
- .prepare = skl_clk_prepare,
- .unprepare = skl_clk_unprepare,
- .set_rate = skl_clk_set_rate,
- .round_rate = skl_clk_round_rate,
- .recalc_rate = skl_clk_recalc_rate,
-};
-
-static void unregister_parent_src_clk(struct skl_clk_parent *pclk,
- unsigned int id)
-{
- while (id--) {
- clkdev_drop(pclk[id].lookup);
- clk_hw_unregister_fixed_rate(pclk[id].hw);
- }
-}
-
-static void unregister_src_clk(struct skl_clk_data *dclk)
-{
- while (dclk->avail_clk_cnt--)
- clkdev_drop(dclk->clk[dclk->avail_clk_cnt]->lookup);
-}
-
-static int skl_register_parent_clks(struct device *dev,
- struct skl_clk_parent *parent,
- struct skl_clk_parent_src *pclk)
-{
- int i, ret;
-
- for (i = 0; i < SKL_MAX_CLK_SRC; i++) {
-
- /* Register Parent clock */
- parent[i].hw = clk_hw_register_fixed_rate(dev, pclk[i].name,
- pclk[i].parent_name, 0, pclk[i].rate);
- if (IS_ERR(parent[i].hw)) {
- ret = PTR_ERR(parent[i].hw);
- goto err;
- }
-
- parent[i].lookup = clkdev_hw_create(parent[i].hw, pclk[i].name,
- NULL);
- if (!parent[i].lookup) {
- clk_hw_unregister_fixed_rate(parent[i].hw);
- ret = -ENOMEM;
- goto err;
- }
- }
-
- return 0;
-err:
- unregister_parent_src_clk(parent, i);
- return ret;
-}
-
-/* Assign fmt_config to clk_data */
-static struct skl_clk *register_skl_clk(struct device *dev,
- struct skl_ssp_clk *clk,
- struct skl_clk_pdata *clk_pdata, int id)
-{
- struct clk_init_data init;
- struct skl_clk *clkdev;
- int ret;
-
- clkdev = devm_kzalloc(dev, sizeof(*clkdev), GFP_KERNEL);
- if (!clkdev)
- return ERR_PTR(-ENOMEM);
-
- init.name = clk->name;
- init.ops = &skl_clk_ops;
- init.flags = CLK_SET_RATE_GATE;
- init.parent_names = &clk->parent_name;
- init.num_parents = 1;
- clkdev->hw.init = &init;
- clkdev->pdata = clk_pdata;
-
- clkdev->id = id;
- ret = devm_clk_hw_register(dev, &clkdev->hw);
- if (ret) {
- clkdev = ERR_PTR(ret);
- return clkdev;
- }
-
- clkdev->lookup = clkdev_hw_create(&clkdev->hw, init.name, NULL);
- if (!clkdev->lookup)
- clkdev = ERR_PTR(-ENOMEM);
-
- return clkdev;
-}
-
-static int skl_clk_dev_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct device *parent_dev = dev->parent;
- struct skl_clk_parent_src *parent_clks;
- struct skl_clk_pdata *clk_pdata;
- struct skl_clk_data *data;
- struct skl_ssp_clk *clks;
- int ret, i;
-
- clk_pdata = dev_get_platdata(&pdev->dev);
- parent_clks = clk_pdata->parent_clks;
- clks = clk_pdata->ssp_clks;
- if (!parent_clks || !clks)
- return -EIO;
-
- data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- /* Register Parent clock */
- ret = skl_register_parent_clks(parent_dev, data->parent, parent_clks);
- if (ret < 0)
- return ret;
-
- for (i = 0; i < clk_pdata->num_clks; i++) {
- /*
- * Only register valid clocks
- * i.e. for which nhlt entry is present.
- */
- if (clks[i].rate_cfg[0].rate == 0)
- continue;
-
- data->clk[data->avail_clk_cnt] = register_skl_clk(dev,
- &clks[i], clk_pdata, i);
-
- if (IS_ERR(data->clk[data->avail_clk_cnt])) {
- ret = PTR_ERR(data->clk[data->avail_clk_cnt]);
- goto err_unreg_skl_clk;
- }
-
- data->avail_clk_cnt++;
- }
-
- platform_set_drvdata(pdev, data);
-
- return 0;
-
-err_unreg_skl_clk:
- unregister_src_clk(data);
- unregister_parent_src_clk(data->parent, SKL_MAX_CLK_SRC);
-
- return ret;
-}
-
-static void skl_clk_dev_remove(struct platform_device *pdev)
-{
- struct skl_clk_data *data;
-
- data = platform_get_drvdata(pdev);
- unregister_src_clk(data);
- unregister_parent_src_clk(data->parent, SKL_MAX_CLK_SRC);
-}
-
-static struct platform_driver skl_clk_driver = {
- .driver = {
- .name = "skl-ssp-clk",
- },
- .probe = skl_clk_dev_probe,
- .remove_new = skl_clk_dev_remove,
-};
-
-module_platform_driver(skl_clk_driver);
-
-MODULE_DESCRIPTION("Skylake clock driver");
-MODULE_AUTHOR("Jaikrishna Nemallapudi <jaikrishnax.nemallapudi@intel.com>");
-MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:skl-ssp-clk");
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.h b/sound/soc/intel/skylake/skl-ssp-clk.h
deleted file mode 100644
index b7852c7f277b..000000000000
--- a/sound/soc/intel/skylake/skl-ssp-clk.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * skl-ssp-clk.h - Skylake ssp clock information and ipc structure
- *
- * Copyright (C) 2017 Intel Corp
- * Author: Jaikrishna Nemallapudi <jaikrishnax.nemallapudi@intel.com>
- * Author: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#ifndef SOUND_SOC_SKL_SSP_CLK_H
-#define SOUND_SOC_SKL_SSP_CLK_H
-
-#define SKL_MAX_SSP 6
-/* xtal/cardinal/pll, parent of ssp clocks and mclk */
-#define SKL_MAX_CLK_SRC 3
-#define SKL_MAX_SSP_CLK_TYPES 3 /* mclk, sclk, sclkfs */
-
-#define SKL_MAX_CLK_CNT (SKL_MAX_SSP * SKL_MAX_SSP_CLK_TYPES)
-
-/* Max number of configurations supported for each clock */
-#define SKL_MAX_CLK_RATES 10
-
-#define SKL_SCLK_OFS SKL_MAX_SSP
-#define SKL_SCLKFS_OFS (SKL_SCLK_OFS + SKL_MAX_SSP)
-
-enum skl_clk_type {
- SKL_MCLK,
- SKL_SCLK,
- SKL_SCLK_FS,
-};
-
-enum skl_clk_src_type {
- SKL_XTAL,
- SKL_CARDINAL,
- SKL_PLL,
-};
-
-struct skl_clk_parent_src {
- u8 clk_id;
- const char *name;
- unsigned long rate;
- const char *parent_name;
-};
-
-struct skl_tlv_hdr {
- u32 type;
- u32 size;
-};
-
-struct skl_dmactrl_mclk_cfg {
- struct skl_tlv_hdr hdr;
- /* DMA Clk TLV params */
- u32 clk_warm_up:16;
- u32 mclk:1;
- u32 warm_up_over:1;
- u32 rsvd0:14;
- u32 clk_stop_delay:16;
- u32 keep_running:1;
- u32 clk_stop_over:1;
- u32 rsvd1:14;
-};
-
-struct skl_dmactrl_sclkfs_cfg {
- struct skl_tlv_hdr hdr;
- /* DMA SClk&FS TLV params */
- u32 sampling_frequency;
- u32 bit_depth;
- u32 channel_map;
- u32 channel_config;
- u32 interleaving_style;
- u32 number_of_channels : 8;
- u32 valid_bit_depth : 8;
- u32 sample_type : 8;
- u32 reserved : 8;
-};
-
-union skl_clk_ctrl_ipc {
- struct skl_dmactrl_mclk_cfg mclk;
- struct skl_dmactrl_sclkfs_cfg sclk_fs;
-};
-
-struct skl_clk_rate_cfg_table {
- unsigned long rate;
- union skl_clk_ctrl_ipc dma_ctl_ipc;
- void *config;
-};
-
-/*
- * rate for mclk will be in rates[0]. For sclk and sclkfs, rates[] store
- * all possible clocks ssp can generate for that platform.
- */
-struct skl_ssp_clk {
- const char *name;
- const char *parent_name;
- struct skl_clk_rate_cfg_table rate_cfg[SKL_MAX_CLK_RATES];
-};
-
-struct skl_clk_pdata {
- struct skl_clk_parent_src *parent_clks;
- int num_clks;
- struct skl_ssp_clk *ssp_clks;
- void *pvt_data;
-};
-
-#endif /* SOUND_SOC_SKL_SSP_CLK_H */
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.c b/sound/soc/intel/skylake/skl-sst-cldma.c
deleted file mode 100644
index b0204ea00f07..000000000000
--- a/sound/soc/intel/skylake/skl-sst-cldma.c
+++ /dev/null
@@ -1,373 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * skl-sst-cldma.c - Code Loader DMA handler
- *
- * Copyright (C) 2015, Intel Corporation.
- * Author: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <sound/hda_register.h>
-#include "../common/sst-dsp.h"
-#include "../common/sst-dsp-priv.h"
-
-static void skl_cldma_int_enable(struct sst_dsp *ctx)
-{
- sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPIC,
- SKL_ADSPIC_CL_DMA, SKL_ADSPIC_CL_DMA);
-}
-
-void skl_cldma_int_disable(struct sst_dsp *ctx)
-{
- sst_dsp_shim_update_bits_unlocked(ctx,
- SKL_ADSP_REG_ADSPIC, SKL_ADSPIC_CL_DMA, 0);
-}
-
-static void skl_cldma_stream_run(struct sst_dsp *ctx, bool enable)
-{
- unsigned char val;
- int timeout;
-
- sst_dsp_shim_update_bits_unlocked(ctx,
- SKL_ADSP_REG_CL_SD_CTL,
- CL_SD_CTL_RUN_MASK, CL_SD_CTL_RUN(enable));
-
- udelay(3);
- timeout = 300;
- do {
- /* waiting for hardware to report that the stream Run bit set */
- val = sst_dsp_shim_read(ctx, SKL_ADSP_REG_CL_SD_CTL) &
- CL_SD_CTL_RUN_MASK;
- if (enable && val)
- break;
- else if (!enable && !val)
- break;
- udelay(3);
- } while (--timeout);
-
- if (timeout == 0)
- dev_err(ctx->dev, "Failed to set Run bit=%d enable=%d\n", val, enable);
-}
-
-static void skl_cldma_stream_clear(struct sst_dsp *ctx)
-{
- /* make sure Run bit is cleared before setting stream register */
- skl_cldma_stream_run(ctx, 0);
-
- sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
- CL_SD_CTL_IOCE_MASK, CL_SD_CTL_IOCE(0));
- sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
- CL_SD_CTL_FEIE_MASK, CL_SD_CTL_FEIE(0));
- sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
- CL_SD_CTL_DEIE_MASK, CL_SD_CTL_DEIE(0));
- sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
- CL_SD_CTL_STRM_MASK, CL_SD_CTL_STRM(0));
-
- sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPL, CL_SD_BDLPLBA(0));
- sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPU, 0);
-
- sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_CBL, 0);
- sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_LVI, 0);
-}
-
-/* Code loader helper APIs */
-static void skl_cldma_setup_bdle(struct sst_dsp *ctx,
- struct snd_dma_buffer *dmab_data,
- __le32 **bdlp, int size, int with_ioc)
-{
- __le32 *bdl = *bdlp;
- int remaining = ctx->cl_dev.bufsize;
- int offset = 0;
-
- ctx->cl_dev.frags = 0;
- while (remaining > 0) {
- phys_addr_t addr;
- int chunk;
-
- addr = snd_sgbuf_get_addr(dmab_data, offset);
- bdl[0] = cpu_to_le32(lower_32_bits(addr));
- bdl[1] = cpu_to_le32(upper_32_bits(addr));
- chunk = snd_sgbuf_get_chunk_size(dmab_data, offset, size);
- bdl[2] = cpu_to_le32(chunk);
-
- remaining -= chunk;
- bdl[3] = (remaining > 0) ? 0 : cpu_to_le32(0x01);
-
- bdl += 4;
- offset += chunk;
- ctx->cl_dev.frags++;
- }
-}
-
-/*
- * Setup controller
- * Configure the registers to update the dma buffer address and
- * enable interrupts.
- * Note: Using the channel 1 for transfer
- */
-static void skl_cldma_setup_controller(struct sst_dsp *ctx,
- struct snd_dma_buffer *dmab_bdl, unsigned int max_size,
- u32 count)
-{
- skl_cldma_stream_clear(ctx);
- sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPL,
- CL_SD_BDLPLBA(dmab_bdl->addr));
- sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPU,
- CL_SD_BDLPUBA(dmab_bdl->addr));
-
- sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_CBL, max_size);
- sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_LVI, count - 1);
- sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
- CL_SD_CTL_IOCE_MASK, CL_SD_CTL_IOCE(1));
- sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
- CL_SD_CTL_FEIE_MASK, CL_SD_CTL_FEIE(1));
- sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
- CL_SD_CTL_DEIE_MASK, CL_SD_CTL_DEIE(1));
- sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
- CL_SD_CTL_STRM_MASK, CL_SD_CTL_STRM(FW_CL_STREAM_NUMBER));
-}
-
-static void skl_cldma_setup_spb(struct sst_dsp *ctx,
- unsigned int size, bool enable)
-{
- if (enable)
- sst_dsp_shim_update_bits_unlocked(ctx,
- SKL_ADSP_REG_CL_SPBFIFO_SPBFCCTL,
- CL_SPBFIFO_SPBFCCTL_SPIBE_MASK,
- CL_SPBFIFO_SPBFCCTL_SPIBE(1));
-
- sst_dsp_shim_write_unlocked(ctx, SKL_ADSP_REG_CL_SPBFIFO_SPIB, size);
-}
-
-static void skl_cldma_cleanup_spb(struct sst_dsp *ctx)
-{
- sst_dsp_shim_update_bits_unlocked(ctx,
- SKL_ADSP_REG_CL_SPBFIFO_SPBFCCTL,
- CL_SPBFIFO_SPBFCCTL_SPIBE_MASK,
- CL_SPBFIFO_SPBFCCTL_SPIBE(0));
-
- sst_dsp_shim_write_unlocked(ctx, SKL_ADSP_REG_CL_SPBFIFO_SPIB, 0);
-}
-
-static void skl_cldma_cleanup(struct sst_dsp *ctx)
-{
- skl_cldma_cleanup_spb(ctx);
- skl_cldma_stream_clear(ctx);
-
- ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data);
- ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_bdl);
-}
-
-int skl_cldma_wait_interruptible(struct sst_dsp *ctx)
-{
- int ret = 0;
-
- if (!wait_event_timeout(ctx->cl_dev.wait_queue,
- ctx->cl_dev.wait_condition,
- msecs_to_jiffies(SKL_WAIT_TIMEOUT))) {
- dev_err(ctx->dev, "%s: Wait timeout\n", __func__);
- ret = -EIO;
- goto cleanup;
- }
-
- dev_dbg(ctx->dev, "%s: Event wake\n", __func__);
- if (ctx->cl_dev.wake_status != SKL_CL_DMA_BUF_COMPLETE) {
- dev_err(ctx->dev, "%s: DMA Error\n", __func__);
- ret = -EIO;
- }
-
-cleanup:
- ctx->cl_dev.wake_status = SKL_CL_DMA_STATUS_NONE;
- return ret;
-}
-
-static void skl_cldma_stop(struct sst_dsp *ctx)
-{
- skl_cldma_stream_run(ctx, false);
-}
-
-static void skl_cldma_fill_buffer(struct sst_dsp *ctx, unsigned int size,
- const void *curr_pos, bool intr_enable, bool trigger)
-{
- dev_dbg(ctx->dev, "Size: %x, intr_enable: %d\n", size, intr_enable);
- dev_dbg(ctx->dev, "buf_pos_index:%d, trigger:%d\n",
- ctx->cl_dev.dma_buffer_offset, trigger);
- dev_dbg(ctx->dev, "spib position: %d\n", ctx->cl_dev.curr_spib_pos);
-
- /*
- * Check if the size exceeds buffer boundary. If it exceeds
- * max_buffer size, then copy till buffer size and then copy
- * remaining buffer from the start of ring buffer.
- */
- if (ctx->cl_dev.dma_buffer_offset + size > ctx->cl_dev.bufsize) {
- unsigned int size_b = ctx->cl_dev.bufsize -
- ctx->cl_dev.dma_buffer_offset;
- memcpy(ctx->cl_dev.dmab_data.area + ctx->cl_dev.dma_buffer_offset,
- curr_pos, size_b);
- size -= size_b;
- curr_pos += size_b;
- ctx->cl_dev.dma_buffer_offset = 0;
- }
-
- memcpy(ctx->cl_dev.dmab_data.area + ctx->cl_dev.dma_buffer_offset,
- curr_pos, size);
-
- if (ctx->cl_dev.curr_spib_pos == ctx->cl_dev.bufsize)
- ctx->cl_dev.dma_buffer_offset = 0;
- else
- ctx->cl_dev.dma_buffer_offset = ctx->cl_dev.curr_spib_pos;
-
- ctx->cl_dev.wait_condition = false;
-
- if (intr_enable)
- skl_cldma_int_enable(ctx);
-
- ctx->cl_dev.ops.cl_setup_spb(ctx, ctx->cl_dev.curr_spib_pos, trigger);
- if (trigger)
- ctx->cl_dev.ops.cl_trigger(ctx, true);
-}
-
-/*
- * The CL dma doesn't have any way to update the transfer status until a BDL
- * buffer is fully transferred
- *
- * So Copying is divided in two parts.
- * 1. Interrupt on buffer done where the size to be transferred is more than
- * ring buffer size.
- * 2. Polling on fw register to identify if data left to transferred doesn't
- * fill the ring buffer. Caller takes care of polling the required status
- * register to identify the transfer status.
- * 3. if wait flag is set, waits for DBL interrupt to copy the next chunk till
- * bytes_left is 0.
- * if wait flag is not set, doesn't wait for BDL interrupt. after ccopying
- * the first chunk return the no of bytes_left to be copied.
- */
-static int
-skl_cldma_copy_to_buf(struct sst_dsp *ctx, const void *bin,
- u32 total_size, bool wait)
-{
- int ret;
- bool start = true;
- unsigned int excess_bytes;
- u32 size;
- unsigned int bytes_left = total_size;
- const void *curr_pos = bin;
-
- if (total_size <= 0)
- return -EINVAL;
-
- dev_dbg(ctx->dev, "%s: Total binary size: %u\n", __func__, bytes_left);
-
- while (bytes_left) {
- if (bytes_left > ctx->cl_dev.bufsize) {
-
- /*
- * dma transfers only till the write pointer as
- * updated in spib
- */
- if (ctx->cl_dev.curr_spib_pos == 0)
- ctx->cl_dev.curr_spib_pos = ctx->cl_dev.bufsize;
-
- size = ctx->cl_dev.bufsize;
- skl_cldma_fill_buffer(ctx, size, curr_pos, true, start);
-
- if (wait) {
- start = false;
- ret = skl_cldma_wait_interruptible(ctx);
- if (ret < 0) {
- skl_cldma_stop(ctx);
- return ret;
- }
- }
- } else {
- skl_cldma_int_disable(ctx);
-
- if ((ctx->cl_dev.curr_spib_pos + bytes_left)
- <= ctx->cl_dev.bufsize) {
- ctx->cl_dev.curr_spib_pos += bytes_left;
- } else {
- excess_bytes = bytes_left -
- (ctx->cl_dev.bufsize -
- ctx->cl_dev.curr_spib_pos);
- ctx->cl_dev.curr_spib_pos = excess_bytes;
- }
-
- size = bytes_left;
- skl_cldma_fill_buffer(ctx, size,
- curr_pos, false, start);
- }
- bytes_left -= size;
- curr_pos = curr_pos + size;
- if (!wait)
- return bytes_left;
- }
-
- return bytes_left;
-}
-
-void skl_cldma_process_intr(struct sst_dsp *ctx)
-{
- u8 cl_dma_intr_status;
-
- cl_dma_intr_status =
- sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_CL_SD_STS);
-
- if (!(cl_dma_intr_status & SKL_CL_DMA_SD_INT_COMPLETE))
- ctx->cl_dev.wake_status = SKL_CL_DMA_ERR;
- else
- ctx->cl_dev.wake_status = SKL_CL_DMA_BUF_COMPLETE;
-
- ctx->cl_dev.wait_condition = true;
- wake_up(&ctx->cl_dev.wait_queue);
-}
-
-int skl_cldma_prepare(struct sst_dsp *ctx)
-{
- int ret;
- __le32 *bdl;
-
- ctx->cl_dev.bufsize = SKL_MAX_BUFFER_SIZE;
-
- /* Allocate cl ops */
- ctx->cl_dev.ops.cl_setup_bdle = skl_cldma_setup_bdle;
- ctx->cl_dev.ops.cl_setup_controller = skl_cldma_setup_controller;
- ctx->cl_dev.ops.cl_setup_spb = skl_cldma_setup_spb;
- ctx->cl_dev.ops.cl_cleanup_spb = skl_cldma_cleanup_spb;
- ctx->cl_dev.ops.cl_trigger = skl_cldma_stream_run;
- ctx->cl_dev.ops.cl_cleanup_controller = skl_cldma_cleanup;
- ctx->cl_dev.ops.cl_copy_to_dmabuf = skl_cldma_copy_to_buf;
- ctx->cl_dev.ops.cl_stop_dma = skl_cldma_stop;
-
- /* Allocate buffer*/
- ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, ctx->dev, ctx->cl_dev.bufsize,
- &ctx->cl_dev.dmab_data);
- if (ret < 0) {
- dev_err(ctx->dev, "Alloc buffer for base fw failed: %x\n", ret);
- return ret;
- }
-
- /* Setup Code loader BDL */
- ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, ctx->dev, BDL_SIZE, &ctx->cl_dev.dmab_bdl);
- if (ret < 0) {
- dev_err(ctx->dev, "Alloc buffer for blde failed: %x\n", ret);
- ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data);
- return ret;
- }
- bdl = (__le32 *)ctx->cl_dev.dmab_bdl.area;
-
- /* Allocate BDLs */
- ctx->cl_dev.ops.cl_setup_bdle(ctx, &ctx->cl_dev.dmab_data,
- &bdl, ctx->cl_dev.bufsize, 1);
- ctx->cl_dev.ops.cl_setup_controller(ctx, &ctx->cl_dev.dmab_bdl,
- ctx->cl_dev.bufsize, ctx->cl_dev.frags);
-
- ctx->cl_dev.curr_spib_pos = 0;
- ctx->cl_dev.dma_buffer_offset = 0;
- init_waitqueue_head(&ctx->cl_dev.wait_queue);
-
- return ret;
-}
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.h b/sound/soc/intel/skylake/skl-sst-cldma.h
deleted file mode 100644
index d5e285a69baa..000000000000
--- a/sound/soc/intel/skylake/skl-sst-cldma.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Intel Code Loader DMA support
- *
- * Copyright (C) 2015, Intel Corporation.
- */
-
-#ifndef SKL_SST_CLDMA_H_
-#define SKL_SST_CLDMA_H_
-
-#define FW_CL_STREAM_NUMBER 0x1
-
-#define DMA_ADDRESS_128_BITS_ALIGNMENT 7
-#define BDL_ALIGN(x) (x >> DMA_ADDRESS_128_BITS_ALIGNMENT)
-
-#define SKL_ADSPIC_CL_DMA 0x2
-#define SKL_ADSPIS_CL_DMA 0x2
-#define SKL_CL_DMA_SD_INT_DESC_ERR 0x10 /* Descriptor error interrupt */
-#define SKL_CL_DMA_SD_INT_FIFO_ERR 0x08 /* FIFO error interrupt */
-#define SKL_CL_DMA_SD_INT_COMPLETE 0x04 /* Buffer completion interrupt */
-
-/* Intel HD Audio Code Loader DMA Registers */
-
-#define HDA_ADSP_LOADER_BASE 0x80
-
-/* Stream Registers */
-#define SKL_ADSP_REG_CL_SD_CTL (HDA_ADSP_LOADER_BASE + 0x00)
-#define SKL_ADSP_REG_CL_SD_STS (HDA_ADSP_LOADER_BASE + 0x03)
-#define SKL_ADSP_REG_CL_SD_LPIB (HDA_ADSP_LOADER_BASE + 0x04)
-#define SKL_ADSP_REG_CL_SD_CBL (HDA_ADSP_LOADER_BASE + 0x08)
-#define SKL_ADSP_REG_CL_SD_LVI (HDA_ADSP_LOADER_BASE + 0x0c)
-#define SKL_ADSP_REG_CL_SD_FIFOW (HDA_ADSP_LOADER_BASE + 0x0e)
-#define SKL_ADSP_REG_CL_SD_FIFOSIZE (HDA_ADSP_LOADER_BASE + 0x10)
-#define SKL_ADSP_REG_CL_SD_FORMAT (HDA_ADSP_LOADER_BASE + 0x12)
-#define SKL_ADSP_REG_CL_SD_FIFOL (HDA_ADSP_LOADER_BASE + 0x14)
-#define SKL_ADSP_REG_CL_SD_BDLPL (HDA_ADSP_LOADER_BASE + 0x18)
-#define SKL_ADSP_REG_CL_SD_BDLPU (HDA_ADSP_LOADER_BASE + 0x1c)
-
-/* CL: Software Position Based FIFO Capability Registers */
-#define SKL_ADSP_REG_CL_SPBFIFO (HDA_ADSP_LOADER_BASE + 0x20)
-#define SKL_ADSP_REG_CL_SPBFIFO_SPBFCH (SKL_ADSP_REG_CL_SPBFIFO + 0x0)
-#define SKL_ADSP_REG_CL_SPBFIFO_SPBFCCTL (SKL_ADSP_REG_CL_SPBFIFO + 0x4)
-#define SKL_ADSP_REG_CL_SPBFIFO_SPIB (SKL_ADSP_REG_CL_SPBFIFO + 0x8)
-#define SKL_ADSP_REG_CL_SPBFIFO_MAXFIFOS (SKL_ADSP_REG_CL_SPBFIFO + 0xc)
-
-/* CL: Stream Descriptor x Control */
-
-/* Stream Reset */
-#define CL_SD_CTL_SRST_SHIFT 0
-#define CL_SD_CTL_SRST_MASK (1 << CL_SD_CTL_SRST_SHIFT)
-#define CL_SD_CTL_SRST(x) \
- ((x << CL_SD_CTL_SRST_SHIFT) & CL_SD_CTL_SRST_MASK)
-
-/* Stream Run */
-#define CL_SD_CTL_RUN_SHIFT 1
-#define CL_SD_CTL_RUN_MASK (1 << CL_SD_CTL_RUN_SHIFT)
-#define CL_SD_CTL_RUN(x) \
- ((x << CL_SD_CTL_RUN_SHIFT) & CL_SD_CTL_RUN_MASK)
-
-/* Interrupt On Completion Enable */
-#define CL_SD_CTL_IOCE_SHIFT 2
-#define CL_SD_CTL_IOCE_MASK (1 << CL_SD_CTL_IOCE_SHIFT)
-#define CL_SD_CTL_IOCE(x) \
- ((x << CL_SD_CTL_IOCE_SHIFT) & CL_SD_CTL_IOCE_MASK)
-
-/* FIFO Error Interrupt Enable */
-#define CL_SD_CTL_FEIE_SHIFT 3
-#define CL_SD_CTL_FEIE_MASK (1 << CL_SD_CTL_FEIE_SHIFT)
-#define CL_SD_CTL_FEIE(x) \
- ((x << CL_SD_CTL_FEIE_SHIFT) & CL_SD_CTL_FEIE_MASK)
-
-/* Descriptor Error Interrupt Enable */
-#define CL_SD_CTL_DEIE_SHIFT 4
-#define CL_SD_CTL_DEIE_MASK (1 << CL_SD_CTL_DEIE_SHIFT)
-#define CL_SD_CTL_DEIE(x) \
- ((x << CL_SD_CTL_DEIE_SHIFT) & CL_SD_CTL_DEIE_MASK)
-
-/* FIFO Limit Change */
-#define CL_SD_CTL_FIFOLC_SHIFT 5
-#define CL_SD_CTL_FIFOLC_MASK (1 << CL_SD_CTL_FIFOLC_SHIFT)
-#define CL_SD_CTL_FIFOLC(x) \
- ((x << CL_SD_CTL_FIFOLC_SHIFT) & CL_SD_CTL_FIFOLC_MASK)
-
-/* Stripe Control */
-#define CL_SD_CTL_STRIPE_SHIFT 16
-#define CL_SD_CTL_STRIPE_MASK (0x3 << CL_SD_CTL_STRIPE_SHIFT)
-#define CL_SD_CTL_STRIPE(x) \
- ((x << CL_SD_CTL_STRIPE_SHIFT) & CL_SD_CTL_STRIPE_MASK)
-
-/* Traffic Priority */
-#define CL_SD_CTL_TP_SHIFT 18
-#define CL_SD_CTL_TP_MASK (1 << CL_SD_CTL_TP_SHIFT)
-#define CL_SD_CTL_TP(x) \
- ((x << CL_SD_CTL_TP_SHIFT) & CL_SD_CTL_TP_MASK)
-
-/* Bidirectional Direction Control */
-#define CL_SD_CTL_DIR_SHIFT 19
-#define CL_SD_CTL_DIR_MASK (1 << CL_SD_CTL_DIR_SHIFT)
-#define CL_SD_CTL_DIR(x) \
- ((x << CL_SD_CTL_DIR_SHIFT) & CL_SD_CTL_DIR_MASK)
-
-/* Stream Number */
-#define CL_SD_CTL_STRM_SHIFT 20
-#define CL_SD_CTL_STRM_MASK (0xf << CL_SD_CTL_STRM_SHIFT)
-#define CL_SD_CTL_STRM(x) \
- ((x << CL_SD_CTL_STRM_SHIFT) & CL_SD_CTL_STRM_MASK)
-
-/* CL: Stream Descriptor x Status */
-
-/* Buffer Completion Interrupt Status */
-#define CL_SD_STS_BCIS(x) CL_SD_CTL_IOCE(x)
-
-/* FIFO Error */
-#define CL_SD_STS_FIFOE(x) CL_SD_CTL_FEIE(x)
-
-/* Descriptor Error */
-#define CL_SD_STS_DESE(x) CL_SD_CTL_DEIE(x)
-
-/* FIFO Ready */
-#define CL_SD_STS_FIFORDY(x) CL_SD_CTL_FIFOLC(x)
-
-
-/* CL: Stream Descriptor x Last Valid Index */
-#define CL_SD_LVI_SHIFT 0
-#define CL_SD_LVI_MASK (0xff << CL_SD_LVI_SHIFT)
-#define CL_SD_LVI(x) ((x << CL_SD_LVI_SHIFT) & CL_SD_LVI_MASK)
-
-/* CL: Stream Descriptor x FIFO Eviction Watermark */
-#define CL_SD_FIFOW_SHIFT 0
-#define CL_SD_FIFOW_MASK (0x7 << CL_SD_FIFOW_SHIFT)
-#define CL_SD_FIFOW(x) \
- ((x << CL_SD_FIFOW_SHIFT) & CL_SD_FIFOW_MASK)
-
-/* CL: Stream Descriptor x Buffer Descriptor List Pointer Lower Base Address */
-
-/* Protect Bits */
-#define CL_SD_BDLPLBA_PROT_SHIFT 0
-#define CL_SD_BDLPLBA_PROT_MASK (1 << CL_SD_BDLPLBA_PROT_SHIFT)
-#define CL_SD_BDLPLBA_PROT(x) \
- ((x << CL_SD_BDLPLBA_PROT_SHIFT) & CL_SD_BDLPLBA_PROT_MASK)
-
-/* Buffer Descriptor List Lower Base Address */
-#define CL_SD_BDLPLBA_SHIFT 7
-#define CL_SD_BDLPLBA_MASK (0x1ffffff << CL_SD_BDLPLBA_SHIFT)
-#define CL_SD_BDLPLBA(x) \
- ((BDL_ALIGN(lower_32_bits(x)) << CL_SD_BDLPLBA_SHIFT) & CL_SD_BDLPLBA_MASK)
-
-/* Buffer Descriptor List Upper Base Address */
-#define CL_SD_BDLPUBA_SHIFT 0
-#define CL_SD_BDLPUBA_MASK (0xffffffff << CL_SD_BDLPUBA_SHIFT)
-#define CL_SD_BDLPUBA(x) \
- ((upper_32_bits(x) << CL_SD_BDLPUBA_SHIFT) & CL_SD_BDLPUBA_MASK)
-
-/*
- * Code Loader - Software Position Based FIFO
- * Capability Registers x Software Position Based FIFO Header
- */
-
-/* Next Capability Pointer */
-#define CL_SPBFIFO_SPBFCH_PTR_SHIFT 0
-#define CL_SPBFIFO_SPBFCH_PTR_MASK (0xff << CL_SPBFIFO_SPBFCH_PTR_SHIFT)
-#define CL_SPBFIFO_SPBFCH_PTR(x) \
- ((x << CL_SPBFIFO_SPBFCH_PTR_SHIFT) & CL_SPBFIFO_SPBFCH_PTR_MASK)
-
-/* Capability Identifier */
-#define CL_SPBFIFO_SPBFCH_ID_SHIFT 16
-#define CL_SPBFIFO_SPBFCH_ID_MASK (0xfff << CL_SPBFIFO_SPBFCH_ID_SHIFT)
-#define CL_SPBFIFO_SPBFCH_ID(x) \
- ((x << CL_SPBFIFO_SPBFCH_ID_SHIFT) & CL_SPBFIFO_SPBFCH_ID_MASK)
-
-/* Capability Version */
-#define CL_SPBFIFO_SPBFCH_VER_SHIFT 28
-#define CL_SPBFIFO_SPBFCH_VER_MASK (0xf << CL_SPBFIFO_SPBFCH_VER_SHIFT)
-#define CL_SPBFIFO_SPBFCH_VER(x) \
- ((x << CL_SPBFIFO_SPBFCH_VER_SHIFT) & CL_SPBFIFO_SPBFCH_VER_MASK)
-
-/* Software Position in Buffer Enable */
-#define CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT 0
-#define CL_SPBFIFO_SPBFCCTL_SPIBE_MASK (1 << CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT)
-#define CL_SPBFIFO_SPBFCCTL_SPIBE(x) \
- ((x << CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT) & CL_SPBFIFO_SPBFCCTL_SPIBE_MASK)
-
-/* SST IPC SKL defines */
-#define SKL_WAIT_TIMEOUT 500 /* 500 msec */
-#define SKL_MAX_BUFFER_SIZE (32 * PAGE_SIZE)
-
-enum skl_cl_dma_wake_states {
- SKL_CL_DMA_STATUS_NONE = 0,
- SKL_CL_DMA_BUF_COMPLETE,
- SKL_CL_DMA_ERR, /* TODO: Expand the error states */
-};
-
-struct sst_dsp;
-
-struct skl_cl_dev_ops {
- void (*cl_setup_bdle)(struct sst_dsp *ctx,
- struct snd_dma_buffer *dmab_data,
- __le32 **bdlp, int size, int with_ioc);
- void (*cl_setup_controller)(struct sst_dsp *ctx,
- struct snd_dma_buffer *dmab_bdl,
- unsigned int max_size, u32 page_count);
- void (*cl_setup_spb)(struct sst_dsp *ctx,
- unsigned int size, bool enable);
- void (*cl_cleanup_spb)(struct sst_dsp *ctx);
- void (*cl_trigger)(struct sst_dsp *ctx, bool enable);
- void (*cl_cleanup_controller)(struct sst_dsp *ctx);
- int (*cl_copy_to_dmabuf)(struct sst_dsp *ctx,
- const void *bin, u32 size, bool wait);
- void (*cl_stop_dma)(struct sst_dsp *ctx);
-};
-
-/**
- * skl_cl_dev - holds information for code loader dma transfer
- *
- * @dmab_data: buffer pointer
- * @dmab_bdl: buffer descriptor list
- * @bufsize: ring buffer size
- * @frags: Last valid buffer descriptor index in the BDL
- * @curr_spib_pos: Current position in ring buffer
- * @dma_buffer_offset: dma buffer offset
- * @ops: operations supported on CL dma
- * @wait_queue: wait queue to wake for wake event
- * @wake_status: DMA wake status
- * @wait_condition: condition to wait on wait queue
- * @cl_dma_lock: for synchronized access to cldma
- */
-struct skl_cl_dev {
- struct snd_dma_buffer dmab_data;
- struct snd_dma_buffer dmab_bdl;
-
- unsigned int bufsize;
- unsigned int frags;
-
- unsigned int curr_spib_pos;
- unsigned int dma_buffer_offset;
- struct skl_cl_dev_ops ops;
-
- wait_queue_head_t wait_queue;
- int wake_status;
- bool wait_condition;
-};
-
-#endif /* SKL_SST_CLDMA_H_ */
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c
deleted file mode 100644
index 4ae3eae0d1fd..000000000000
--- a/sound/soc/intel/skylake/skl-sst-dsp.c
+++ /dev/null
@@ -1,462 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * skl-sst-dsp.c - SKL SST library generic function
- *
- * Copyright (C) 2014-15, Intel Corporation.
- * Author:Rafal Redzimski <rafal.f.redzimski@intel.com>
- * Jeeja KP <jeeja.kp@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-#include <sound/pcm.h>
-
-#include "../common/sst-dsp.h"
-#include "../common/sst-ipc.h"
-#include "../common/sst-dsp-priv.h"
-#include "skl.h"
-
-/* various timeout values */
-#define SKL_DSP_PU_TO 50
-#define SKL_DSP_PD_TO 50
-#define SKL_DSP_RESET_TO 50
-
-void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state)
-{
- mutex_lock(&ctx->mutex);
- ctx->sst_state = state;
- mutex_unlock(&ctx->mutex);
-}
-
-/*
- * Initialize core power state and usage count. To be called after
- * successful first boot. Hence core 0 will be running and other cores
- * will be reset
- */
-void skl_dsp_init_core_state(struct sst_dsp *ctx)
-{
- struct skl_dev *skl = ctx->thread_context;
- int i;
-
- skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING;
- skl->cores.usage_count[SKL_DSP_CORE0_ID] = 1;
-
- for (i = SKL_DSP_CORE0_ID + 1; i < skl->cores.count; i++) {
- skl->cores.state[i] = SKL_DSP_RESET;
- skl->cores.usage_count[i] = 0;
- }
-}
-
-/* Get the mask for all enabled cores */
-unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx)
-{
- struct skl_dev *skl = ctx->thread_context;
- unsigned int core_mask, en_cores_mask;
- u32 val;
-
- core_mask = SKL_DSP_CORES_MASK(skl->cores.count);
-
- val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS);
-
- /* Cores having CPA bit set */
- en_cores_mask = (val & SKL_ADSPCS_CPA_MASK(core_mask)) >>
- SKL_ADSPCS_CPA_SHIFT;
-
- /* And cores having CRST bit cleared */
- en_cores_mask &= (~val & SKL_ADSPCS_CRST_MASK(core_mask)) >>
- SKL_ADSPCS_CRST_SHIFT;
-
- /* And cores having CSTALL bit cleared */
- en_cores_mask &= (~val & SKL_ADSPCS_CSTALL_MASK(core_mask)) >>
- SKL_ADSPCS_CSTALL_SHIFT;
- en_cores_mask &= core_mask;
-
- dev_dbg(ctx->dev, "DSP enabled cores mask = %x\n", en_cores_mask);
-
- return en_cores_mask;
-}
-
-static int
-skl_dsp_core_set_reset_state(struct sst_dsp *ctx, unsigned int core_mask)
-{
- int ret;
-
- /* update bits */
- sst_dsp_shim_update_bits_unlocked(ctx,
- SKL_ADSP_REG_ADSPCS, SKL_ADSPCS_CRST_MASK(core_mask),
- SKL_ADSPCS_CRST_MASK(core_mask));
-
- /* poll with timeout to check if operation successful */
- ret = sst_dsp_register_poll(ctx,
- SKL_ADSP_REG_ADSPCS,
- SKL_ADSPCS_CRST_MASK(core_mask),
- SKL_ADSPCS_CRST_MASK(core_mask),
- SKL_DSP_RESET_TO,
- "Set reset");
- if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
- SKL_ADSPCS_CRST_MASK(core_mask)) !=
- SKL_ADSPCS_CRST_MASK(core_mask)) {
- dev_err(ctx->dev, "Set reset state failed: core_mask %x\n",
- core_mask);
- ret = -EIO;
- }
-
- return ret;
-}
-
-int skl_dsp_core_unset_reset_state(
- struct sst_dsp *ctx, unsigned int core_mask)
-{
- int ret;
-
- dev_dbg(ctx->dev, "In %s\n", __func__);
-
- /* update bits */
- sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
- SKL_ADSPCS_CRST_MASK(core_mask), 0);
-
- /* poll with timeout to check if operation successful */
- ret = sst_dsp_register_poll(ctx,
- SKL_ADSP_REG_ADSPCS,
- SKL_ADSPCS_CRST_MASK(core_mask),
- 0,
- SKL_DSP_RESET_TO,
- "Unset reset");
-
- if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
- SKL_ADSPCS_CRST_MASK(core_mask)) != 0) {
- dev_err(ctx->dev, "Unset reset state failed: core_mask %x\n",
- core_mask);
- ret = -EIO;
- }
-
- return ret;
-}
-
-static bool
-is_skl_dsp_core_enable(struct sst_dsp *ctx, unsigned int core_mask)
-{
- int val;
- bool is_enable;
-
- val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS);
-
- is_enable = ((val & SKL_ADSPCS_CPA_MASK(core_mask)) &&
- (val & SKL_ADSPCS_SPA_MASK(core_mask)) &&
- !(val & SKL_ADSPCS_CRST_MASK(core_mask)) &&
- !(val & SKL_ADSPCS_CSTALL_MASK(core_mask)));
-
- dev_dbg(ctx->dev, "DSP core(s) enabled? %d : core_mask %x\n",
- is_enable, core_mask);
-
- return is_enable;
-}
-
-static int skl_dsp_reset_core(struct sst_dsp *ctx, unsigned int core_mask)
-{
- /* stall core */
- sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
- SKL_ADSPCS_CSTALL_MASK(core_mask),
- SKL_ADSPCS_CSTALL_MASK(core_mask));
-
- /* set reset state */
- return skl_dsp_core_set_reset_state(ctx, core_mask);
-}
-
-int skl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask)
-{
- int ret;
-
- /* unset reset state */
- ret = skl_dsp_core_unset_reset_state(ctx, core_mask);
- if (ret < 0)
- return ret;
-
- /* run core */
- dev_dbg(ctx->dev, "unstall/run core: core_mask = %x\n", core_mask);
- sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
- SKL_ADSPCS_CSTALL_MASK(core_mask), 0);
-
- if (!is_skl_dsp_core_enable(ctx, core_mask)) {
- skl_dsp_reset_core(ctx, core_mask);
- dev_err(ctx->dev, "DSP start core failed: core_mask %x\n",
- core_mask);
- ret = -EIO;
- }
-
- return ret;
-}
-
-int skl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask)
-{
- int ret;
-
- /* update bits */
- sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
- SKL_ADSPCS_SPA_MASK(core_mask),
- SKL_ADSPCS_SPA_MASK(core_mask));
-
- /* poll with timeout to check if operation successful */
- ret = sst_dsp_register_poll(ctx,
- SKL_ADSP_REG_ADSPCS,
- SKL_ADSPCS_CPA_MASK(core_mask),
- SKL_ADSPCS_CPA_MASK(core_mask),
- SKL_DSP_PU_TO,
- "Power up");
-
- if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
- SKL_ADSPCS_CPA_MASK(core_mask)) !=
- SKL_ADSPCS_CPA_MASK(core_mask)) {
- dev_err(ctx->dev, "DSP core power up failed: core_mask %x\n",
- core_mask);
- ret = -EIO;
- }
-
- return ret;
-}
-
-int skl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask)
-{
- /* update bits */
- sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
- SKL_ADSPCS_SPA_MASK(core_mask), 0);
-
- /* poll with timeout to check if operation successful */
- return sst_dsp_register_poll(ctx,
- SKL_ADSP_REG_ADSPCS,
- SKL_ADSPCS_CPA_MASK(core_mask),
- 0,
- SKL_DSP_PD_TO,
- "Power down");
-}
-
-int skl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask)
-{
- int ret;
-
- /* power up */
- ret = skl_dsp_core_power_up(ctx, core_mask);
- if (ret < 0) {
- dev_err(ctx->dev, "dsp core power up failed: core_mask %x\n",
- core_mask);
- return ret;
- }
-
- return skl_dsp_start_core(ctx, core_mask);
-}
-
-int skl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask)
-{
- int ret;
-
- ret = skl_dsp_reset_core(ctx, core_mask);
- if (ret < 0) {
- dev_err(ctx->dev, "dsp core reset failed: core_mask %x\n",
- core_mask);
- return ret;
- }
-
- /* power down core*/
- ret = skl_dsp_core_power_down(ctx, core_mask);
- if (ret < 0) {
- dev_err(ctx->dev, "dsp core power down fail mask %x: %d\n",
- core_mask, ret);
- return ret;
- }
-
- if (is_skl_dsp_core_enable(ctx, core_mask)) {
- dev_err(ctx->dev, "dsp core disable fail mask %x: %d\n",
- core_mask, ret);
- ret = -EIO;
- }
-
- return ret;
-}
-
-int skl_dsp_boot(struct sst_dsp *ctx)
-{
- int ret;
-
- if (is_skl_dsp_core_enable(ctx, SKL_DSP_CORE0_MASK)) {
- ret = skl_dsp_reset_core(ctx, SKL_DSP_CORE0_MASK);
- if (ret < 0) {
- dev_err(ctx->dev, "dsp core0 reset fail: %d\n", ret);
- return ret;
- }
-
- ret = skl_dsp_start_core(ctx, SKL_DSP_CORE0_MASK);
- if (ret < 0) {
- dev_err(ctx->dev, "dsp core0 start fail: %d\n", ret);
- return ret;
- }
- } else {
- ret = skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
- if (ret < 0) {
- dev_err(ctx->dev, "dsp core0 disable fail: %d\n", ret);
- return ret;
- }
- ret = skl_dsp_enable_core(ctx, SKL_DSP_CORE0_MASK);
- }
-
- return ret;
-}
-
-irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id)
-{
- struct sst_dsp *ctx = dev_id;
- u32 val;
- irqreturn_t result = IRQ_NONE;
-
- spin_lock(&ctx->spinlock);
-
- val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPIS);
- ctx->intr_status = val;
-
- if (val == 0xffffffff) {
- spin_unlock(&ctx->spinlock);
- return IRQ_NONE;
- }
-
- if (val & SKL_ADSPIS_IPC) {
- skl_ipc_int_disable(ctx);
- result = IRQ_WAKE_THREAD;
- }
-
- if (val & SKL_ADSPIS_CL_DMA) {
- skl_cldma_int_disable(ctx);
- result = IRQ_WAKE_THREAD;
- }
-
- spin_unlock(&ctx->spinlock);
-
- return result;
-}
-/*
- * skl_dsp_get_core/skl_dsp_put_core will be called inside DAPM context
- * within the dapm mutex. Hence no separate lock is used.
- */
-int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
-{
- struct skl_dev *skl = ctx->thread_context;
- int ret = 0;
-
- if (core_id >= skl->cores.count) {
- dev_err(ctx->dev, "invalid core id: %d\n", core_id);
- return -EINVAL;
- }
-
- skl->cores.usage_count[core_id]++;
-
- if (skl->cores.state[core_id] == SKL_DSP_RESET) {
- ret = ctx->fw_ops.set_state_D0(ctx, core_id);
- if (ret < 0) {
- dev_err(ctx->dev, "unable to get core%d\n", core_id);
- goto out;
- }
- }
-
-out:
- dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n",
- core_id, skl->cores.state[core_id],
- skl->cores.usage_count[core_id]);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_dsp_get_core);
-
-int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id)
-{
- struct skl_dev *skl = ctx->thread_context;
- int ret = 0;
-
- if (core_id >= skl->cores.count) {
- dev_err(ctx->dev, "invalid core id: %d\n", core_id);
- return -EINVAL;
- }
-
- if ((--skl->cores.usage_count[core_id] == 0) &&
- (skl->cores.state[core_id] != SKL_DSP_RESET)) {
- ret = ctx->fw_ops.set_state_D3(ctx, core_id);
- if (ret < 0) {
- dev_err(ctx->dev, "unable to put core %d: %d\n",
- core_id, ret);
- skl->cores.usage_count[core_id]++;
- }
- }
-
- dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n",
- core_id, skl->cores.state[core_id],
- skl->cores.usage_count[core_id]);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_dsp_put_core);
-
-int skl_dsp_wake(struct sst_dsp *ctx)
-{
- return skl_dsp_get_core(ctx, SKL_DSP_CORE0_ID);
-}
-EXPORT_SYMBOL_GPL(skl_dsp_wake);
-
-int skl_dsp_sleep(struct sst_dsp *ctx)
-{
- return skl_dsp_put_core(ctx, SKL_DSP_CORE0_ID);
-}
-EXPORT_SYMBOL_GPL(skl_dsp_sleep);
-
-struct sst_dsp *skl_dsp_ctx_init(struct device *dev,
- struct sst_dsp_device *sst_dev, int irq)
-{
- int ret;
- struct sst_dsp *sst;
-
- sst = devm_kzalloc(dev, sizeof(*sst), GFP_KERNEL);
- if (sst == NULL)
- return NULL;
-
- spin_lock_init(&sst->spinlock);
- mutex_init(&sst->mutex);
- sst->dev = dev;
- sst->sst_dev = sst_dev;
- sst->irq = irq;
- sst->ops = sst_dev->ops;
- sst->thread_context = sst_dev->thread_context;
-
- /* Initialise SST Audio DSP */
- if (sst->ops->init) {
- ret = sst->ops->init(sst);
- if (ret < 0)
- return NULL;
- }
-
- return sst;
-}
-
-int skl_dsp_acquire_irq(struct sst_dsp *sst)
-{
- struct sst_dsp_device *sst_dev = sst->sst_dev;
- int ret;
-
- /* Register the ISR */
- ret = request_threaded_irq(sst->irq, sst->ops->irq_handler,
- sst_dev->thread, IRQF_SHARED, "AudioDSP", sst);
- if (ret)
- dev_err(sst->dev, "unable to grab threaded IRQ %d, disabling device\n",
- sst->irq);
-
- return ret;
-}
-
-void skl_dsp_free(struct sst_dsp *dsp)
-{
- skl_ipc_int_disable(dsp);
-
- free_irq(dsp->irq, dsp);
- skl_ipc_op_int_disable(dsp);
- skl_dsp_disable_core(dsp, SKL_DSP_CORE0_MASK);
-}
-EXPORT_SYMBOL_GPL(skl_dsp_free);
-
-bool is_skl_dsp_running(struct sst_dsp *ctx)
-{
- return (ctx->sst_state == SKL_DSP_RUNNING);
-}
-EXPORT_SYMBOL_GPL(is_skl_dsp_running);
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
deleted file mode 100644
index 1df9ef422f61..000000000000
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Skylake SST DSP Support
- *
- * Copyright (C) 2014-15, Intel Corporation.
- */
-
-#ifndef __SKL_SST_DSP_H__
-#define __SKL_SST_DSP_H__
-
-#include <linux/interrupt.h>
-#include <linux/uuid.h>
-#include <linux/firmware.h>
-#include <sound/memalloc.h>
-#include "skl-sst-cldma.h"
-
-struct sst_dsp;
-struct sst_dsp_device;
-struct skl_lib_info;
-struct skl_dev;
-
-/* Intel HD Audio General DSP Registers */
-#define SKL_ADSP_GEN_BASE 0x0
-#define SKL_ADSP_REG_ADSPCS (SKL_ADSP_GEN_BASE + 0x04)
-#define SKL_ADSP_REG_ADSPIC (SKL_ADSP_GEN_BASE + 0x08)
-#define SKL_ADSP_REG_ADSPIS (SKL_ADSP_GEN_BASE + 0x0C)
-#define SKL_ADSP_REG_ADSPIC2 (SKL_ADSP_GEN_BASE + 0x10)
-#define SKL_ADSP_REG_ADSPIS2 (SKL_ADSP_GEN_BASE + 0x14)
-
-/* Intel HD Audio Inter-Processor Communication Registers */
-#define SKL_ADSP_IPC_BASE 0x40
-#define SKL_ADSP_REG_HIPCT (SKL_ADSP_IPC_BASE + 0x00)
-#define SKL_ADSP_REG_HIPCTE (SKL_ADSP_IPC_BASE + 0x04)
-#define SKL_ADSP_REG_HIPCI (SKL_ADSP_IPC_BASE + 0x08)
-#define SKL_ADSP_REG_HIPCIE (SKL_ADSP_IPC_BASE + 0x0C)
-#define SKL_ADSP_REG_HIPCCTL (SKL_ADSP_IPC_BASE + 0x10)
-
-/* HIPCI */
-#define SKL_ADSP_REG_HIPCI_BUSY BIT(31)
-
-/* HIPCIE */
-#define SKL_ADSP_REG_HIPCIE_DONE BIT(30)
-
-/* HIPCCTL */
-#define SKL_ADSP_REG_HIPCCTL_DONE BIT(1)
-#define SKL_ADSP_REG_HIPCCTL_BUSY BIT(0)
-
-/* HIPCT */
-#define SKL_ADSP_REG_HIPCT_BUSY BIT(31)
-
-/* FW base IDs */
-#define SKL_INSTANCE_ID 0
-#define SKL_BASE_FW_MODULE_ID 0
-
-/* Intel HD Audio SRAM Window 1 */
-#define SKL_ADSP_SRAM1_BASE 0xA000
-
-#define SKL_ADSP_MMIO_LEN 0x10000
-
-#define SKL_ADSP_W0_STAT_SZ 0x1000
-
-#define SKL_ADSP_W0_UP_SZ 0x1000
-
-#define SKL_ADSP_W1_SZ 0x1000
-
-#define SKL_FW_STS_MASK 0xf
-
-#define SKL_FW_INIT 0x1
-#define SKL_FW_RFW_START 0xf
-#define BXT_FW_ROM_INIT_RETRY 3
-#define BXT_INIT_TIMEOUT 300
-
-#define SKL_ADSPIC_IPC 1
-#define SKL_ADSPIS_IPC 1
-
-/* Core ID of core0 */
-#define SKL_DSP_CORE0_ID 0
-
-/* Mask for a given core index, c = 0.. number of supported cores - 1 */
-#define SKL_DSP_CORE_MASK(c) BIT(c)
-
-/*
- * Core 0 mask = SKL_DSP_CORE_MASK(0); Defined separately
- * since Core0 is primary core and it is used often
- */
-#define SKL_DSP_CORE0_MASK BIT(0)
-
-/*
- * Mask for a given number of cores
- * nc = number of supported cores
- */
-#define SKL_DSP_CORES_MASK(nc) GENMASK((nc - 1), 0)
-
-/* ADSPCS - Audio DSP Control & Status */
-
-/*
- * Core Reset - asserted high
- * CRST Mask for a given core mask pattern, cm
- */
-#define SKL_ADSPCS_CRST_SHIFT 0
-#define SKL_ADSPCS_CRST_MASK(cm) ((cm) << SKL_ADSPCS_CRST_SHIFT)
-
-/*
- * Core run/stall - when set to '1' core is stalled
- * CSTALL Mask for a given core mask pattern, cm
- */
-#define SKL_ADSPCS_CSTALL_SHIFT 8
-#define SKL_ADSPCS_CSTALL_MASK(cm) ((cm) << SKL_ADSPCS_CSTALL_SHIFT)
-
-/*
- * Set Power Active - when set to '1' turn cores on
- * SPA Mask for a given core mask pattern, cm
- */
-#define SKL_ADSPCS_SPA_SHIFT 16
-#define SKL_ADSPCS_SPA_MASK(cm) ((cm) << SKL_ADSPCS_SPA_SHIFT)
-
-/*
- * Current Power Active - power status of cores, set by hardware
- * CPA Mask for a given core mask pattern, cm
- */
-#define SKL_ADSPCS_CPA_SHIFT 24
-#define SKL_ADSPCS_CPA_MASK(cm) ((cm) << SKL_ADSPCS_CPA_SHIFT)
-
-/* DSP Core state */
-enum skl_dsp_states {
- SKL_DSP_RUNNING = 1,
- /* Running in D0i3 state; can be in streaming or non-streaming D0i3 */
- SKL_DSP_RUNNING_D0I3, /* Running in D0i3 state*/
- SKL_DSP_RESET,
-};
-
-/* D0i3 substates */
-enum skl_dsp_d0i3_states {
- SKL_DSP_D0I3_NONE = -1, /* No D0i3 */
- SKL_DSP_D0I3_NON_STREAMING = 0,
- SKL_DSP_D0I3_STREAMING = 1,
-};
-
-struct skl_dsp_fw_ops {
- int (*load_fw)(struct sst_dsp *ctx);
- /* FW module parser/loader */
- int (*load_library)(struct sst_dsp *ctx,
- struct skl_lib_info *linfo, int lib_count);
- int (*parse_fw)(struct sst_dsp *ctx);
- int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id);
- int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id);
- int (*set_state_D0i3)(struct sst_dsp *ctx);
- int (*set_state_D0i0)(struct sst_dsp *ctx);
- unsigned int (*get_fw_errcode)(struct sst_dsp *ctx);
- int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, u8 *mod_name);
- int (*unload_mod)(struct sst_dsp *ctx, u16 mod_id);
-
-};
-
-struct skl_dsp_loader_ops {
- int stream_tag;
-
- int (*alloc_dma_buf)(struct device *dev,
- struct snd_dma_buffer *dmab, size_t size);
- int (*free_dma_buf)(struct device *dev,
- struct snd_dma_buffer *dmab);
- int (*prepare)(struct device *dev, unsigned int format,
- unsigned int byte_size,
- struct snd_dma_buffer *bufp);
- int (*trigger)(struct device *dev, bool start, int stream_tag);
-
- int (*cleanup)(struct device *dev, struct snd_dma_buffer *dmab,
- int stream_tag);
-};
-
-#define MAX_INSTANCE_BUFF 2
-
-struct uuid_module {
- guid_t uuid;
- int id;
- int is_loadable;
- int max_instance;
- u64 pvt_id[MAX_INSTANCE_BUFF];
- int *instance_id;
-
- struct list_head list;
-};
-
-struct skl_load_module_info {
- u16 mod_id;
- const struct firmware *fw;
-};
-
-struct skl_module_table {
- struct skl_load_module_info *mod_info;
- unsigned int usage_cnt;
- struct list_head list;
-};
-
-void skl_cldma_process_intr(struct sst_dsp *ctx);
-void skl_cldma_int_disable(struct sst_dsp *ctx);
-int skl_cldma_prepare(struct sst_dsp *ctx);
-int skl_cldma_wait_interruptible(struct sst_dsp *ctx);
-
-void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state);
-struct sst_dsp *skl_dsp_ctx_init(struct device *dev,
- struct sst_dsp_device *sst_dev, int irq);
-int skl_dsp_acquire_irq(struct sst_dsp *sst);
-bool is_skl_dsp_running(struct sst_dsp *ctx);
-
-unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx);
-void skl_dsp_init_core_state(struct sst_dsp *ctx);
-int skl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask);
-int skl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask);
-int skl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask);
-int skl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask);
-int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx,
- unsigned int core_mask);
-int skl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask);
-
-irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id);
-int skl_dsp_wake(struct sst_dsp *ctx);
-int skl_dsp_sleep(struct sst_dsp *ctx);
-void skl_dsp_free(struct sst_dsp *dsp);
-
-int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id);
-int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id);
-
-int skl_dsp_boot(struct sst_dsp *ctx);
-int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
- const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
- struct skl_dev **dsp);
-int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
- const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
- struct skl_dev **dsp);
-int skl_sst_init_fw(struct device *dev, struct skl_dev *skl);
-int bxt_sst_init_fw(struct device *dev, struct skl_dev *skl);
-void skl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl);
-void bxt_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl);
-
-int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
- unsigned int offset, int index);
-int skl_get_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int instance_id);
-int skl_put_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int *pvt_id);
-int skl_get_pvt_instance_id_map(struct skl_dev *skl,
- int module_id, int instance_id);
-void skl_freeup_uuid_list(struct skl_dev *skl);
-
-int skl_dsp_strip_extended_manifest(struct firmware *fw);
-
-void skl_dsp_set_astate_cfg(struct skl_dev *skl, u32 cnt, void *data);
-
-int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
- struct skl_dsp_loader_ops dsp_ops, struct skl_dev **dsp,
- struct sst_dsp_device *skl_dev);
-int skl_prepare_lib_load(struct skl_dev *skl, struct skl_lib_info *linfo,
- struct firmware *stripped_fw,
- unsigned int hdr_offset, int index);
-void skl_release_library(struct skl_lib_info *linfo, int lib_count);
-
-#endif /*__SKL_SST_DSP_H__*/
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
deleted file mode 100644
index fd9624ad5f72..000000000000
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ /dev/null
@@ -1,1071 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * skl-sst-ipc.c - Intel skl IPC Support
- *
- * Copyright (C) 2014-15, Intel Corporation.
- */
-#include <linux/device.h>
-
-#include "../common/sst-dsp.h"
-#include "../common/sst-dsp-priv.h"
-#include "skl.h"
-#include "skl-sst-dsp.h"
-#include "skl-sst-ipc.h"
-#include "sound/hdaudio_ext.h"
-
-
-#define IPC_IXC_STATUS_BITS 24
-
-/* Global Message - Generic */
-#define IPC_GLB_TYPE_SHIFT 24
-#define IPC_GLB_TYPE_MASK (0xf << IPC_GLB_TYPE_SHIFT)
-#define IPC_GLB_TYPE(x) ((x) << IPC_GLB_TYPE_SHIFT)
-
-/* Global Message - Reply */
-#define IPC_GLB_REPLY_STATUS_SHIFT 24
-#define IPC_GLB_REPLY_STATUS_MASK ((0x1 << IPC_GLB_REPLY_STATUS_SHIFT) - 1)
-#define IPC_GLB_REPLY_STATUS(x) ((x) << IPC_GLB_REPLY_STATUS_SHIFT)
-
-#define IPC_GLB_REPLY_TYPE_SHIFT 29
-#define IPC_GLB_REPLY_TYPE_MASK 0x1F
-#define IPC_GLB_REPLY_TYPE(x) (((x) >> IPC_GLB_REPLY_TYPE_SHIFT) \
- & IPC_GLB_RPLY_TYPE_MASK)
-
-#define IPC_TIMEOUT_MSECS 3000
-
-#define IPC_EMPTY_LIST_SIZE 8
-
-#define IPC_MSG_TARGET_SHIFT 30
-#define IPC_MSG_TARGET_MASK 0x1
-#define IPC_MSG_TARGET(x) (((x) & IPC_MSG_TARGET_MASK) \
- << IPC_MSG_TARGET_SHIFT)
-
-#define IPC_MSG_DIR_SHIFT 29
-#define IPC_MSG_DIR_MASK 0x1
-#define IPC_MSG_DIR(x) (((x) & IPC_MSG_DIR_MASK) \
- << IPC_MSG_DIR_SHIFT)
-/* Global Notification Message */
-#define IPC_GLB_NOTIFY_TYPE_SHIFT 16
-#define IPC_GLB_NOTIFY_TYPE_MASK 0xFF
-#define IPC_GLB_NOTIFY_TYPE(x) (((x) >> IPC_GLB_NOTIFY_TYPE_SHIFT) \
- & IPC_GLB_NOTIFY_TYPE_MASK)
-
-#define IPC_GLB_NOTIFY_MSG_TYPE_SHIFT 24
-#define IPC_GLB_NOTIFY_MSG_TYPE_MASK 0x1F
-#define IPC_GLB_NOTIFY_MSG_TYPE(x) (((x) >> IPC_GLB_NOTIFY_MSG_TYPE_SHIFT) \
- & IPC_GLB_NOTIFY_MSG_TYPE_MASK)
-
-#define IPC_GLB_NOTIFY_RSP_SHIFT 29
-#define IPC_GLB_NOTIFY_RSP_MASK 0x1
-#define IPC_GLB_NOTIFY_RSP_TYPE(x) (((x) >> IPC_GLB_NOTIFY_RSP_SHIFT) \
- & IPC_GLB_NOTIFY_RSP_MASK)
-
-/* Pipeline operations */
-
-/* Create pipeline message */
-#define IPC_PPL_MEM_SIZE_SHIFT 0
-#define IPC_PPL_MEM_SIZE_MASK 0x7FF
-#define IPC_PPL_MEM_SIZE(x) (((x) & IPC_PPL_MEM_SIZE_MASK) \
- << IPC_PPL_MEM_SIZE_SHIFT)
-
-#define IPC_PPL_TYPE_SHIFT 11
-#define IPC_PPL_TYPE_MASK 0x1F
-#define IPC_PPL_TYPE(x) (((x) & IPC_PPL_TYPE_MASK) \
- << IPC_PPL_TYPE_SHIFT)
-
-#define IPC_INSTANCE_ID_SHIFT 16
-#define IPC_INSTANCE_ID_MASK 0xFF
-#define IPC_INSTANCE_ID(x) (((x) & IPC_INSTANCE_ID_MASK) \
- << IPC_INSTANCE_ID_SHIFT)
-
-#define IPC_PPL_LP_MODE_SHIFT 0
-#define IPC_PPL_LP_MODE_MASK 0x1
-#define IPC_PPL_LP_MODE(x) (((x) & IPC_PPL_LP_MODE_MASK) \
- << IPC_PPL_LP_MODE_SHIFT)
-
-/* Set pipeline state message */
-#define IPC_PPL_STATE_SHIFT 0
-#define IPC_PPL_STATE_MASK 0x1F
-#define IPC_PPL_STATE(x) (((x) & IPC_PPL_STATE_MASK) \
- << IPC_PPL_STATE_SHIFT)
-
-/* Module operations primary register */
-#define IPC_MOD_ID_SHIFT 0
-#define IPC_MOD_ID_MASK 0xFFFF
-#define IPC_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \
- << IPC_MOD_ID_SHIFT)
-
-#define IPC_MOD_INSTANCE_ID_SHIFT 16
-#define IPC_MOD_INSTANCE_ID_MASK 0xFF
-#define IPC_MOD_INSTANCE_ID(x) (((x) & IPC_MOD_INSTANCE_ID_MASK) \
- << IPC_MOD_INSTANCE_ID_SHIFT)
-
-/* Init instance message extension register */
-#define IPC_PARAM_BLOCK_SIZE_SHIFT 0
-#define IPC_PARAM_BLOCK_SIZE_MASK 0xFFFF
-#define IPC_PARAM_BLOCK_SIZE(x) (((x) & IPC_PARAM_BLOCK_SIZE_MASK) \
- << IPC_PARAM_BLOCK_SIZE_SHIFT)
-
-#define IPC_PPL_INSTANCE_ID_SHIFT 16
-#define IPC_PPL_INSTANCE_ID_MASK 0xFF
-#define IPC_PPL_INSTANCE_ID(x) (((x) & IPC_PPL_INSTANCE_ID_MASK) \
- << IPC_PPL_INSTANCE_ID_SHIFT)
-
-#define IPC_CORE_ID_SHIFT 24
-#define IPC_CORE_ID_MASK 0x1F
-#define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \
- << IPC_CORE_ID_SHIFT)
-
-#define IPC_DOMAIN_SHIFT 28
-#define IPC_DOMAIN_MASK 0x1
-#define IPC_DOMAIN(x) (((x) & IPC_DOMAIN_MASK) \
- << IPC_DOMAIN_SHIFT)
-
-/* Bind/Unbind message extension register */
-#define IPC_DST_MOD_ID_SHIFT 0
-#define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \
- << IPC_DST_MOD_ID_SHIFT)
-
-#define IPC_DST_MOD_INSTANCE_ID_SHIFT 16
-#define IPC_DST_MOD_INSTANCE_ID(x) (((x) & IPC_MOD_INSTANCE_ID_MASK) \
- << IPC_DST_MOD_INSTANCE_ID_SHIFT)
-
-#define IPC_DST_QUEUE_SHIFT 24
-#define IPC_DST_QUEUE_MASK 0x7
-#define IPC_DST_QUEUE(x) (((x) & IPC_DST_QUEUE_MASK) \
- << IPC_DST_QUEUE_SHIFT)
-
-#define IPC_SRC_QUEUE_SHIFT 27
-#define IPC_SRC_QUEUE_MASK 0x7
-#define IPC_SRC_QUEUE(x) (((x) & IPC_SRC_QUEUE_MASK) \
- << IPC_SRC_QUEUE_SHIFT)
-/* Load Module count */
-#define IPC_LOAD_MODULE_SHIFT 0
-#define IPC_LOAD_MODULE_MASK 0xFF
-#define IPC_LOAD_MODULE_CNT(x) (((x) & IPC_LOAD_MODULE_MASK) \
- << IPC_LOAD_MODULE_SHIFT)
-
-/* Save pipeline messgae extension register */
-#define IPC_DMA_ID_SHIFT 0
-#define IPC_DMA_ID_MASK 0x1F
-#define IPC_DMA_ID(x) (((x) & IPC_DMA_ID_MASK) \
- << IPC_DMA_ID_SHIFT)
-/* Large Config message extension register */
-#define IPC_DATA_OFFSET_SZ_SHIFT 0
-#define IPC_DATA_OFFSET_SZ_MASK 0xFFFFF
-#define IPC_DATA_OFFSET_SZ(x) (((x) & IPC_DATA_OFFSET_SZ_MASK) \
- << IPC_DATA_OFFSET_SZ_SHIFT)
-#define IPC_DATA_OFFSET_SZ_CLEAR ~(IPC_DATA_OFFSET_SZ_MASK \
- << IPC_DATA_OFFSET_SZ_SHIFT)
-
-#define IPC_LARGE_PARAM_ID_SHIFT 20
-#define IPC_LARGE_PARAM_ID_MASK 0xFF
-#define IPC_LARGE_PARAM_ID(x) (((x) & IPC_LARGE_PARAM_ID_MASK) \
- << IPC_LARGE_PARAM_ID_SHIFT)
-
-#define IPC_FINAL_BLOCK_SHIFT 28
-#define IPC_FINAL_BLOCK_MASK 0x1
-#define IPC_FINAL_BLOCK(x) (((x) & IPC_FINAL_BLOCK_MASK) \
- << IPC_FINAL_BLOCK_SHIFT)
-
-#define IPC_INITIAL_BLOCK_SHIFT 29
-#define IPC_INITIAL_BLOCK_MASK 0x1
-#define IPC_INITIAL_BLOCK(x) (((x) & IPC_INITIAL_BLOCK_MASK) \
- << IPC_INITIAL_BLOCK_SHIFT)
-#define IPC_INITIAL_BLOCK_CLEAR ~(IPC_INITIAL_BLOCK_MASK \
- << IPC_INITIAL_BLOCK_SHIFT)
-/* Set D0ix IPC extension register */
-#define IPC_D0IX_WAKE_SHIFT 0
-#define IPC_D0IX_WAKE_MASK 0x1
-#define IPC_D0IX_WAKE(x) (((x) & IPC_D0IX_WAKE_MASK) \
- << IPC_D0IX_WAKE_SHIFT)
-
-#define IPC_D0IX_STREAMING_SHIFT 1
-#define IPC_D0IX_STREAMING_MASK 0x1
-#define IPC_D0IX_STREAMING(x) (((x) & IPC_D0IX_STREAMING_MASK) \
- << IPC_D0IX_STREAMING_SHIFT)
-
-
-enum skl_ipc_msg_target {
- IPC_FW_GEN_MSG = 0,
- IPC_MOD_MSG = 1
-};
-
-enum skl_ipc_msg_direction {
- IPC_MSG_REQUEST = 0,
- IPC_MSG_REPLY = 1
-};
-
-/* Global Message Types */
-enum skl_ipc_glb_type {
- IPC_GLB_GET_FW_VERSION = 0, /* Retrieves firmware version */
- IPC_GLB_LOAD_MULTIPLE_MODS = 15,
- IPC_GLB_UNLOAD_MULTIPLE_MODS = 16,
- IPC_GLB_CREATE_PPL = 17,
- IPC_GLB_DELETE_PPL = 18,
- IPC_GLB_SET_PPL_STATE = 19,
- IPC_GLB_GET_PPL_STATE = 20,
- IPC_GLB_GET_PPL_CONTEXT_SIZE = 21,
- IPC_GLB_SAVE_PPL = 22,
- IPC_GLB_RESTORE_PPL = 23,
- IPC_GLB_LOAD_LIBRARY = 24,
- IPC_GLB_NOTIFY = 26,
- IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */
-};
-
-enum skl_ipc_glb_reply {
- IPC_GLB_REPLY_SUCCESS = 0,
-
- IPC_GLB_REPLY_UNKNOWN_MSG_TYPE = 1,
- IPC_GLB_REPLY_ERROR_INVALID_PARAM = 2,
-
- IPC_GLB_REPLY_BUSY = 3,
- IPC_GLB_REPLY_PENDING = 4,
- IPC_GLB_REPLY_FAILURE = 5,
- IPC_GLB_REPLY_INVALID_REQUEST = 6,
-
- IPC_GLB_REPLY_OUT_OF_MEMORY = 7,
- IPC_GLB_REPLY_OUT_OF_MIPS = 8,
-
- IPC_GLB_REPLY_INVALID_RESOURCE_ID = 9,
- IPC_GLB_REPLY_INVALID_RESOURCE_STATE = 10,
-
- IPC_GLB_REPLY_MOD_MGMT_ERROR = 100,
- IPC_GLB_REPLY_MOD_LOAD_CL_FAILED = 101,
- IPC_GLB_REPLY_MOD_LOAD_INVALID_HASH = 102,
-
- IPC_GLB_REPLY_MOD_UNLOAD_INST_EXIST = 103,
- IPC_GLB_REPLY_MOD_NOT_INITIALIZED = 104,
-
- IPC_GLB_REPLY_INVALID_CONFIG_PARAM_ID = 120,
- IPC_GLB_REPLY_INVALID_CONFIG_DATA_LEN = 121,
- IPC_GLB_REPLY_GATEWAY_NOT_INITIALIZED = 140,
- IPC_GLB_REPLY_GATEWAY_NOT_EXIST = 141,
- IPC_GLB_REPLY_SCLK_ALREADY_RUNNING = 150,
- IPC_GLB_REPLY_MCLK_ALREADY_RUNNING = 151,
-
- IPC_GLB_REPLY_PPL_NOT_INITIALIZED = 160,
- IPC_GLB_REPLY_PPL_NOT_EXIST = 161,
- IPC_GLB_REPLY_PPL_SAVE_FAILED = 162,
- IPC_GLB_REPLY_PPL_RESTORE_FAILED = 163,
-
- IPC_MAX_STATUS = ((1<<IPC_IXC_STATUS_BITS)-1)
-};
-
-enum skl_ipc_notification_type {
- IPC_GLB_NOTIFY_GLITCH = 0,
- IPC_GLB_NOTIFY_OVERRUN = 1,
- IPC_GLB_NOTIFY_UNDERRUN = 2,
- IPC_GLB_NOTIFY_END_STREAM = 3,
- IPC_GLB_NOTIFY_PHRASE_DETECTED = 4,
- IPC_GLB_NOTIFY_RESOURCE_EVENT = 5,
- IPC_GLB_NOTIFY_LOG_BUFFER_STATUS = 6,
- IPC_GLB_NOTIFY_TIMESTAMP_CAPTURED = 7,
- IPC_GLB_NOTIFY_FW_READY = 8
-};
-
-/* Module Message Types */
-enum skl_ipc_module_msg {
- IPC_MOD_INIT_INSTANCE = 0,
- IPC_MOD_CONFIG_GET = 1,
- IPC_MOD_CONFIG_SET = 2,
- IPC_MOD_LARGE_CONFIG_GET = 3,
- IPC_MOD_LARGE_CONFIG_SET = 4,
- IPC_MOD_BIND = 5,
- IPC_MOD_UNBIND = 6,
- IPC_MOD_SET_DX = 7,
- IPC_MOD_SET_D0IX = 8
-};
-
-void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data,
- size_t tx_size)
-{
- if (tx_size)
- memcpy(msg->tx.data, tx_data, tx_size);
-}
-
-static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp)
-{
- u32 hipci;
-
- hipci = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCI);
- return (hipci & SKL_ADSP_REG_HIPCI_BUSY);
-}
-
-/* Lock to be held by caller */
-static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
-{
- struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header);
-
- if (msg->tx.size)
- sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
- sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE,
- header->extension);
- sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI,
- header->primary | SKL_ADSP_REG_HIPCI_BUSY);
-}
-
-int skl_ipc_check_D0i0(struct sst_dsp *dsp, bool state)
-{
- int ret;
-
- /* check D0i3 support */
- if (!dsp->fw_ops.set_state_D0i0)
- return 0;
-
- /* Attempt D0i0 or D0i3 based on state */
- if (state)
- ret = dsp->fw_ops.set_state_D0i0(dsp);
- else
- ret = dsp->fw_ops.set_state_D0i3(dsp);
-
- return ret;
-}
-
-static struct ipc_message *skl_ipc_reply_get_msg(struct sst_generic_ipc *ipc,
- u64 ipc_header)
-{
- struct ipc_message *msg = NULL;
- struct skl_ipc_header *header = (struct skl_ipc_header *)(&ipc_header);
-
- if (list_empty(&ipc->rx_list)) {
- dev_err(ipc->dev, "ipc: rx list is empty but received 0x%x\n",
- header->primary);
- goto out;
- }
-
- msg = list_first_entry(&ipc->rx_list, struct ipc_message, list);
-
- list_del(&msg->list);
-out:
- return msg;
-
-}
-
-int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
- struct skl_ipc_header header)
-{
- struct skl_dev *skl = container_of(ipc, struct skl_dev, ipc);
-
- if (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
- switch (IPC_GLB_NOTIFY_TYPE(header.primary)) {
-
- case IPC_GLB_NOTIFY_UNDERRUN:
- dev_err(ipc->dev, "FW Underrun %x\n", header.primary);
- break;
-
- case IPC_GLB_NOTIFY_RESOURCE_EVENT:
- dev_err(ipc->dev, "MCPS Budget Violation: %x\n",
- header.primary);
- break;
-
- case IPC_GLB_NOTIFY_FW_READY:
- skl->boot_complete = true;
- wake_up(&skl->boot_wait);
- break;
-
- case IPC_GLB_NOTIFY_PHRASE_DETECTED:
- dev_dbg(ipc->dev, "***** Phrase Detected **********\n");
-
- /*
- * Per HW recomendation, After phrase detection,
- * clear the CGCTL.MISCBDCGE.
- *
- * This will be set back on stream closure
- */
- skl->enable_miscbdcge(ipc->dev, false);
- skl->miscbdcg_disabled = true;
- break;
-
- default:
- dev_err(ipc->dev, "ipc: Unhandled error msg=%x\n",
- header.primary);
- break;
- }
- }
-
- return 0;
-}
-
-struct skl_ipc_err_map {
- const char *msg;
- enum skl_ipc_glb_reply reply;
- int err;
-};
-
-static struct skl_ipc_err_map skl_err_map[] = {
- {"DSP out of memory", IPC_GLB_REPLY_OUT_OF_MEMORY, -ENOMEM},
- {"DSP busy", IPC_GLB_REPLY_BUSY, -EBUSY},
- {"SCLK already running", IPC_GLB_REPLY_SCLK_ALREADY_RUNNING,
- IPC_GLB_REPLY_SCLK_ALREADY_RUNNING},
- {"MCLK already running", IPC_GLB_REPLY_MCLK_ALREADY_RUNNING,
- IPC_GLB_REPLY_MCLK_ALREADY_RUNNING},
-};
-
-static int skl_ipc_set_reply_error_code(struct sst_generic_ipc *ipc, u32 reply)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(skl_err_map); i++) {
- if (skl_err_map[i].reply == reply)
- break;
- }
-
- if (i == ARRAY_SIZE(skl_err_map)) {
- dev_err(ipc->dev, "ipc FW reply: %d FW Error Code: %u\n",
- reply,
- ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
- return -EINVAL;
- }
-
- if (skl_err_map[i].err < 0)
- dev_err(ipc->dev, "ipc FW reply: %s FW Error Code: %u\n",
- skl_err_map[i].msg,
- ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
- else
- dev_info(ipc->dev, "ipc FW reply: %s FW Error Code: %u\n",
- skl_err_map[i].msg,
- ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
-
- return skl_err_map[i].err;
-}
-
-void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
- struct skl_ipc_header header)
-{
- struct ipc_message *msg;
- u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK;
- u64 *ipc_header = (u64 *)(&header);
- struct skl_dev *skl = container_of(ipc, struct skl_dev, ipc);
- unsigned long flags;
-
- spin_lock_irqsave(&ipc->dsp->spinlock, flags);
- msg = skl_ipc_reply_get_msg(ipc, *ipc_header);
- spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
- if (msg == NULL) {
- dev_dbg(ipc->dev, "ipc: rx list is empty\n");
- return;
- }
-
- msg->rx.header = *ipc_header;
- /* first process the header */
- if (reply == IPC_GLB_REPLY_SUCCESS) {
- dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary);
- /* copy the rx data from the mailbox */
- sst_dsp_inbox_read(ipc->dsp, msg->rx.data, msg->rx.size);
- switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
- case IPC_GLB_LOAD_MULTIPLE_MODS:
- case IPC_GLB_LOAD_LIBRARY:
- skl->mod_load_complete = true;
- skl->mod_load_status = true;
- wake_up(&skl->mod_load_wait);
- break;
-
- default:
- break;
-
- }
- } else {
- msg->errno = skl_ipc_set_reply_error_code(ipc, reply);
- switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
- case IPC_GLB_LOAD_MULTIPLE_MODS:
- case IPC_GLB_LOAD_LIBRARY:
- skl->mod_load_complete = true;
- skl->mod_load_status = false;
- wake_up(&skl->mod_load_wait);
- break;
-
- default:
- break;
-
- }
- }
-
- spin_lock_irqsave(&ipc->dsp->spinlock, flags);
- sst_ipc_tx_msg_reply_complete(ipc, msg);
- spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
-}
-
-irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
-{
- struct sst_dsp *dsp = context;
- struct skl_dev *skl = dsp->thread_context;
- struct sst_generic_ipc *ipc = &skl->ipc;
- struct skl_ipc_header header = {0};
- u32 hipcie, hipct, hipcte;
- int ipc_irq = 0;
-
- if (dsp->intr_status & SKL_ADSPIS_CL_DMA)
- skl_cldma_process_intr(dsp);
-
- /* Here we handle IPC interrupts only */
- if (!(dsp->intr_status & SKL_ADSPIS_IPC))
- return IRQ_NONE;
-
- hipcie = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCIE);
- hipct = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCT);
- hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE);
-
- /* reply message from DSP */
- if (hipcie & SKL_ADSP_REG_HIPCIE_DONE) {
- sst_dsp_shim_update_bits(dsp, SKL_ADSP_REG_HIPCCTL,
- SKL_ADSP_REG_HIPCCTL_DONE, 0);
-
- /* clear DONE bit - tell DSP we have completed the operation */
- sst_dsp_shim_update_bits_forced(dsp, SKL_ADSP_REG_HIPCIE,
- SKL_ADSP_REG_HIPCIE_DONE, SKL_ADSP_REG_HIPCIE_DONE);
-
- ipc_irq = 1;
-
- /* unmask Done interrupt */
- sst_dsp_shim_update_bits(dsp, SKL_ADSP_REG_HIPCCTL,
- SKL_ADSP_REG_HIPCCTL_DONE, SKL_ADSP_REG_HIPCCTL_DONE);
- }
-
- /* New message from DSP */
- if (hipct & SKL_ADSP_REG_HIPCT_BUSY) {
- header.primary = hipct;
- header.extension = hipcte;
- dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x\n",
- header.primary);
- dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x\n",
- header.extension);
-
- if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) {
- /* Handle Immediate reply from DSP Core */
- skl_ipc_process_reply(ipc, header);
- } else {
- dev_dbg(dsp->dev, "IPC irq: Notification from firmware\n");
- skl_ipc_process_notification(ipc, header);
- }
- /* clear busy interrupt */
- sst_dsp_shim_update_bits_forced(dsp, SKL_ADSP_REG_HIPCT,
- SKL_ADSP_REG_HIPCT_BUSY, SKL_ADSP_REG_HIPCT_BUSY);
- ipc_irq = 1;
- }
-
- if (ipc_irq == 0)
- return IRQ_NONE;
-
- skl_ipc_int_enable(dsp);
-
- /* continue to send any remaining messages... */
- schedule_work(&ipc->kwork);
-
- return IRQ_HANDLED;
-}
-
-void skl_ipc_int_enable(struct sst_dsp *ctx)
-{
- sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_ADSPIC,
- SKL_ADSPIC_IPC, SKL_ADSPIC_IPC);
-}
-
-void skl_ipc_int_disable(struct sst_dsp *ctx)
-{
- sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPIC,
- SKL_ADSPIC_IPC, 0);
-}
-
-void skl_ipc_op_int_enable(struct sst_dsp *ctx)
-{
- /* enable IPC DONE interrupt */
- sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_HIPCCTL,
- SKL_ADSP_REG_HIPCCTL_DONE, SKL_ADSP_REG_HIPCCTL_DONE);
-
- /* Enable IPC BUSY interrupt */
- sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_HIPCCTL,
- SKL_ADSP_REG_HIPCCTL_BUSY, SKL_ADSP_REG_HIPCCTL_BUSY);
-}
-
-void skl_ipc_op_int_disable(struct sst_dsp *ctx)
-{
- /* disable IPC DONE interrupt */
- sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
- SKL_ADSP_REG_HIPCCTL_DONE, 0);
-
- /* Disable IPC BUSY interrupt */
- sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
- SKL_ADSP_REG_HIPCCTL_BUSY, 0);
-
-}
-
-bool skl_ipc_int_status(struct sst_dsp *ctx)
-{
- return sst_dsp_shim_read_unlocked(ctx,
- SKL_ADSP_REG_ADSPIS) & SKL_ADSPIS_IPC;
-}
-
-int skl_ipc_init(struct device *dev, struct skl_dev *skl)
-{
- struct sst_generic_ipc *ipc;
- int err;
-
- ipc = &skl->ipc;
- ipc->dsp = skl->dsp;
- ipc->dev = dev;
-
- ipc->tx_data_max_size = SKL_ADSP_W1_SZ;
- ipc->rx_data_max_size = SKL_ADSP_W0_UP_SZ;
-
- err = sst_ipc_init(ipc);
- if (err)
- return err;
-
- ipc->ops.tx_msg = skl_ipc_tx_msg;
- ipc->ops.tx_data_copy = skl_ipc_tx_data_copy;
- ipc->ops.is_dsp_busy = skl_ipc_is_dsp_busy;
-
- return 0;
-}
-
-void skl_ipc_free(struct sst_generic_ipc *ipc)
-{
- /* Disable IPC DONE interrupt */
- sst_dsp_shim_update_bits(ipc->dsp, SKL_ADSP_REG_HIPCCTL,
- SKL_ADSP_REG_HIPCCTL_DONE, 0);
-
- /* Disable IPC BUSY interrupt */
- sst_dsp_shim_update_bits(ipc->dsp, SKL_ADSP_REG_HIPCCTL,
- SKL_ADSP_REG_HIPCCTL_BUSY, 0);
-
- sst_ipc_fini(ipc);
-}
-
-int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
- u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request = {0};
- int ret;
-
- header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_GLB_CREATE_PPL);
- header.primary |= IPC_INSTANCE_ID(instance_id);
- header.primary |= IPC_PPL_TYPE(ppl_type);
- header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size);
-
- header.extension = IPC_PPL_LP_MODE(lp_mode);
- request.header = *(u64 *)(&header);
-
- dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
- ret = sst_ipc_tx_message_wait(ipc, request, NULL);
- if (ret < 0) {
- dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret);
- return ret;
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_create_pipeline);
-
-int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request = {0};
- int ret;
-
- header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL);
- header.primary |= IPC_INSTANCE_ID(instance_id);
- request.header = *(u64 *)(&header);
-
- dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
- ret = sst_ipc_tx_message_wait(ipc, request, NULL);
- if (ret < 0) {
- dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_delete_pipeline);
-
-int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc,
- u8 instance_id, enum skl_ipc_pipeline_state state)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request = {0};
- int ret;
-
- header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE);
- header.primary |= IPC_INSTANCE_ID(instance_id);
- header.primary |= IPC_PPL_STATE(state);
- request.header = *(u64 *)(&header);
-
- dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
- ret = sst_ipc_tx_message_wait(ipc, request, NULL);
- if (ret < 0) {
- dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret);
- return ret;
- }
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_set_pipeline_state);
-
-int
-skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request = {0};
- int ret;
-
- header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_GLB_SAVE_PPL);
- header.primary |= IPC_INSTANCE_ID(instance_id);
-
- header.extension = IPC_DMA_ID(dma_id);
- request.header = *(u64 *)(&header);
-
- dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
- ret = sst_ipc_tx_message_wait(ipc, request, NULL);
- if (ret < 0) {
- dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret);
- return ret;
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_save_pipeline);
-
-int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request = {0};
- int ret;
-
- header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL);
- header.primary |= IPC_INSTANCE_ID(instance_id);
- request.header = *(u64 *)(&header);
-
- dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
- ret = sst_ipc_tx_message_wait(ipc, request, NULL);
- if (ret < 0) {
- dev_err(ipc->dev, "ipc: restore pipeline failed, err: %d\n", ret);
- return ret;
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_restore_pipeline);
-
-int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id,
- u16 module_id, struct skl_ipc_dxstate_info *dx)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request;
- int ret;
-
- header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_MOD_SET_DX);
- header.primary |= IPC_MOD_INSTANCE_ID(instance_id);
- header.primary |= IPC_MOD_ID(module_id);
-
- request.header = *(u64 *)(&header);
- request.data = dx;
- request.size = sizeof(*dx);
-
- dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
- header.primary, header.extension);
- ret = sst_ipc_tx_message_wait(ipc, request, NULL);
- if (ret < 0) {
- dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret);
- return ret;
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_set_dx);
-
-int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
- struct skl_ipc_init_instance_msg *msg, void *param_data)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request;
- int ret;
- u32 *buffer = (u32 *)param_data;
- /* param_block_size must be in dwords */
- u16 param_block_size = msg->param_data_size / sizeof(u32);
-
- print_hex_dump_debug("Param data:", DUMP_PREFIX_NONE,
- 16, 4, buffer, param_block_size, false);
-
- header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_MOD_INIT_INSTANCE);
- header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
- header.primary |= IPC_MOD_ID(msg->module_id);
-
- header.extension = IPC_CORE_ID(msg->core_id);
- header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id);
- header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
- header.extension |= IPC_DOMAIN(msg->domain);
-
- request.header = *(u64 *)(&header);
- request.data = param_data;
- request.size = msg->param_data_size;
-
- dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
- header.primary, header.extension);
- ret = sst_ipc_tx_message_wait(ipc, request, NULL);
-
- if (ret < 0) {
- dev_err(ipc->dev, "ipc: init instance failed\n");
- return ret;
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_init_instance);
-
-int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
- struct skl_ipc_bind_unbind_msg *msg)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request = {0};
- u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND;
- int ret;
-
- header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(bind_unbind);
- header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
- header.primary |= IPC_MOD_ID(msg->module_id);
-
- header.extension = IPC_DST_MOD_ID(msg->dst_module_id);
- header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id);
- header.extension |= IPC_DST_QUEUE(msg->dst_queue);
- header.extension |= IPC_SRC_QUEUE(msg->src_queue);
- request.header = *(u64 *)(&header);
-
- dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary,
- header.extension);
- ret = sst_ipc_tx_message_wait(ipc, request, NULL);
- if (ret < 0) {
- dev_err(ipc->dev, "ipc: bind/unbind failed\n");
- return ret;
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_bind_unbind);
-
-/*
- * In order to load a module we need to send IPC to initiate that. DMA will
- * performed to load the module memory. The FW supports multiple module load
- * at single shot, so we can send IPC with N modules represented by
- * module_cnt
- */
-int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
- u8 module_cnt, void *data)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request;
- int ret;
-
- header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS);
- header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
-
- request.header = *(u64 *)(&header);
- request.data = data;
- request.size = sizeof(u16) * module_cnt;
-
- ret = sst_ipc_tx_message_nowait(ipc, request);
- if (ret < 0)
- dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_load_modules);
-
-int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt,
- void *data)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request;
- int ret;
-
- header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS);
- header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
-
- request.header = *(u64 *)(&header);
- request.data = data;
- request.size = sizeof(u16) * module_cnt;
-
- ret = sst_ipc_tx_message_wait(ipc, request, NULL);
- if (ret < 0)
- dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_unload_modules);
-
-int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
- struct skl_ipc_large_config_msg *msg, u32 *param)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request;
- int ret = 0;
- size_t sz_remaining, tx_size, data_offset;
-
- header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_MOD_LARGE_CONFIG_SET);
- header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
- header.primary |= IPC_MOD_ID(msg->module_id);
-
- header.extension = IPC_DATA_OFFSET_SZ(msg->param_data_size);
- header.extension |= IPC_LARGE_PARAM_ID(msg->large_param_id);
- header.extension |= IPC_FINAL_BLOCK(0);
- header.extension |= IPC_INITIAL_BLOCK(1);
-
- sz_remaining = msg->param_data_size;
- data_offset = 0;
- while (sz_remaining != 0) {
- tx_size = sz_remaining > SKL_ADSP_W1_SZ
- ? SKL_ADSP_W1_SZ : sz_remaining;
- if (tx_size == sz_remaining)
- header.extension |= IPC_FINAL_BLOCK(1);
-
- dev_dbg(ipc->dev, "In %s primary=%#x ext=%#x\n", __func__,
- header.primary, header.extension);
- dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n",
- (unsigned)data_offset, (unsigned)tx_size);
-
- request.header = *(u64 *)(&header);
- request.data = ((char *)param) + data_offset;
- request.size = tx_size;
- ret = sst_ipc_tx_message_wait(ipc, request, NULL);
- if (ret < 0) {
- dev_err(ipc->dev,
- "ipc: set large config fail, err: %d\n", ret);
- return ret;
- }
- sz_remaining -= tx_size;
- data_offset = msg->param_data_size - sz_remaining;
-
- /* clear the fields */
- header.extension &= IPC_INITIAL_BLOCK_CLEAR;
- header.extension &= IPC_DATA_OFFSET_SZ_CLEAR;
- /* fill the fields */
- header.extension |= IPC_INITIAL_BLOCK(0);
- header.extension |= IPC_DATA_OFFSET_SZ(data_offset);
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_set_large_config);
-
-int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
- struct skl_ipc_large_config_msg *msg,
- u32 **payload, size_t *bytes)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request, reply = {0};
- unsigned int *buf;
- int ret;
-
- reply.data = kzalloc(SKL_ADSP_W1_SZ, GFP_KERNEL);
- if (!reply.data)
- return -ENOMEM;
-
- header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_MOD_LARGE_CONFIG_GET);
- header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
- header.primary |= IPC_MOD_ID(msg->module_id);
-
- header.extension = IPC_DATA_OFFSET_SZ(msg->param_data_size);
- header.extension |= IPC_LARGE_PARAM_ID(msg->large_param_id);
- header.extension |= IPC_FINAL_BLOCK(1);
- header.extension |= IPC_INITIAL_BLOCK(1);
-
- request.header = *(u64 *)&header;
- request.data = *payload;
- request.size = *bytes;
- reply.size = SKL_ADSP_W1_SZ;
-
- ret = sst_ipc_tx_message_wait(ipc, request, &reply);
- if (ret < 0)
- dev_err(ipc->dev, "ipc: get large config fail, err: %d\n", ret);
-
- reply.size = (reply.header >> 32) & IPC_DATA_OFFSET_SZ_MASK;
- buf = krealloc(reply.data, reply.size, GFP_KERNEL);
- if (!buf) {
- kfree(reply.data);
- return -ENOMEM;
- }
- *payload = buf;
- *bytes = reply.size;
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
-
-int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
- u8 dma_id, u8 table_id, bool wait)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request = {0};
- int ret = 0;
-
- header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
- header.primary |= IPC_MOD_INSTANCE_ID(table_id);
- header.primary |= IPC_MOD_ID(dma_id);
- request.header = *(u64 *)(&header);
-
- if (wait)
- ret = sst_ipc_tx_message_wait(ipc, request, NULL);
- else
- ret = sst_ipc_tx_message_nowait(ipc, request);
-
- if (ret < 0)
- dev_err(ipc->dev, "ipc: load lib failed\n");
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library);
-
-int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
-{
- struct skl_ipc_header header = {0};
- struct sst_ipc_message request = {0};
- int ret;
-
- header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
- header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
- header.primary |= IPC_GLB_TYPE(IPC_MOD_SET_D0IX);
- header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
- header.primary |= IPC_MOD_ID(msg->module_id);
-
- header.extension = IPC_D0IX_WAKE(msg->wake);
- header.extension |= IPC_D0IX_STREAMING(msg->streaming);
- request.header = *(u64 *)(&header);
-
- dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__,
- header.primary, header.extension);
-
- /*
- * Use the nopm IPC here as we dont want it checking for D0iX
- */
- ret = sst_ipc_tx_message_nopm(ipc, request, NULL);
- if (ret < 0)
- dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(skl_ipc_set_d0ix);
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
deleted file mode 100644
index aaaab3b3ec42..000000000000
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Intel SKL IPC Support
- *
- * Copyright (C) 2014-15, Intel Corporation.
- */
-
-#ifndef __SKL_IPC_H
-#define __SKL_IPC_H
-
-#include <linux/irqreturn.h>
-#include "../common/sst-ipc.h"
-#include "skl-sst-dsp.h"
-
-struct sst_dsp;
-struct sst_generic_ipc;
-
-enum skl_ipc_pipeline_state {
- PPL_INVALID_STATE = 0,
- PPL_UNINITIALIZED = 1,
- PPL_RESET = 2,
- PPL_PAUSED = 3,
- PPL_RUNNING = 4,
- PPL_ERROR_STOP = 5,
- PPL_SAVED = 6,
- PPL_RESTORED = 7
-};
-
-struct skl_ipc_dxstate_info {
- u32 core_mask;
- u32 dx_mask;
-};
-
-struct skl_ipc_header {
- u32 primary;
- u32 extension;
-};
-
-struct skl_dsp_cores {
- unsigned int count;
- enum skl_dsp_states *state;
- int *usage_count;
-};
-
-/**
- * skl_d0i3_data: skl D0i3 counters data struct
- *
- * @streaming: Count of usecases that can attempt streaming D0i3
- * @non_streaming: Count of usecases that can attempt non-streaming D0i3
- * @non_d0i3: Count of usecases that cannot attempt D0i3
- * @state: current state
- * @work: D0i3 worker thread
- */
-struct skl_d0i3_data {
- int streaming;
- int non_streaming;
- int non_d0i3;
- enum skl_dsp_d0i3_states state;
- struct delayed_work work;
-};
-
-#define SKL_LIB_NAME_LENGTH 128
-#define SKL_MAX_LIB 16
-
-struct skl_lib_info {
- char name[SKL_LIB_NAME_LENGTH];
- const struct firmware *fw;
-};
-
-struct skl_ipc_init_instance_msg {
- u32 module_id;
- u32 instance_id;
- u16 param_data_size;
- u8 ppl_instance_id;
- u8 core_id;
- u8 domain;
-};
-
-struct skl_ipc_bind_unbind_msg {
- u32 module_id;
- u32 instance_id;
- u32 dst_module_id;
- u32 dst_instance_id;
- u8 src_queue;
- u8 dst_queue;
- bool bind;
-};
-
-struct skl_ipc_large_config_msg {
- u32 module_id;
- u32 instance_id;
- u32 large_param_id;
- u32 param_data_size;
-};
-
-struct skl_ipc_d0ix_msg {
- u32 module_id;
- u32 instance_id;
- u8 streaming;
- u8 wake;
-};
-
-#define SKL_IPC_BOOT_MSECS 3000
-
-#define SKL_IPC_D3_MASK 0
-#define SKL_IPC_D0_MASK 3
-
-irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context);
-
-int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
- u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode);
-
-int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id);
-
-int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc,
- u8 instance_id, enum skl_ipc_pipeline_state state);
-
-int skl_ipc_save_pipeline(struct sst_generic_ipc *ipc,
- u8 instance_id, int dma_id);
-
-int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id);
-
-int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
- struct skl_ipc_init_instance_msg *msg, void *param_data);
-
-int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
- struct skl_ipc_bind_unbind_msg *msg);
-
-int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
- u8 module_cnt, void *data);
-
-int skl_ipc_unload_modules(struct sst_generic_ipc *ipc,
- u8 module_cnt, void *data);
-
-int skl_ipc_set_dx(struct sst_generic_ipc *ipc,
- u8 instance_id, u16 module_id, struct skl_ipc_dxstate_info *dx);
-
-int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
- struct skl_ipc_large_config_msg *msg, u32 *param);
-
-int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
- struct skl_ipc_large_config_msg *msg,
- u32 **payload, size_t *bytes);
-
-int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
- u8 dma_id, u8 table_id, bool wait);
-
-int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc,
- struct skl_ipc_d0ix_msg *msg);
-
-int skl_ipc_check_D0i0(struct sst_dsp *dsp, bool state);
-
-void skl_ipc_int_enable(struct sst_dsp *ctx);
-void skl_ipc_op_int_enable(struct sst_dsp *ctx);
-void skl_ipc_op_int_disable(struct sst_dsp *ctx);
-void skl_ipc_int_disable(struct sst_dsp *ctx);
-
-bool skl_ipc_int_status(struct sst_dsp *ctx);
-void skl_ipc_free(struct sst_generic_ipc *ipc);
-int skl_ipc_init(struct device *dev, struct skl_dev *skl);
-void skl_clear_module_cnt(struct sst_dsp *ctx);
-
-void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
- struct skl_ipc_header header);
-int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
- struct skl_ipc_header header);
-void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data,
- size_t tx_size);
-#endif /* __SKL_IPC_H */
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
deleted file mode 100644
index b776c58dcf47..000000000000
--- a/sound/soc/intel/skylake/skl-sst-utils.c
+++ /dev/null
@@ -1,425 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * skl-sst-utils.c - SKL sst utils functions
- *
- * Copyright (C) 2016 Intel Corp
- */
-
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/uuid.h>
-#include "../common/sst-dsp.h"
-#include "../common/sst-dsp-priv.h"
-#include "skl.h"
-
-#define DEFAULT_HASH_SHA256_LEN 32
-
-/* FW Extended Manifest Header id = $AE1 */
-#define SKL_EXT_MANIFEST_HEADER_MAGIC 0x31454124
-
-union seg_flags {
- u32 ul;
- struct {
- u32 contents : 1;
- u32 alloc : 1;
- u32 load : 1;
- u32 read_only : 1;
- u32 code : 1;
- u32 data : 1;
- u32 _rsvd0 : 2;
- u32 type : 4;
- u32 _rsvd1 : 4;
- u32 length : 16;
- } r;
-} __packed;
-
-struct segment_desc {
- union seg_flags flags;
- u32 v_base_addr;
- u32 file_offset;
-};
-
-struct module_type {
- u32 load_type : 4;
- u32 auto_start : 1;
- u32 domain_ll : 1;
- u32 domain_dp : 1;
- u32 rsvd : 25;
-} __packed;
-
-struct adsp_module_entry {
- u32 struct_id;
- u8 name[8];
- u8 uuid[16];
- struct module_type type;
- u8 hash1[DEFAULT_HASH_SHA256_LEN];
- u32 entry_point;
- u16 cfg_offset;
- u16 cfg_count;
- u32 affinity_mask;
- u16 instance_max_count;
- u16 instance_bss_size;
- struct segment_desc segments[3];
-} __packed;
-
-struct adsp_fw_hdr {
- u32 id;
- u32 len;
- u8 name[8];
- u32 preload_page_count;
- u32 fw_image_flags;
- u32 feature_mask;
- u16 major;
- u16 minor;
- u16 hotfix;
- u16 build;
- u32 num_modules;
- u32 hw_buf_base;
- u32 hw_buf_length;
- u32 load_offset;
-} __packed;
-
-struct skl_ext_manifest_hdr {
- u32 id;
- u32 len;
- u16 version_major;
- u16 version_minor;
- u32 entries;
-};
-
-static int skl_get_pvtid_map(struct uuid_module *module, int instance_id)
-{
- int pvt_id;
-
- for (pvt_id = 0; pvt_id < module->max_instance; pvt_id++) {
- if (module->instance_id[pvt_id] == instance_id)
- return pvt_id;
- }
- return -EINVAL;
-}
-
-int skl_get_pvt_instance_id_map(struct skl_dev *skl,
- int module_id, int instance_id)
-{
- struct uuid_module *module;
-
- list_for_each_entry(module, &skl->uuid_list, list) {
- if (module->id == module_id)
- return skl_get_pvtid_map(module, instance_id);
- }
-
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(skl_get_pvt_instance_id_map);
-
-static inline int skl_getid_32(struct uuid_module *module, u64 *val,
- int word1_mask, int word2_mask)
-{
- int index, max_inst, pvt_id;
- u32 mask_val;
-
- max_inst = module->max_instance;
- mask_val = (u32)(*val >> word1_mask);
-
- if (mask_val != 0xffffffff) {
- index = ffz(mask_val);
- pvt_id = index + word1_mask + word2_mask;
- if (pvt_id <= (max_inst - 1)) {
- *val |= 1ULL << (index + word1_mask);
- return pvt_id;
- }
- }
-
- return -EINVAL;
-}
-
-static inline int skl_pvtid_128(struct uuid_module *module)
-{
- int j, i, word1_mask, word2_mask = 0, pvt_id;
-
- for (j = 0; j < MAX_INSTANCE_BUFF; j++) {
- word1_mask = 0;
-
- for (i = 0; i < 2; i++) {
- pvt_id = skl_getid_32(module, &module->pvt_id[j],
- word1_mask, word2_mask);
- if (pvt_id >= 0)
- return pvt_id;
-
- word1_mask += 32;
- if ((word1_mask + word2_mask) >= module->max_instance)
- return -EINVAL;
- }
-
- word2_mask += 64;
- if (word2_mask >= module->max_instance)
- return -EINVAL;
- }
-
- return -EINVAL;
-}
-
-/**
- * skl_get_pvt_id: generate a private id for use as module id
- *
- * @skl: driver context
- * @uuid_mod: module's uuid
- * @instance_id: module's instance id
- *
- * This generates a 128 bit private unique id for a module TYPE so that
- * module instance is unique
- */
-int skl_get_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int instance_id)
-{
- struct uuid_module *module;
- int pvt_id;
-
- list_for_each_entry(module, &skl->uuid_list, list) {
- if (guid_equal(uuid_mod, &module->uuid)) {
-
- pvt_id = skl_pvtid_128(module);
- if (pvt_id >= 0) {
- module->instance_id[pvt_id] = instance_id;
-
- return pvt_id;
- }
- }
- }
-
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(skl_get_pvt_id);
-
-/**
- * skl_put_pvt_id: free up the private id allocated
- *
- * @skl: driver context
- * @uuid_mod: module's uuid
- * @pvt_id: module pvt id
- *
- * This frees a 128 bit private unique id previously generated
- */
-int skl_put_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int *pvt_id)
-{
- int i;
- struct uuid_module *module;
-
- list_for_each_entry(module, &skl->uuid_list, list) {
- if (guid_equal(uuid_mod, &module->uuid)) {
-
- if (*pvt_id != 0)
- i = (*pvt_id) / 64;
- else
- i = 0;
-
- module->pvt_id[i] &= ~(1 << (*pvt_id));
- *pvt_id = -1;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(skl_put_pvt_id);
-
-/*
- * Parse the firmware binary to get the UUID, module id
- * and loadable flags
- */
-int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
- unsigned int offset, int index)
-{
- struct adsp_fw_hdr *adsp_hdr;
- struct adsp_module_entry *mod_entry;
- int i, num_entry, size;
- const char *buf;
- struct skl_dev *skl = ctx->thread_context;
- struct uuid_module *module;
- struct firmware stripped_fw;
- unsigned int safe_file;
- int ret;
-
- /* Get the FW pointer to derive ADSP header */
- stripped_fw.data = fw->data;
- stripped_fw.size = fw->size;
-
- skl_dsp_strip_extended_manifest(&stripped_fw);
-
- buf = stripped_fw.data;
-
- /* check if we have enough space in file to move to header */
- safe_file = sizeof(*adsp_hdr) + offset;
- if (stripped_fw.size <= safe_file) {
- dev_err(ctx->dev, "Small fw file size, No space for hdr\n");
- return -EINVAL;
- }
-
- adsp_hdr = (struct adsp_fw_hdr *)(buf + offset);
-
- /* check 1st module entry is in file */
- safe_file += adsp_hdr->len + sizeof(*mod_entry);
- if (stripped_fw.size <= safe_file) {
- dev_err(ctx->dev, "Small fw file size, No module entry\n");
- return -EINVAL;
- }
-
- mod_entry = (struct adsp_module_entry *)(buf + offset + adsp_hdr->len);
-
- num_entry = adsp_hdr->num_modules;
-
- /* check all entries are in file */
- safe_file += num_entry * sizeof(*mod_entry);
- if (stripped_fw.size <= safe_file) {
- dev_err(ctx->dev, "Small fw file size, No modules\n");
- return -EINVAL;
- }
-
-
- /*
- * Read the UUID(GUID) from FW Manifest.
- *
- * The 16 byte UUID format is: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX
- * Populate the UUID table to store module_id and loadable flags
- * for the module.
- */
-
- for (i = 0; i < num_entry; i++, mod_entry++) {
- module = kzalloc(sizeof(*module), GFP_KERNEL);
- if (!module) {
- ret = -ENOMEM;
- goto free_uuid_list;
- }
-
- import_guid(&module->uuid, mod_entry->uuid);
-
- module->id = (i | (index << 12));
- module->is_loadable = mod_entry->type.load_type;
- module->max_instance = mod_entry->instance_max_count;
- size = sizeof(int) * mod_entry->instance_max_count;
- module->instance_id = devm_kzalloc(ctx->dev, size, GFP_KERNEL);
- if (!module->instance_id) {
- ret = -ENOMEM;
- kfree(module);
- goto free_uuid_list;
- }
-
- list_add_tail(&module->list, &skl->uuid_list);
-
- dev_dbg(ctx->dev,
- "Adding uuid :%pUL mod id: %d Loadable: %d\n",
- &module->uuid, module->id, module->is_loadable);
- }
-
- return 0;
-
-free_uuid_list:
- skl_freeup_uuid_list(skl);
- return ret;
-}
-
-void skl_freeup_uuid_list(struct skl_dev *skl)
-{
- struct uuid_module *uuid, *_uuid;
-
- list_for_each_entry_safe(uuid, _uuid, &skl->uuid_list, list) {
- list_del(&uuid->list);
- kfree(uuid);
- }
-}
-
-/*
- * some firmware binary contains some extended manifest. This needs
- * to be stripped in that case before we load and use that image.
- *
- * Get the module id for the module by checking
- * the table for the UUID for the module
- */
-int skl_dsp_strip_extended_manifest(struct firmware *fw)
-{
- struct skl_ext_manifest_hdr *hdr;
-
- /* check if fw file is greater than header we are looking */
- if (fw->size < sizeof(hdr)) {
- pr_err("%s: Firmware file small, no hdr\n", __func__);
- return -EINVAL;
- }
-
- hdr = (struct skl_ext_manifest_hdr *)fw->data;
-
- if (hdr->id == SKL_EXT_MANIFEST_HEADER_MAGIC) {
- fw->size -= hdr->len;
- fw->data += hdr->len;
- }
-
- return 0;
-}
-
-int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
- struct skl_dsp_loader_ops dsp_ops, struct skl_dev **dsp,
- struct sst_dsp_device *skl_dev)
-{
- struct skl_dev *skl = *dsp;
- struct sst_dsp *sst;
-
- skl->dev = dev;
- skl_dev->thread_context = skl;
- INIT_LIST_HEAD(&skl->uuid_list);
- skl->dsp = skl_dsp_ctx_init(dev, skl_dev, irq);
- if (!skl->dsp) {
- dev_err(skl->dev, "%s: no device\n", __func__);
- return -ENODEV;
- }
-
- sst = skl->dsp;
- sst->fw_name = fw_name;
- sst->dsp_ops = dsp_ops;
- init_waitqueue_head(&skl->mod_load_wait);
- INIT_LIST_HEAD(&sst->module_list);
-
- skl->is_first_boot = true;
-
- return 0;
-}
-
-int skl_prepare_lib_load(struct skl_dev *skl, struct skl_lib_info *linfo,
- struct firmware *stripped_fw,
- unsigned int hdr_offset, int index)
-{
- int ret;
- struct sst_dsp *dsp = skl->dsp;
-
- if (linfo->fw == NULL) {
- ret = request_firmware(&linfo->fw, linfo->name,
- skl->dev);
- if (ret < 0) {
- dev_err(skl->dev, "Request lib %s failed:%d\n",
- linfo->name, ret);
- return ret;
- }
- }
-
- if (skl->is_first_boot) {
- ret = snd_skl_parse_uuids(dsp, linfo->fw, hdr_offset, index);
- if (ret < 0)
- return ret;
- }
-
- stripped_fw->data = linfo->fw->data;
- stripped_fw->size = linfo->fw->size;
- skl_dsp_strip_extended_manifest(stripped_fw);
-
- return 0;
-}
-
-void skl_release_library(struct skl_lib_info *linfo, int lib_count)
-{
- int i;
-
- /* library indices start from 1 to N. 0 represents base FW */
- for (i = 1; i < lib_count; i++) {
- if (linfo[i].fw) {
- release_firmware(linfo[i].fw);
- linfo[i].fw = NULL;
- }
- }
-}
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
deleted file mode 100644
index 39d027ac16ec..000000000000
--- a/sound/soc/intel/skylake/skl-sst.c
+++ /dev/null
@@ -1,599 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * skl-sst.c - HDA DSP library functions for SKL platform
- *
- * Copyright (C) 2014-15, Intel Corporation.
- * Author:Rafal Redzimski <rafal.f.redzimski@intel.com>
- * Jeeja KP <jeeja.kp@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/uuid.h>
-#include "../common/sst-dsp.h"
-#include "../common/sst-dsp-priv.h"
-#include "../common/sst-ipc.h"
-#include "skl.h"
-
-#define SKL_BASEFW_TIMEOUT 300
-#define SKL_INIT_TIMEOUT 1000
-
-/* Intel HD Audio SRAM Window 0*/
-#define SKL_ADSP_SRAM0_BASE 0x8000
-
-/* Firmware status window */
-#define SKL_ADSP_FW_STATUS SKL_ADSP_SRAM0_BASE
-#define SKL_ADSP_ERROR_CODE (SKL_ADSP_FW_STATUS + 0x4)
-
-#define SKL_NUM_MODULES 1
-
-static bool skl_check_fw_status(struct sst_dsp *ctx, u32 status)
-{
- u32 cur_sts;
-
- cur_sts = sst_dsp_shim_read(ctx, SKL_ADSP_FW_STATUS) & SKL_FW_STS_MASK;
-
- return (cur_sts == status);
-}
-
-static int skl_transfer_firmware(struct sst_dsp *ctx,
- const void *basefw, u32 base_fw_size)
-{
- int ret = 0;
-
- ret = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, basefw, base_fw_size,
- true);
- if (ret < 0)
- return ret;
-
- ret = sst_dsp_register_poll(ctx,
- SKL_ADSP_FW_STATUS,
- SKL_FW_STS_MASK,
- SKL_FW_RFW_START,
- SKL_BASEFW_TIMEOUT,
- "Firmware boot");
-
- ctx->cl_dev.ops.cl_stop_dma(ctx);
-
- return ret;
-}
-
-#define SKL_ADSP_FW_BIN_HDR_OFFSET 0x284
-
-static int skl_load_base_firmware(struct sst_dsp *ctx)
-{
- int ret = 0, i;
- struct skl_dev *skl = ctx->thread_context;
- struct firmware stripped_fw;
- u32 reg;
-
- skl->boot_complete = false;
- init_waitqueue_head(&skl->boot_wait);
-
- if (ctx->fw == NULL) {
- ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
- if (ret < 0) {
- dev_err(ctx->dev, "Request firmware failed %d\n", ret);
- return -EIO;
- }
- }
-
- /* prase uuids on first boot */
- if (skl->is_first_boot) {
- ret = snd_skl_parse_uuids(ctx, ctx->fw, SKL_ADSP_FW_BIN_HDR_OFFSET, 0);
- if (ret < 0) {
- dev_err(ctx->dev, "UUID parsing err: %d\n", ret);
- release_firmware(ctx->fw);
- skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
- return ret;
- }
- }
-
- /* check for extended manifest */
- stripped_fw.data = ctx->fw->data;
- stripped_fw.size = ctx->fw->size;
-
- skl_dsp_strip_extended_manifest(&stripped_fw);
-
- ret = skl_dsp_boot(ctx);
- if (ret < 0) {
- dev_err(ctx->dev, "Boot dsp core failed ret: %d\n", ret);
- goto skl_load_base_firmware_failed;
- }
-
- ret = skl_cldma_prepare(ctx);
- if (ret < 0) {
- dev_err(ctx->dev, "CL dma prepare failed : %d\n", ret);
- goto skl_load_base_firmware_failed;
- }
-
- /* enable Interrupt */
- skl_ipc_int_enable(ctx);
- skl_ipc_op_int_enable(ctx);
-
- /* check ROM Status */
- for (i = SKL_INIT_TIMEOUT; i > 0; --i) {
- if (skl_check_fw_status(ctx, SKL_FW_INIT)) {
- dev_dbg(ctx->dev,
- "ROM loaded, we can continue with FW loading\n");
- break;
- }
- mdelay(1);
- }
- if (!i) {
- reg = sst_dsp_shim_read(ctx, SKL_ADSP_FW_STATUS);
- dev_err(ctx->dev,
- "Timeout waiting for ROM init done, reg:0x%x\n", reg);
- ret = -EIO;
- goto transfer_firmware_failed;
- }
-
- ret = skl_transfer_firmware(ctx, stripped_fw.data, stripped_fw.size);
- if (ret < 0) {
- dev_err(ctx->dev, "Transfer firmware failed%d\n", ret);
- goto transfer_firmware_failed;
- } else {
- ret = wait_event_timeout(skl->boot_wait, skl->boot_complete,
- msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
- if (ret == 0) {
- dev_err(ctx->dev, "DSP boot failed, FW Ready timed-out\n");
- ret = -EIO;
- goto transfer_firmware_failed;
- }
-
- dev_dbg(ctx->dev, "Download firmware successful%d\n", ret);
- skl->fw_loaded = true;
- }
- return 0;
-transfer_firmware_failed:
- ctx->cl_dev.ops.cl_cleanup_controller(ctx);
-skl_load_base_firmware_failed:
- skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
- release_firmware(ctx->fw);
- ctx->fw = NULL;
- return ret;
-}
-
-static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
-{
- int ret;
- struct skl_ipc_dxstate_info dx;
- struct skl_dev *skl = ctx->thread_context;
- unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
-
- /* If core0 is being turned on, we need to load the FW */
- if (core_id == SKL_DSP_CORE0_ID) {
- ret = skl_load_base_firmware(ctx);
- if (ret < 0) {
- dev_err(ctx->dev, "unable to load firmware\n");
- return ret;
- }
-
- /* load libs as they are also lost on D3 */
- if (skl->lib_count > 1) {
- ret = ctx->fw_ops.load_library(ctx, skl->lib_info,
- skl->lib_count);
- if (ret < 0) {
- dev_err(ctx->dev, "reload libs failed: %d\n",
- ret);
- return ret;
- }
-
- }
- }
-
- /*
- * If any core other than core 0 is being moved to D0, enable the
- * core and send the set dx IPC for the core.
- */
- if (core_id != SKL_DSP_CORE0_ID) {
- ret = skl_dsp_enable_core(ctx, core_mask);
- if (ret < 0)
- return ret;
-
- dx.core_mask = core_mask;
- dx.dx_mask = core_mask;
-
- ret = skl_ipc_set_dx(&skl->ipc, SKL_INSTANCE_ID,
- SKL_BASE_FW_MODULE_ID, &dx);
- if (ret < 0) {
- dev_err(ctx->dev, "Failed to set dsp to D0:core id= %d\n",
- core_id);
- skl_dsp_disable_core(ctx, core_mask);
- }
- }
-
- skl->cores.state[core_id] = SKL_DSP_RUNNING;
-
- return 0;
-}
-
-static int skl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
-{
- int ret;
- struct skl_ipc_dxstate_info dx;
- struct skl_dev *skl = ctx->thread_context;
- unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
-
- dx.core_mask = core_mask;
- dx.dx_mask = SKL_IPC_D3_MASK;
-
- ret = skl_ipc_set_dx(&skl->ipc, SKL_INSTANCE_ID, SKL_BASE_FW_MODULE_ID, &dx);
- if (ret < 0)
- dev_err(ctx->dev, "set Dx core %d fail: %d\n", core_id, ret);
-
- if (core_id == SKL_DSP_CORE0_ID) {
- /* disable Interrupt */
- ctx->cl_dev.ops.cl_cleanup_controller(ctx);
- skl_cldma_int_disable(ctx);
- skl_ipc_op_int_disable(ctx);
- skl_ipc_int_disable(ctx);
- }
-
- ret = skl_dsp_disable_core(ctx, core_mask);
- if (ret < 0)
- return ret;
-
- skl->cores.state[core_id] = SKL_DSP_RESET;
- return ret;
-}
-
-static unsigned int skl_get_errorcode(struct sst_dsp *ctx)
-{
- return sst_dsp_shim_read(ctx, SKL_ADSP_ERROR_CODE);
-}
-
-/*
- * since get/set_module are called from DAPM context,
- * we don't need lock for usage count
- */
-static int skl_get_module(struct sst_dsp *ctx, u16 mod_id)
-{
- struct skl_module_table *module;
-
- list_for_each_entry(module, &ctx->module_list, list) {
- if (module->mod_info->mod_id == mod_id)
- return ++module->usage_cnt;
- }
-
- return -EINVAL;
-}
-
-static int skl_put_module(struct sst_dsp *ctx, u16 mod_id)
-{
- struct skl_module_table *module;
-
- list_for_each_entry(module, &ctx->module_list, list) {
- if (module->mod_info->mod_id == mod_id)
- return --module->usage_cnt;
- }
-
- return -EINVAL;
-}
-
-static struct skl_module_table *skl_fill_module_table(struct sst_dsp *ctx,
- char *mod_name, int mod_id)
-{
- const struct firmware *fw;
- struct skl_module_table *skl_module;
- unsigned int size;
- int ret;
-
- ret = request_firmware(&fw, mod_name, ctx->dev);
- if (ret < 0) {
- dev_err(ctx->dev, "Request Module %s failed :%d\n",
- mod_name, ret);
- return NULL;
- }
-
- skl_module = devm_kzalloc(ctx->dev, sizeof(*skl_module), GFP_KERNEL);
- if (skl_module == NULL) {
- release_firmware(fw);
- return NULL;
- }
-
- size = sizeof(*skl_module->mod_info);
- skl_module->mod_info = devm_kzalloc(ctx->dev, size, GFP_KERNEL);
- if (skl_module->mod_info == NULL) {
- release_firmware(fw);
- return NULL;
- }
-
- skl_module->mod_info->mod_id = mod_id;
- skl_module->mod_info->fw = fw;
- list_add(&skl_module->list, &ctx->module_list);
-
- return skl_module;
-}
-
-/* get a module from it's unique ID */
-static struct skl_module_table *skl_module_get_from_id(
- struct sst_dsp *ctx, u16 mod_id)
-{
- struct skl_module_table *module;
-
- if (list_empty(&ctx->module_list)) {
- dev_err(ctx->dev, "Module list is empty\n");
- return NULL;
- }
-
- list_for_each_entry(module, &ctx->module_list, list) {
- if (module->mod_info->mod_id == mod_id)
- return module;
- }
-
- return NULL;
-}
-
-static int skl_transfer_module(struct sst_dsp *ctx, const void *data,
- u32 size, u16 mod_id, u8 table_id, bool is_module)
-{
- int ret, bytes_left, curr_pos;
- struct skl_dev *skl = ctx->thread_context;
- skl->mod_load_complete = false;
-
- bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, data, size, false);
- if (bytes_left < 0)
- return bytes_left;
-
- /* check is_module flag to load module or library */
- if (is_module)
- ret = skl_ipc_load_modules(&skl->ipc, SKL_NUM_MODULES, &mod_id);
- else
- ret = skl_sst_ipc_load_library(&skl->ipc, 0, table_id, false);
-
- if (ret < 0) {
- dev_err(ctx->dev, "Failed to Load %s with err %d\n",
- is_module ? "module" : "lib", ret);
- goto out;
- }
-
- /*
- * if bytes_left > 0 then wait for BDL complete interrupt and
- * copy the next chunk till bytes_left is 0. if bytes_left is
- * zero, then wait for load module IPC reply
- */
- while (bytes_left > 0) {
- curr_pos = size - bytes_left;
-
- ret = skl_cldma_wait_interruptible(ctx);
- if (ret < 0)
- goto out;
-
- bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx,
- data + curr_pos,
- bytes_left, false);
- }
-
- ret = wait_event_timeout(skl->mod_load_wait, skl->mod_load_complete,
- msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
- if (ret == 0 || !skl->mod_load_status) {
- dev_err(ctx->dev, "Module Load failed\n");
- ret = -EIO;
- }
-
-out:
- ctx->cl_dev.ops.cl_stop_dma(ctx);
-
- return ret;
-}
-
-static int
-skl_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
-{
- struct skl_dev *skl = ctx->thread_context;
- struct firmware stripped_fw;
- int ret, i;
-
- /* library indices start from 1 to N. 0 represents base FW */
- for (i = 1; i < lib_count; i++) {
- ret = skl_prepare_lib_load(skl, &skl->lib_info[i], &stripped_fw,
- SKL_ADSP_FW_BIN_HDR_OFFSET, i);
- if (ret < 0)
- goto load_library_failed;
- ret = skl_transfer_module(ctx, stripped_fw.data,
- stripped_fw.size, 0, i, false);
- if (ret < 0)
- goto load_library_failed;
- }
-
- return 0;
-
-load_library_failed:
- skl_release_library(linfo, lib_count);
- return ret;
-}
-
-static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid)
-{
- struct skl_module_table *module_entry = NULL;
- int ret = 0;
- char mod_name[64]; /* guid str = 32 chars + 4 hyphens */
-
- snprintf(mod_name, sizeof(mod_name), "intel/dsp_fw_%pUL.bin", guid);
-
- module_entry = skl_module_get_from_id(ctx, mod_id);
- if (module_entry == NULL) {
- module_entry = skl_fill_module_table(ctx, mod_name, mod_id);
- if (module_entry == NULL) {
- dev_err(ctx->dev, "Failed to Load module\n");
- return -EINVAL;
- }
- }
-
- if (!module_entry->usage_cnt) {
- ret = skl_transfer_module(ctx, module_entry->mod_info->fw->data,
- module_entry->mod_info->fw->size,
- mod_id, 0, true);
- if (ret < 0) {
- dev_err(ctx->dev, "Failed to Load module\n");
- return ret;
- }
- }
-
- ret = skl_get_module(ctx, mod_id);
-
- return ret;
-}
-
-static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id)
-{
- int usage_cnt;
- struct skl_dev *skl = ctx->thread_context;
- int ret = 0;
-
- usage_cnt = skl_put_module(ctx, mod_id);
- if (usage_cnt < 0) {
- dev_err(ctx->dev, "Module bad usage cnt!:%d\n", usage_cnt);
- return -EIO;
- }
-
- /* if module is used by others return, no need to unload */
- if (usage_cnt > 0)
- return 0;
-
- ret = skl_ipc_unload_modules(&skl->ipc,
- SKL_NUM_MODULES, &mod_id);
- if (ret < 0) {
- dev_err(ctx->dev, "Failed to UnLoad module\n");
- skl_get_module(ctx, mod_id);
- return ret;
- }
-
- return ret;
-}
-
-void skl_clear_module_cnt(struct sst_dsp *ctx)
-{
- struct skl_module_table *module;
-
- if (list_empty(&ctx->module_list))
- return;
-
- list_for_each_entry(module, &ctx->module_list, list) {
- module->usage_cnt = 0;
- }
-}
-EXPORT_SYMBOL_GPL(skl_clear_module_cnt);
-
-static void skl_clear_module_table(struct sst_dsp *ctx)
-{
- struct skl_module_table *module, *tmp;
-
- if (list_empty(&ctx->module_list))
- return;
-
- list_for_each_entry_safe(module, tmp, &ctx->module_list, list) {
- list_del(&module->list);
- release_firmware(module->mod_info->fw);
- }
-}
-
-static const struct skl_dsp_fw_ops skl_fw_ops = {
- .set_state_D0 = skl_set_dsp_D0,
- .set_state_D3 = skl_set_dsp_D3,
- .load_fw = skl_load_base_firmware,
- .get_fw_errcode = skl_get_errorcode,
- .load_library = skl_load_library,
- .load_mod = skl_load_module,
- .unload_mod = skl_unload_module,
-};
-
-static struct sst_ops skl_ops = {
- .irq_handler = skl_dsp_sst_interrupt,
- .write = sst_shim32_write,
- .read = sst_shim32_read,
- .free = skl_dsp_free,
-};
-
-static struct sst_dsp_device skl_dev = {
- .thread = skl_dsp_irq_thread_handler,
- .ops = &skl_ops,
-};
-
-int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
- const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
- struct skl_dev **dsp)
-{
- struct skl_dev *skl;
- struct sst_dsp *sst;
- int ret;
-
- ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &skl_dev);
- if (ret < 0) {
- dev_err(dev, "%s: no device\n", __func__);
- return ret;
- }
-
- skl = *dsp;
- sst = skl->dsp;
- sst->addr.lpe = mmio_base;
- sst->addr.shim = mmio_base;
- sst->addr.sram0_base = SKL_ADSP_SRAM0_BASE;
- sst->addr.sram1_base = SKL_ADSP_SRAM1_BASE;
- sst->addr.w0_stat_sz = SKL_ADSP_W0_STAT_SZ;
- sst->addr.w0_up_sz = SKL_ADSP_W0_UP_SZ;
-
- sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ),
- SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
-
- ret = skl_ipc_init(dev, skl);
- if (ret) {
- skl_dsp_free(sst);
- return ret;
- }
-
- sst->fw_ops = skl_fw_ops;
-
- return skl_dsp_acquire_irq(sst);
-}
-EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
-
-int skl_sst_init_fw(struct device *dev, struct skl_dev *skl)
-{
- int ret;
- struct sst_dsp *sst = skl->dsp;
-
- ret = sst->fw_ops.load_fw(sst);
- if (ret < 0) {
- dev_err(dev, "Load base fw failed : %d\n", ret);
- return ret;
- }
-
- skl_dsp_init_core_state(sst);
-
- if (skl->lib_count > 1) {
- ret = sst->fw_ops.load_library(sst, skl->lib_info,
- skl->lib_count);
- if (ret < 0) {
- dev_err(dev, "Load Library failed : %x\n", ret);
- return ret;
- }
- }
- skl->is_first_boot = false;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(skl_sst_init_fw);
-
-void skl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl)
-{
-
- if (skl->dsp->fw)
- release_firmware(skl->dsp->fw);
- skl_clear_module_table(skl->dsp);
- skl_freeup_uuid_list(skl);
- skl_ipc_free(&skl->ipc);
- skl->dsp->ops->free(skl->dsp);
- if (skl->boot_complete) {
- skl->dsp->cl_dev.ops.cl_cleanup_controller(skl->dsp);
- skl_cldma_int_disable(skl->dsp);
- }
-}
-EXPORT_SYMBOL_GPL(skl_sst_dsp_cleanup);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Intel Skylake IPC driver");
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
deleted file mode 100644
index 96cfebded072..000000000000
--- a/sound/soc/intel/skylake/skl-topology.c
+++ /dev/null
@@ -1,3774 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * skl-topology.c - Implements Platform component ALSA controls/widget
- * handlers.
- *
- * Copyright (C) 2014-2015 Intel Corp
- * Author: Jeeja KP <jeeja.kp@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/firmware.h>
-#include <linux/uuid.h>
-#include <sound/intel-nhlt.h>
-#include <sound/soc.h>
-#include <sound/soc-acpi.h>
-#include <sound/soc-topology.h>
-#include <uapi/sound/snd_sst_tokens.h>
-#include <uapi/sound/skl-tplg-interface.h>
-#include "skl-sst-dsp.h"
-#include "skl-sst-ipc.h"
-#include "skl-topology.h"
-#include "skl.h"
-#include "../common/sst-dsp.h"
-#include "../common/sst-dsp-priv.h"
-
-#define SKL_CH_FIXUP_MASK (1 << 0)
-#define SKL_RATE_FIXUP_MASK (1 << 1)
-#define SKL_FMT_FIXUP_MASK (1 << 2)
-#define SKL_IN_DIR_BIT_MASK BIT(0)
-#define SKL_PIN_COUNT_MASK GENMASK(7, 4)
-
-static const int mic_mono_list[] = {
-0, 1, 2, 3,
-};
-static const int mic_stereo_list[][SKL_CH_STEREO] = {
-{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3},
-};
-static const int mic_trio_list[][SKL_CH_TRIO] = {
-{0, 1, 2}, {0, 1, 3}, {0, 2, 3}, {1, 2, 3},
-};
-static const int mic_quatro_list[][SKL_CH_QUATRO] = {
-{0, 1, 2, 3},
-};
-
-#define CHECK_HW_PARAMS(ch, freq, bps, prm_ch, prm_freq, prm_bps) \
- ((ch == prm_ch) && (bps == prm_bps) && (freq == prm_freq))
-
-void skl_tplg_d0i3_get(struct skl_dev *skl, enum d0i3_capability caps)
-{
- struct skl_d0i3_data *d0i3 = &skl->d0i3;
-
- switch (caps) {
- case SKL_D0I3_NONE:
- d0i3->non_d0i3++;
- break;
-
- case SKL_D0I3_STREAMING:
- d0i3->streaming++;
- break;
-
- case SKL_D0I3_NON_STREAMING:
- d0i3->non_streaming++;
- break;
- }
-}
-
-void skl_tplg_d0i3_put(struct skl_dev *skl, enum d0i3_capability caps)
-{
- struct skl_d0i3_data *d0i3 = &skl->d0i3;
-
- switch (caps) {
- case SKL_D0I3_NONE:
- d0i3->non_d0i3--;
- break;
-
- case SKL_D0I3_STREAMING:
- d0i3->streaming--;
- break;
-
- case SKL_D0I3_NON_STREAMING:
- d0i3->non_streaming--;
- break;
- }
-}
-
-/*
- * SKL DSP driver modelling uses only few DAPM widgets so for rest we will
- * ignore. This helpers checks if the SKL driver handles this widget type
- */
-static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w,
- struct device *dev)
-{
- if (w->dapm->dev != dev)
- return false;
-
- switch (w->id) {
- case snd_soc_dapm_dai_link:
- case snd_soc_dapm_dai_in:
- case snd_soc_dapm_aif_in:
- case snd_soc_dapm_aif_out:
- case snd_soc_dapm_dai_out:
- case snd_soc_dapm_switch:
- case snd_soc_dapm_output:
- case snd_soc_dapm_mux:
-
- return false;
- default:
- return true;
- }
-}
-
-static void skl_dump_mconfig(struct skl_dev *skl, struct skl_module_cfg *mcfg)
-{
- struct skl_module_iface *iface = &mcfg->module->formats[mcfg->fmt_idx];
-
- dev_dbg(skl->dev, "Dumping config\n");
- dev_dbg(skl->dev, "Input Format:\n");
- dev_dbg(skl->dev, "channels = %d\n", iface->inputs[0].fmt.channels);
- dev_dbg(skl->dev, "s_freq = %d\n", iface->inputs[0].fmt.s_freq);
- dev_dbg(skl->dev, "ch_cfg = %d\n", iface->inputs[0].fmt.ch_cfg);
- dev_dbg(skl->dev, "valid bit depth = %d\n",
- iface->inputs[0].fmt.valid_bit_depth);
- dev_dbg(skl->dev, "Output Format:\n");
- dev_dbg(skl->dev, "channels = %d\n", iface->outputs[0].fmt.channels);
- dev_dbg(skl->dev, "s_freq = %d\n", iface->outputs[0].fmt.s_freq);
- dev_dbg(skl->dev, "valid bit depth = %d\n",
- iface->outputs[0].fmt.valid_bit_depth);
- dev_dbg(skl->dev, "ch_cfg = %d\n", iface->outputs[0].fmt.ch_cfg);
-}
-
-static void skl_tplg_update_chmap(struct skl_module_fmt *fmt, int chs)
-{
- int slot_map = 0xFFFFFFFF;
- int start_slot = 0;
- int i;
-
- for (i = 0; i < chs; i++) {
- /*
- * For 2 channels with starting slot as 0, slot map will
- * look like 0xFFFFFF10.
- */
- slot_map &= (~(0xF << (4 * i)) | (start_slot << (4 * i)));
- start_slot++;
- }
- fmt->ch_map = slot_map;
-}
-
-static void skl_tplg_update_params(struct skl_module_fmt *fmt,
- struct skl_pipe_params *params, int fixup)
-{
- if (fixup & SKL_RATE_FIXUP_MASK)
- fmt->s_freq = params->s_freq;
- if (fixup & SKL_CH_FIXUP_MASK) {
- fmt->channels = params->ch;
- skl_tplg_update_chmap(fmt, fmt->channels);
- }
- if (fixup & SKL_FMT_FIXUP_MASK) {
- fmt->valid_bit_depth = skl_get_bit_depth(params->s_fmt);
-
- /*
- * 16 bit is 16 bit container whereas 24 bit is in 32 bit
- * container so update bit depth accordingly
- */
- switch (fmt->valid_bit_depth) {
- case SKL_DEPTH_16BIT:
- fmt->bit_depth = fmt->valid_bit_depth;
- break;
-
- default:
- fmt->bit_depth = SKL_DEPTH_32BIT;
- break;
- }
- }
-
-}
-
-/*
- * A pipeline may have modules which impact the pcm parameters, like SRC,
- * channel converter, format converter.
- * We need to calculate the output params by applying the 'fixup'
- * Topology will tell driver which type of fixup is to be applied by
- * supplying the fixup mask, so based on that we calculate the output
- *
- * Now In FE the pcm hw_params is source/target format. Same is applicable
- * for BE with its hw_params invoked.
- * here based on FE, BE pipeline and direction we calculate the input and
- * outfix and then apply that for a module
- */
-static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg,
- struct skl_pipe_params *params, bool is_fe)
-{
- int in_fixup, out_fixup;
- struct skl_module_fmt *in_fmt, *out_fmt;
-
- /* Fixups will be applied to pin 0 only */
- in_fmt = &m_cfg->module->formats[m_cfg->fmt_idx].inputs[0].fmt;
- out_fmt = &m_cfg->module->formats[m_cfg->fmt_idx].outputs[0].fmt;
-
- if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (is_fe) {
- in_fixup = m_cfg->params_fixup;
- out_fixup = (~m_cfg->converter) &
- m_cfg->params_fixup;
- } else {
- out_fixup = m_cfg->params_fixup;
- in_fixup = (~m_cfg->converter) &
- m_cfg->params_fixup;
- }
- } else {
- if (is_fe) {
- out_fixup = m_cfg->params_fixup;
- in_fixup = (~m_cfg->converter) &
- m_cfg->params_fixup;
- } else {
- in_fixup = m_cfg->params_fixup;
- out_fixup = (~m_cfg->converter) &
- m_cfg->params_fixup;
- }
- }
-
- skl_tplg_update_params(in_fmt, params, in_fixup);
- skl_tplg_update_params(out_fmt, params, out_fixup);
-}
-
-/*
- * A module needs input and output buffers, which are dependent upon pcm
- * params, so once we have calculate params, we need buffer calculation as
- * well.
- */
-static void skl_tplg_update_buffer_size(struct skl_dev *skl,
- struct skl_module_cfg *mcfg)
-{
- int multiplier = 1;
- struct skl_module_fmt *in_fmt, *out_fmt;
- struct skl_module_res *res;
-
- /* Since fixups is applied to pin 0 only, ibs, obs needs
- * change for pin 0 only
- */
- res = &mcfg->module->resources[mcfg->res_idx];
- in_fmt = &mcfg->module->formats[mcfg->fmt_idx].inputs[0].fmt;
- out_fmt = &mcfg->module->formats[mcfg->fmt_idx].outputs[0].fmt;
-
- if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT)
- multiplier = 5;
-
- res->ibs = DIV_ROUND_UP(in_fmt->s_freq, 1000) *
- in_fmt->channels * (in_fmt->bit_depth >> 3) *
- multiplier;
-
- res->obs = DIV_ROUND_UP(out_fmt->s_freq, 1000) *
- out_fmt->channels * (out_fmt->bit_depth >> 3) *
- multiplier;
-}
-
-static u8 skl_tplg_be_dev_type(int dev_type)
-{
- int ret;
-
- switch (dev_type) {
- case SKL_DEVICE_BT:
- ret = NHLT_DEVICE_BT;
- break;
-
- case SKL_DEVICE_DMIC:
- ret = NHLT_DEVICE_DMIC;
- break;
-
- case SKL_DEVICE_I2S:
- ret = NHLT_DEVICE_I2S;
- break;
-
- default:
- ret = NHLT_DEVICE_INVALID;
- break;
- }
-
- return ret;
-}
-
-static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
- struct skl_dev *skl)
-{
- struct skl_module_cfg *m_cfg = w->priv;
- int link_type, dir;
- u32 ch, s_freq, s_fmt, s_cont;
- struct nhlt_specific_cfg *cfg;
- u8 dev_type = skl_tplg_be_dev_type(m_cfg->dev_type);
- int fmt_idx = m_cfg->fmt_idx;
- struct skl_module_iface *m_iface = &m_cfg->module->formats[fmt_idx];
-
- /* check if we already have blob */
- if (m_cfg->formats_config[SKL_PARAM_INIT].caps_size > 0)
- return 0;
-
- dev_dbg(skl->dev, "Applying default cfg blob\n");
- switch (m_cfg->dev_type) {
- case SKL_DEVICE_DMIC:
- link_type = NHLT_LINK_DMIC;
- dir = SNDRV_PCM_STREAM_CAPTURE;
- s_freq = m_iface->inputs[0].fmt.s_freq;
- s_fmt = m_iface->inputs[0].fmt.valid_bit_depth;
- s_cont = m_iface->inputs[0].fmt.bit_depth;
- ch = m_iface->inputs[0].fmt.channels;
- break;
-
- case SKL_DEVICE_I2S:
- link_type = NHLT_LINK_SSP;
- if (m_cfg->hw_conn_type == SKL_CONN_SOURCE) {
- dir = SNDRV_PCM_STREAM_PLAYBACK;
- s_freq = m_iface->outputs[0].fmt.s_freq;
- s_fmt = m_iface->outputs[0].fmt.valid_bit_depth;
- s_cont = m_iface->outputs[0].fmt.bit_depth;
- ch = m_iface->outputs[0].fmt.channels;
- } else {
- dir = SNDRV_PCM_STREAM_CAPTURE;
- s_freq = m_iface->inputs[0].fmt.s_freq;
- s_fmt = m_iface->inputs[0].fmt.valid_bit_depth;
- s_cont = m_iface->inputs[0].fmt.bit_depth;
- ch = m_iface->inputs[0].fmt.channels;
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- /* update the blob based on virtual bus_id and default params */
- cfg = intel_nhlt_get_endpoint_blob(skl->dev, skl->nhlt, m_cfg->vbus_id,
- link_type, s_fmt, s_cont, ch,
- s_freq, dir, dev_type);
- if (cfg) {
- m_cfg->formats_config[SKL_PARAM_INIT].caps_size = cfg->size;
- m_cfg->formats_config[SKL_PARAM_INIT].caps = (u32 *)&cfg->caps;
- } else {
- dev_err(skl->dev, "Blob NULL for id %x type %d dirn %d\n",
- m_cfg->vbus_id, link_type, dir);
- dev_err(skl->dev, "PCM: ch %d, freq %d, fmt %d/%d\n",
- ch, s_freq, s_fmt, s_cont);
- return -EIO;
- }
-
- return 0;
-}
-
-static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
- struct skl_dev *skl)
-{
- struct skl_module_cfg *m_cfg = w->priv;
- struct skl_pipe_params *params = m_cfg->pipe->p_params;
- int p_conn_type = m_cfg->pipe->conn_type;
- bool is_fe;
-
- if (!m_cfg->params_fixup)
- return;
-
- dev_dbg(skl->dev, "Mconfig for widget=%s BEFORE updation\n",
- w->name);
-
- skl_dump_mconfig(skl, m_cfg);
-
- if (p_conn_type == SKL_PIPE_CONN_TYPE_FE)
- is_fe = true;
- else
- is_fe = false;
-
- skl_tplg_update_params_fixup(m_cfg, params, is_fe);
- skl_tplg_update_buffer_size(skl, m_cfg);
-
- dev_dbg(skl->dev, "Mconfig for widget=%s AFTER updation\n",
- w->name);
-
- skl_dump_mconfig(skl, m_cfg);
-}
-
-/*
- * some modules can have multiple params set from user control and
- * need to be set after module is initialized. If set_param flag is
- * set module params will be done after module is initialised.
- */
-static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
- struct skl_dev *skl)
-{
- int i, ret;
- struct skl_module_cfg *mconfig = w->priv;
- const struct snd_kcontrol_new *k;
- struct soc_bytes_ext *sb;
- struct skl_algo_data *bc;
- struct skl_specific_cfg *sp_cfg;
-
- if (mconfig->formats_config[SKL_PARAM_SET].caps_size > 0 &&
- mconfig->formats_config[SKL_PARAM_SET].set_params == SKL_PARAM_SET) {
- sp_cfg = &mconfig->formats_config[SKL_PARAM_SET];
- ret = skl_set_module_params(skl, sp_cfg->caps,
- sp_cfg->caps_size,
- sp_cfg->param_id, mconfig);
- if (ret < 0)
- return ret;
- }
-
- for (i = 0; i < w->num_kcontrols; i++) {
- k = &w->kcontrol_news[i];
- if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
- sb = (void *) k->private_value;
- bc = (struct skl_algo_data *)sb->dobj.private;
-
- if (bc->set_params == SKL_PARAM_SET) {
- ret = skl_set_module_params(skl,
- (u32 *)bc->params, bc->size,
- bc->param_id, mconfig);
- if (ret < 0)
- return ret;
- }
- }
- }
-
- return 0;
-}
-
-/*
- * some module param can set from user control and this is required as
- * when module is initailzed. if module param is required in init it is
- * identifed by set_param flag. if set_param flag is not set, then this
- * parameter needs to set as part of module init.
- */
-static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w)
-{
- const struct snd_kcontrol_new *k;
- struct soc_bytes_ext *sb;
- struct skl_algo_data *bc;
- struct skl_module_cfg *mconfig = w->priv;
- int i;
-
- for (i = 0; i < w->num_kcontrols; i++) {
- k = &w->kcontrol_news[i];
- if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
- sb = (struct soc_bytes_ext *)k->private_value;
- bc = (struct skl_algo_data *)sb->dobj.private;
-
- if (bc->set_params != SKL_PARAM_INIT)
- continue;
-
- mconfig->formats_config[SKL_PARAM_INIT].caps =
- (u32 *)bc->params;
- mconfig->formats_config[SKL_PARAM_INIT].caps_size =
- bc->size;
-
- break;
- }
- }
-
- return 0;
-}
-
-static int skl_tplg_module_prepare(struct skl_dev *skl, struct skl_pipe *pipe,
- struct snd_soc_dapm_widget *w, struct skl_module_cfg *mcfg)
-{
- switch (mcfg->dev_type) {
- case SKL_DEVICE_HDAHOST:
- return skl_pcm_host_dma_prepare(skl->dev, pipe->p_params);
-
- case SKL_DEVICE_HDALINK:
- return skl_pcm_link_dma_prepare(skl->dev, pipe->p_params);
- }
-
- return 0;
-}
-
-/*
- * Inside a pipe instance, we can have various modules. These modules need
- * to instantiated in DSP by invoking INIT_MODULE IPC, which is achieved by
- * skl_init_module() routine, so invoke that for all modules in a pipeline
- */
-static int
-skl_tplg_init_pipe_modules(struct skl_dev *skl, struct skl_pipe *pipe)
-{
- struct skl_pipe_module *w_module;
- struct snd_soc_dapm_widget *w;
- struct skl_module_cfg *mconfig;
- u8 cfg_idx;
- int ret = 0;
-
- list_for_each_entry(w_module, &pipe->w_list, node) {
- guid_t *uuid_mod;
- w = w_module->w;
- mconfig = w->priv;
-
- /* check if module ids are populated */
- if (mconfig->id.module_id < 0) {
- dev_err(skl->dev,
- "module %pUL id not populated\n",
- (guid_t *)mconfig->guid);
- return -EIO;
- }
-
- cfg_idx = mconfig->pipe->cur_config_idx;
- mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx;
- mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx;
-
- if (mconfig->module->loadable && skl->dsp->fw_ops.load_mod) {
- ret = skl->dsp->fw_ops.load_mod(skl->dsp,
- mconfig->id.module_id, mconfig->guid);
- if (ret < 0)
- return ret;
- }
-
- /* prepare the DMA if the module is gateway cpr */
- ret = skl_tplg_module_prepare(skl, pipe, w, mconfig);
- if (ret < 0)
- return ret;
-
- /* update blob if blob is null for be with default value */
- skl_tplg_update_be_blob(w, skl);
-
- /*
- * apply fix/conversion to module params based on
- * FE/BE params
- */
- skl_tplg_update_module_params(w, skl);
- uuid_mod = (guid_t *)mconfig->guid;
- mconfig->id.pvt_id = skl_get_pvt_id(skl, uuid_mod,
- mconfig->id.instance_id);
- if (mconfig->id.pvt_id < 0)
- return ret;
- skl_tplg_set_module_init_data(w);
-
- ret = skl_dsp_get_core(skl->dsp, mconfig->core_id);
- if (ret < 0) {
- dev_err(skl->dev, "Failed to wake up core %d ret=%d\n",
- mconfig->core_id, ret);
- return ret;
- }
-
- ret = skl_init_module(skl, mconfig);
- if (ret < 0) {
- skl_put_pvt_id(skl, uuid_mod, &mconfig->id.pvt_id);
- goto err;
- }
-
- ret = skl_tplg_set_module_params(w, skl);
- if (ret < 0)
- goto err;
- }
-
- return 0;
-err:
- skl_dsp_put_core(skl->dsp, mconfig->core_id);
- return ret;
-}
-
-static int skl_tplg_unload_pipe_modules(struct skl_dev *skl,
- struct skl_pipe *pipe)
-{
- int ret = 0;
- struct skl_pipe_module *w_module;
- struct skl_module_cfg *mconfig;
-
- list_for_each_entry(w_module, &pipe->w_list, node) {
- guid_t *uuid_mod;
- mconfig = w_module->w->priv;
- uuid_mod = (guid_t *)mconfig->guid;
-
- if (mconfig->module->loadable && skl->dsp->fw_ops.unload_mod) {
- ret = skl->dsp->fw_ops.unload_mod(skl->dsp,
- mconfig->id.module_id);
- if (ret < 0)
- return -EIO;
- }
- skl_put_pvt_id(skl, uuid_mod, &mconfig->id.pvt_id);
-
- ret = skl_dsp_put_core(skl->dsp, mconfig->core_id);
- if (ret < 0) {
- /* don't return; continue with other modules */
- dev_err(skl->dev, "Failed to sleep core %d ret=%d\n",
- mconfig->core_id, ret);
- }
- }
-
- /* no modules to unload in this path, so return */
- return ret;
-}
-
-static void skl_tplg_set_pipe_config_idx(struct skl_pipe *pipe, int idx)
-{
- pipe->cur_config_idx = idx;
- pipe->memory_pages = pipe->configs[idx].mem_pages;
-}
-
-/*
- * Here, we select pipe format based on the pipe type and pipe
- * direction to determine the current config index for the pipeline.
- * The config index is then used to select proper module resources.
- * Intermediate pipes currently have a fixed format hence we select the
- * 0th configuratation by default for such pipes.
- */
-static int
-skl_tplg_get_pipe_config(struct skl_dev *skl, struct skl_module_cfg *mconfig)
-{
- struct skl_pipe *pipe = mconfig->pipe;
- struct skl_pipe_params *params = pipe->p_params;
- struct skl_path_config *pconfig = &pipe->configs[0];
- struct skl_pipe_fmt *fmt = NULL;
- bool in_fmt = false;
- int i;
-
- if (pipe->nr_cfgs == 0) {
- skl_tplg_set_pipe_config_idx(pipe, 0);
- return 0;
- }
-
- if (pipe->conn_type == SKL_PIPE_CONN_TYPE_NONE || pipe->nr_cfgs == 1) {
- dev_dbg(skl->dev, "No conn_type or just 1 pathcfg, taking 0th for %d\n",
- pipe->ppl_id);
- skl_tplg_set_pipe_config_idx(pipe, 0);
- return 0;
- }
-
- if ((pipe->conn_type == SKL_PIPE_CONN_TYPE_FE &&
- pipe->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
- (pipe->conn_type == SKL_PIPE_CONN_TYPE_BE &&
- pipe->direction == SNDRV_PCM_STREAM_CAPTURE))
- in_fmt = true;
-
- for (i = 0; i < pipe->nr_cfgs; i++) {
- pconfig = &pipe->configs[i];
- if (in_fmt)
- fmt = &pconfig->in_fmt;
- else
- fmt = &pconfig->out_fmt;
-
- if (CHECK_HW_PARAMS(params->ch, params->s_freq, params->s_fmt,
- fmt->channels, fmt->freq, fmt->bps)) {
- skl_tplg_set_pipe_config_idx(pipe, i);
- dev_dbg(skl->dev, "Using pipe config: %d\n", i);
- return 0;
- }
- }
-
- dev_err(skl->dev, "Invalid pipe config: %d %d %d for pipe: %d\n",
- params->ch, params->s_freq, params->s_fmt, pipe->ppl_id);
- return -EINVAL;
-}
-
-/*
- * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we
- * need create the pipeline. So we do following:
- * - Create the pipeline
- * - Initialize the modules in pipeline
- * - finally bind all modules together
- */
-static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
- struct skl_dev *skl)
-{
- int ret;
- struct skl_module_cfg *mconfig = w->priv;
- struct skl_pipe_module *w_module;
- struct skl_pipe *s_pipe = mconfig->pipe;
- struct skl_module_cfg *src_module = NULL, *dst_module, *module;
- struct skl_module_deferred_bind *modules;
-
- ret = skl_tplg_get_pipe_config(skl, mconfig);
- if (ret < 0)
- return ret;
-
- /*
- * Create a list of modules for pipe.
- * This list contains modules from source to sink
- */
- ret = skl_create_pipeline(skl, mconfig->pipe);
- if (ret < 0)
- return ret;
-
- /* Init all pipe modules from source to sink */
- ret = skl_tplg_init_pipe_modules(skl, s_pipe);
- if (ret < 0)
- return ret;
-
- /* Bind modules from source to sink */
- list_for_each_entry(w_module, &s_pipe->w_list, node) {
- dst_module = w_module->w->priv;
-
- if (src_module == NULL) {
- src_module = dst_module;
- continue;
- }
-
- ret = skl_bind_modules(skl, src_module, dst_module);
- if (ret < 0)
- return ret;
-
- src_module = dst_module;
- }
-
- /*
- * When the destination module is initialized, check for these modules
- * in deferred bind list. If found, bind them.
- */
- list_for_each_entry(w_module, &s_pipe->w_list, node) {
- if (list_empty(&skl->bind_list))
- break;
-
- list_for_each_entry(modules, &skl->bind_list, node) {
- module = w_module->w->priv;
- if (modules->dst == module)
- skl_bind_modules(skl, modules->src,
- modules->dst);
- }
- }
-
- return 0;
-}
-
-static int skl_fill_sink_instance_id(struct skl_dev *skl, u32 *params,
- int size, struct skl_module_cfg *mcfg)
-{
- int i, pvt_id;
-
- if (mcfg->m_type == SKL_MODULE_TYPE_KPB) {
- struct skl_kpb_params *kpb_params =
- (struct skl_kpb_params *)params;
- struct skl_mod_inst_map *inst = kpb_params->u.map;
-
- for (i = 0; i < kpb_params->num_modules; i++) {
- pvt_id = skl_get_pvt_instance_id_map(skl, inst->mod_id,
- inst->inst_id);
- if (pvt_id < 0)
- return -EINVAL;
-
- inst->inst_id = pvt_id;
- inst++;
- }
- }
-
- return 0;
-}
-/*
- * Some modules require params to be set after the module is bound to
- * all pins connected.
- *
- * The module provider initializes set_param flag for such modules and we
- * send params after binding
- */
-static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
- struct skl_module_cfg *mcfg, struct skl_dev *skl)
-{
- int i, ret;
- struct skl_module_cfg *mconfig = w->priv;
- const struct snd_kcontrol_new *k;
- struct soc_bytes_ext *sb;
- struct skl_algo_data *bc;
- struct skl_specific_cfg *sp_cfg;
- u32 *params;
-
- /*
- * check all out/in pins are in bind state.
- * if so set the module param
- */
- for (i = 0; i < mcfg->module->max_output_pins; i++) {
- if (mcfg->m_out_pin[i].pin_state != SKL_PIN_BIND_DONE)
- return 0;
- }
-
- for (i = 0; i < mcfg->module->max_input_pins; i++) {
- if (mcfg->m_in_pin[i].pin_state != SKL_PIN_BIND_DONE)
- return 0;
- }
-
- if (mconfig->formats_config[SKL_PARAM_BIND].caps_size > 0 &&
- mconfig->formats_config[SKL_PARAM_BIND].set_params ==
- SKL_PARAM_BIND) {
- sp_cfg = &mconfig->formats_config[SKL_PARAM_BIND];
- ret = skl_set_module_params(skl, sp_cfg->caps,
- sp_cfg->caps_size,
- sp_cfg->param_id, mconfig);
- if (ret < 0)
- return ret;
- }
-
- for (i = 0; i < w->num_kcontrols; i++) {
- k = &w->kcontrol_news[i];
- if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
- sb = (void *) k->private_value;
- bc = (struct skl_algo_data *)sb->dobj.private;
-
- if (bc->set_params == SKL_PARAM_BIND) {
- params = kmemdup(bc->params, bc->max, GFP_KERNEL);
- if (!params)
- return -ENOMEM;
-
- skl_fill_sink_instance_id(skl, params, bc->max,
- mconfig);
-
- ret = skl_set_module_params(skl, params,
- bc->max, bc->param_id, mconfig);
- kfree(params);
-
- if (ret < 0)
- return ret;
- }
- }
- }
-
- return 0;
-}
-
-static int skl_get_module_id(struct skl_dev *skl, guid_t *uuid)
-{
- struct uuid_module *module;
-
- list_for_each_entry(module, &skl->uuid_list, list) {
- if (guid_equal(uuid, &module->uuid))
- return module->id;
- }
-
- return -EINVAL;
-}
-
-static int skl_tplg_find_moduleid_from_uuid(struct skl_dev *skl,
- const struct snd_kcontrol_new *k)
-{
- struct soc_bytes_ext *sb = (void *) k->private_value;
- struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private;
- struct skl_kpb_params *uuid_params, *params;
- struct hdac_bus *bus = skl_to_bus(skl);
- int i, size, module_id;
-
- if (bc->set_params == SKL_PARAM_BIND && bc->max) {
- uuid_params = (struct skl_kpb_params *)bc->params;
- size = struct_size(params, u.map, uuid_params->num_modules);
-
- params = devm_kzalloc(bus->dev, size, GFP_KERNEL);
- if (!params)
- return -ENOMEM;
-
- params->num_modules = uuid_params->num_modules;
-
- for (i = 0; i < uuid_params->num_modules; i++) {
- module_id = skl_get_module_id(skl,
- &uuid_params->u.map_uuid[i].mod_uuid);
- if (module_id < 0) {
- devm_kfree(bus->dev, params);
- return -EINVAL;
- }
-
- params->u.map[i].mod_id = module_id;
- params->u.map[i].inst_id =
- uuid_params->u.map_uuid[i].inst_id;
- }
-
- devm_kfree(bus->dev, bc->params);
- bc->params = (char *)params;
- bc->max = size;
- }
-
- return 0;
-}
-
-/*
- * Retrieve the module id from UUID mentioned in the
- * post bind params
- */
-void skl_tplg_add_moduleid_in_bind_params(struct skl_dev *skl,
- struct snd_soc_dapm_widget *w)
-{
- struct skl_module_cfg *mconfig = w->priv;
- int i;
-
- /*
- * Post bind params are used for only for KPB
- * to set copier instances to drain the data
- * in fast mode
- */
- if (mconfig->m_type != SKL_MODULE_TYPE_KPB)
- return;
-
- for (i = 0; i < w->num_kcontrols; i++)
- if ((w->kcontrol_news[i].access &
- SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) &&
- (skl_tplg_find_moduleid_from_uuid(skl,
- &w->kcontrol_news[i]) < 0))
- dev_err(skl->dev,
- "%s: invalid kpb post bind params\n",
- __func__);
-}
-
-static int skl_tplg_module_add_deferred_bind(struct skl_dev *skl,
- struct skl_module_cfg *src, struct skl_module_cfg *dst)
-{
- struct skl_module_deferred_bind *m_list, *modules;
- int i;
-
- /* only supported for module with static pin connection */
- for (i = 0; i < dst->module->max_input_pins; i++) {
- struct skl_module_pin *pin = &dst->m_in_pin[i];
-
- if (pin->is_dynamic)
- continue;
-
- if ((pin->id.module_id == src->id.module_id) &&
- (pin->id.instance_id == src->id.instance_id)) {
-
- if (!list_empty(&skl->bind_list)) {
- list_for_each_entry(modules, &skl->bind_list, node) {
- if (modules->src == src && modules->dst == dst)
- return 0;
- }
- }
-
- m_list = kzalloc(sizeof(*m_list), GFP_KERNEL);
- if (!m_list)
- return -ENOMEM;
-
- m_list->src = src;
- m_list->dst = dst;
-
- list_add(&m_list->node, &skl->bind_list);
- }
- }
-
- return 0;
-}
-
-static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
- struct skl_dev *skl,
- struct snd_soc_dapm_widget *src_w,
- struct skl_module_cfg *src_mconfig)
-{
- struct snd_soc_dapm_path *p;
- struct snd_soc_dapm_widget *sink = NULL, *next_sink = NULL;
- struct skl_module_cfg *sink_mconfig;
- int ret;
-
- snd_soc_dapm_widget_for_each_sink_path(w, p) {
- if (!p->connect)
- continue;
-
- dev_dbg(skl->dev,
- "%s: src widget=%s\n", __func__, w->name);
- dev_dbg(skl->dev,
- "%s: sink widget=%s\n", __func__, p->sink->name);
-
- next_sink = p->sink;
-
- if (!is_skl_dsp_widget_type(p->sink, skl->dev))
- return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig);
-
- /*
- * here we will check widgets in sink pipelines, so that
- * can be any widgets type and we are only interested if
- * they are ones used for SKL so check that first
- */
- if ((p->sink->priv != NULL) &&
- is_skl_dsp_widget_type(p->sink, skl->dev)) {
-
- sink = p->sink;
- sink_mconfig = sink->priv;
-
- /*
- * Modules other than PGA leaf can be connected
- * directly or via switch to a module in another
- * pipeline. EX: reference path
- * when the path is enabled, the dst module that needs
- * to be bound may not be initialized. if the module is
- * not initialized, add these modules in the deferred
- * bind list and when the dst module is initialised,
- * bind this module to the dst_module in deferred list.
- */
- if (((src_mconfig->m_state == SKL_MODULE_INIT_DONE)
- && (sink_mconfig->m_state == SKL_MODULE_UNINIT))) {
-
- ret = skl_tplg_module_add_deferred_bind(skl,
- src_mconfig, sink_mconfig);
-
- if (ret < 0)
- return ret;
-
- }
-
-
- if (src_mconfig->m_state == SKL_MODULE_UNINIT ||
- sink_mconfig->m_state == SKL_MODULE_UNINIT)
- continue;
-
- /* Bind source to sink, mixin is always source */
- ret = skl_bind_modules(skl, src_mconfig, sink_mconfig);
- if (ret)
- return ret;
-
- /* set module params after bind */
- skl_tplg_set_module_bind_params(src_w,
- src_mconfig, skl);
- skl_tplg_set_module_bind_params(sink,
- sink_mconfig, skl);
-
- /* Start sinks pipe first */
- if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) {
- if (sink_mconfig->pipe->conn_type !=
- SKL_PIPE_CONN_TYPE_FE)
- ret = skl_run_pipe(skl,
- sink_mconfig->pipe);
- if (ret)
- return ret;
- }
- }
- }
-
- if (!sink && next_sink)
- return skl_tplg_bind_sinks(next_sink, skl, src_w, src_mconfig);
-
- return 0;
-}
-
-/*
- * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA
- * we need to do following:
- * - Bind to sink pipeline
- * Since the sink pipes can be running and we don't get mixer event on
- * connect for already running mixer, we need to find the sink pipes
- * here and bind to them. This way dynamic connect works.
- * - Start sink pipeline, if not running
- * - Then run current pipe
- */
-static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
- struct skl_dev *skl)
-{
- struct skl_module_cfg *src_mconfig;
- int ret = 0;
-
- src_mconfig = w->priv;
-
- /*
- * find which sink it is connected to, bind with the sink,
- * if sink is not started, start sink pipe first, then start
- * this pipe
- */
- ret = skl_tplg_bind_sinks(w, skl, w, src_mconfig);
- if (ret)
- return ret;
-
- /* Start source pipe last after starting all sinks */
- if (src_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
- return skl_run_pipe(skl, src_mconfig->pipe);
-
- return 0;
-}
-
-static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
- struct snd_soc_dapm_widget *w, struct skl_dev *skl)
-{
- struct snd_soc_dapm_path *p;
- struct snd_soc_dapm_widget *src_w = NULL;
-
- snd_soc_dapm_widget_for_each_source_path(w, p) {
- src_w = p->source;
- if (!p->connect)
- continue;
-
- dev_dbg(skl->dev, "sink widget=%s\n", w->name);
- dev_dbg(skl->dev, "src widget=%s\n", p->source->name);
-
- /*
- * here we will check widgets in sink pipelines, so that can
- * be any widgets type and we are only interested if they are
- * ones used for SKL so check that first
- */
- if ((p->source->priv != NULL) &&
- is_skl_dsp_widget_type(p->source, skl->dev)) {
- return p->source;
- }
- }
-
- if (src_w != NULL)
- return skl_get_src_dsp_widget(src_w, skl);
-
- return NULL;
-}
-
-/*
- * in the Post-PMU event of mixer we need to do following:
- * - Check if this pipe is running
- * - if not, then
- * - bind this pipeline to its source pipeline
- * if source pipe is already running, this means it is a dynamic
- * connection and we need to bind only to that pipe
- * - start this pipeline
- */
-static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
- struct skl_dev *skl)
-{
- int ret = 0;
- struct snd_soc_dapm_widget *source, *sink;
- struct skl_module_cfg *src_mconfig, *sink_mconfig;
- int src_pipe_started = 0;
-
- sink = w;
- sink_mconfig = sink->priv;
-
- /*
- * If source pipe is already started, that means source is driving
- * one more sink before this sink got connected, Since source is
- * started, bind this sink to source and start this pipe.
- */
- source = skl_get_src_dsp_widget(w, skl);
- if (source != NULL) {
- src_mconfig = source->priv;
- sink_mconfig = sink->priv;
- src_pipe_started = 1;
-
- /*
- * check pipe state, then no need to bind or start the
- * pipe
- */
- if (src_mconfig->pipe->state != SKL_PIPE_STARTED)
- src_pipe_started = 0;
- }
-
- if (src_pipe_started) {
- ret = skl_bind_modules(skl, src_mconfig, sink_mconfig);
- if (ret)
- return ret;
-
- /* set module params after bind */
- skl_tplg_set_module_bind_params(source, src_mconfig, skl);
- skl_tplg_set_module_bind_params(sink, sink_mconfig, skl);
-
- if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
- ret = skl_run_pipe(skl, sink_mconfig->pipe);
- }
-
- return ret;
-}
-
-/*
- * in the Pre-PMD event of mixer we need to do following:
- * - Stop the pipe
- * - find the source connections and remove that from dapm_path_list
- * - unbind with source pipelines if still connected
- */
-static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
- struct skl_dev *skl)
-{
- struct skl_module_cfg *src_mconfig, *sink_mconfig;
- int ret = 0, i;
-
- sink_mconfig = w->priv;
-
- /* Stop the pipe */
- ret = skl_stop_pipe(skl, sink_mconfig->pipe);
- if (ret)
- return ret;
-
- for (i = 0; i < sink_mconfig->module->max_input_pins; i++) {
- if (sink_mconfig->m_in_pin[i].pin_state == SKL_PIN_BIND_DONE) {
- src_mconfig = sink_mconfig->m_in_pin[i].tgt_mcfg;
- if (!src_mconfig)
- continue;
-
- ret = skl_unbind_modules(skl,
- src_mconfig, sink_mconfig);
- }
- }
-
- return ret;
-}
-
-/*
- * in the Post-PMD event of mixer we need to do following:
- * - Unbind the modules within the pipeline
- * - Delete the pipeline (modules are not required to be explicitly
- * deleted, pipeline delete is enough here
- */
-static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
- struct skl_dev *skl)
-{
- struct skl_module_cfg *mconfig = w->priv;
- struct skl_pipe_module *w_module;
- struct skl_module_cfg *src_module = NULL, *dst_module;
- struct skl_pipe *s_pipe = mconfig->pipe;
- struct skl_module_deferred_bind *modules, *tmp;
-
- if (s_pipe->state == SKL_PIPE_INVALID)
- return -EINVAL;
-
- list_for_each_entry(w_module, &s_pipe->w_list, node) {
- if (list_empty(&skl->bind_list))
- break;
-
- src_module = w_module->w->priv;
-
- list_for_each_entry_safe(modules, tmp, &skl->bind_list, node) {
- /*
- * When the destination module is deleted, Unbind the
- * modules from deferred bind list.
- */
- if (modules->dst == src_module) {
- skl_unbind_modules(skl, modules->src,
- modules->dst);
- }
-
- /*
- * When the source module is deleted, remove this entry
- * from the deferred bind list.
- */
- if (modules->src == src_module) {
- list_del(&modules->node);
- modules->src = NULL;
- modules->dst = NULL;
- kfree(modules);
- }
- }
- }
-
- list_for_each_entry(w_module, &s_pipe->w_list, node) {
- dst_module = w_module->w->priv;
-
- if (src_module == NULL) {
- src_module = dst_module;
- continue;
- }
-
- skl_unbind_modules(skl, src_module, dst_module);
- src_module = dst_module;
- }
-
- skl_delete_pipe(skl, mconfig->pipe);
-
- list_for_each_entry(w_module, &s_pipe->w_list, node) {
- src_module = w_module->w->priv;
- src_module->m_state = SKL_MODULE_UNINIT;
- }
-
- return skl_tplg_unload_pipe_modules(skl, s_pipe);
-}
-
-/*
- * in the Post-PMD event of PGA we need to do following:
- * - Stop the pipeline
- * - In source pipe is connected, unbind with source pipelines
- */
-static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
- struct skl_dev *skl)
-{
- struct skl_module_cfg *src_mconfig, *sink_mconfig;
- int ret = 0, i;
-
- src_mconfig = w->priv;
-
- /* Stop the pipe since this is a mixin module */
- ret = skl_stop_pipe(skl, src_mconfig->pipe);
- if (ret)
- return ret;
-
- for (i = 0; i < src_mconfig->module->max_output_pins; i++) {
- if (src_mconfig->m_out_pin[i].pin_state == SKL_PIN_BIND_DONE) {
- sink_mconfig = src_mconfig->m_out_pin[i].tgt_mcfg;
- if (!sink_mconfig)
- continue;
- /*
- * This is a connecter and if path is found that means
- * unbind between source and sink has not happened yet
- */
- ret = skl_unbind_modules(skl, src_mconfig,
- sink_mconfig);
- }
- }
-
- return ret;
-}
-
-/*
- * In modelling, we assume there will be ONLY one mixer in a pipeline. If a
- * second one is required that is created as another pipe entity.
- * The mixer is responsible for pipe management and represent a pipeline
- * instance
- */
-static int skl_tplg_mixer_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- struct snd_soc_dapm_context *dapm = w->dapm;
- struct skl_dev *skl = get_skl_ctx(dapm->dev);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- return skl_tplg_mixer_dapm_pre_pmu_event(w, skl);
-
- case SND_SOC_DAPM_POST_PMU:
- return skl_tplg_mixer_dapm_post_pmu_event(w, skl);
-
- case SND_SOC_DAPM_PRE_PMD:
- return skl_tplg_mixer_dapm_pre_pmd_event(w, skl);
-
- case SND_SOC_DAPM_POST_PMD:
- return skl_tplg_mixer_dapm_post_pmd_event(w, skl);
- }
-
- return 0;
-}
-
-/*
- * In modelling, we assumed rest of the modules in pipeline are PGA. But we
- * are interested in last PGA (leaf PGA) in a pipeline to disconnect with
- * the sink when it is running (two FE to one BE or one FE to two BE)
- * scenarios
- */
-static int skl_tplg_pga_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-
-{
- struct snd_soc_dapm_context *dapm = w->dapm;
- struct skl_dev *skl = get_skl_ctx(dapm->dev);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- return skl_tplg_pga_dapm_pre_pmu_event(w, skl);
-
- case SND_SOC_DAPM_POST_PMD:
- return skl_tplg_pga_dapm_post_pmd_event(w, skl);
- }
-
- return 0;
-}
-
-static int skl_tplg_multi_config_set_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol,
- bool is_set)
-{
- struct snd_soc_component *component =
- snd_soc_kcontrol_component(kcontrol);
- struct hdac_bus *bus = snd_soc_component_get_drvdata(component);
- struct skl_dev *skl = bus_to_skl(bus);
- struct skl_pipeline *ppl;
- struct skl_pipe *pipe = NULL;
- struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
- u32 *pipe_id;
-
- if (!ec)
- return -EINVAL;
-
- if (is_set && ucontrol->value.enumerated.item[0] > ec->items)
- return -EINVAL;
-
- pipe_id = ec->dobj.private;
-
- list_for_each_entry(ppl, &skl->ppl_list, node) {
- if (ppl->pipe->ppl_id == *pipe_id) {
- pipe = ppl->pipe;
- break;
- }
- }
- if (!pipe)
- return -EIO;
-
- if (is_set)
- skl_tplg_set_pipe_config_idx(pipe, ucontrol->value.enumerated.item[0]);
- else
- ucontrol->value.enumerated.item[0] = pipe->cur_config_idx;
-
- return 0;
-}
-
-static int skl_tplg_multi_config_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- return skl_tplg_multi_config_set_get(kcontrol, ucontrol, false);
-}
-
-static int skl_tplg_multi_config_set(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- return skl_tplg_multi_config_set_get(kcontrol, ucontrol, true);
-}
-
-static int skl_tplg_multi_config_get_dmic(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- return skl_tplg_multi_config_set_get(kcontrol, ucontrol, false);
-}
-
-static int skl_tplg_multi_config_set_dmic(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- return skl_tplg_multi_config_set_get(kcontrol, ucontrol, true);
-}
-
-static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol,
- unsigned int __user *data, unsigned int size)
-{
- struct soc_bytes_ext *sb =
- (struct soc_bytes_ext *)kcontrol->private_value;
- struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private;
- struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
- struct skl_module_cfg *mconfig = w->priv;
- struct skl_dev *skl = get_skl_ctx(w->dapm->dev);
-
- if (w->power)
- skl_get_module_params(skl, (u32 *)bc->params,
- bc->size, bc->param_id, mconfig);
-
- /* decrement size for TLV header */
- size -= 2 * sizeof(u32);
-
- /* check size as we don't want to send kernel data */
- if (size > bc->max)
- size = bc->max;
-
- if (bc->params) {
- if (copy_to_user(data, &bc->param_id, sizeof(u32)))
- return -EFAULT;
- if (copy_to_user(data + 1, &size, sizeof(u32)))
- return -EFAULT;
- if (copy_to_user(data + 2, bc->params, size))
- return -EFAULT;
- }
-
- return 0;
-}
-
-#define SKL_PARAM_VENDOR_ID 0xff
-
-static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
- const unsigned int __user *data, unsigned int size)
-{
- struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
- struct skl_module_cfg *mconfig = w->priv;
- struct soc_bytes_ext *sb =
- (struct soc_bytes_ext *)kcontrol->private_value;
- struct skl_algo_data *ac = (struct skl_algo_data *)sb->dobj.private;
- struct skl_dev *skl = get_skl_ctx(w->dapm->dev);
-
- if (ac->params) {
- if (size > ac->max)
- return -EINVAL;
- ac->size = size;
-
- if (copy_from_user(ac->params, data, size))
- return -EFAULT;
-
- if (w->power)
- return skl_set_module_params(skl,
- (u32 *)ac->params, ac->size,
- ac->param_id, mconfig);
- }
-
- return 0;
-}
-
-static int skl_tplg_mic_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
- struct skl_module_cfg *mconfig = w->priv;
- struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
- u32 ch_type = *((u32 *)ec->dobj.private);
-
- if (mconfig->dmic_ch_type == ch_type)
- ucontrol->value.enumerated.item[0] =
- mconfig->dmic_ch_combo_index;
- else
- ucontrol->value.enumerated.item[0] = 0;
-
- return 0;
-}
-
-static int skl_fill_mic_sel_params(struct skl_module_cfg *mconfig,
- struct skl_mic_sel_config *mic_cfg, struct device *dev)
-{
- struct skl_specific_cfg *sp_cfg =
- &mconfig->formats_config[SKL_PARAM_INIT];
-
- sp_cfg->caps_size = sizeof(struct skl_mic_sel_config);
- sp_cfg->set_params = SKL_PARAM_SET;
- sp_cfg->param_id = 0x00;
- if (!sp_cfg->caps) {
- sp_cfg->caps = devm_kzalloc(dev, sp_cfg->caps_size, GFP_KERNEL);
- if (!sp_cfg->caps)
- return -ENOMEM;
- }
-
- mic_cfg->mic_switch = SKL_MIC_SEL_SWITCH;
- mic_cfg->flags = 0;
- memcpy(sp_cfg->caps, mic_cfg, sp_cfg->caps_size);
-
- return 0;
-}
-
-static int skl_tplg_mic_control_set(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
- struct skl_module_cfg *mconfig = w->priv;
- struct skl_mic_sel_config mic_cfg = {0};
- struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
- u32 ch_type = *((u32 *)ec->dobj.private);
- const int *list;
- u8 in_ch, out_ch, index;
-
- mconfig->dmic_ch_type = ch_type;
- mconfig->dmic_ch_combo_index = ucontrol->value.enumerated.item[0];
-
- /* enum control index 0 is INVALID, so no channels to be set */
- if (mconfig->dmic_ch_combo_index == 0)
- return 0;
-
- /* No valid channel selection map for index 0, so offset by 1 */
- index = mconfig->dmic_ch_combo_index - 1;
-
- switch (ch_type) {
- case SKL_CH_MONO:
- if (mconfig->dmic_ch_combo_index > ARRAY_SIZE(mic_mono_list))
- return -EINVAL;
-
- list = &mic_mono_list[index];
- break;
-
- case SKL_CH_STEREO:
- if (mconfig->dmic_ch_combo_index > ARRAY_SIZE(mic_stereo_list))
- return -EINVAL;
-
- list = mic_stereo_list[index];
- break;
-
- case SKL_CH_TRIO:
- if (mconfig->dmic_ch_combo_index > ARRAY_SIZE(mic_trio_list))
- return -EINVAL;
-
- list = mic_trio_list[index];
- break;
-
- case SKL_CH_QUATRO:
- if (mconfig->dmic_ch_combo_index > ARRAY_SIZE(mic_quatro_list))
- return -EINVAL;
-
- list = mic_quatro_list[index];
- break;
-
- default:
- dev_err(w->dapm->dev,
- "Invalid channel %d for mic_select module\n",
- ch_type);
- return -EINVAL;
-
- }
-
- /* channel type enum map to number of chanels for that type */
- for (out_ch = 0; out_ch < ch_type; out_ch++) {
- in_ch = list[out_ch];
- mic_cfg.blob[out_ch][in_ch] = SKL_DEFAULT_MIC_SEL_GAIN;
- }
-
- return skl_fill_mic_sel_params(mconfig, &mic_cfg, w->dapm->dev);
-}
-
-/*
- * Fill the dma id for host and link. In case of passthrough
- * pipeline, this will both host and link in the same
- * pipeline, so need to copy the link and host based on dev_type
- */
-static void skl_tplg_fill_dma_id(struct skl_module_cfg *mcfg,
- struct skl_pipe_params *params)
-{
- struct skl_pipe *pipe = mcfg->pipe;
-
- if (pipe->passthru) {
- switch (mcfg->dev_type) {
- case SKL_DEVICE_HDALINK:
- pipe->p_params->link_dma_id = params->link_dma_id;
- pipe->p_params->link_index = params->link_index;
- pipe->p_params->link_bps = params->link_bps;
- break;
-
- case SKL_DEVICE_HDAHOST:
- pipe->p_params->host_dma_id = params->host_dma_id;
- pipe->p_params->host_bps = params->host_bps;
- break;
-
- default:
- break;
- }
- pipe->p_params->s_fmt = params->s_fmt;
- pipe->p_params->ch = params->ch;
- pipe->p_params->s_freq = params->s_freq;
- pipe->p_params->stream = params->stream;
- pipe->p_params->format = params->format;
-
- } else {
- memcpy(pipe->p_params, params, sizeof(*params));
- }
-}
-
-/*
- * The FE params are passed by hw_params of the DAI.
- * On hw_params, the params are stored in Gateway module of the FE and we
- * need to calculate the format in DSP module configuration, that
- * conversion is done here
- */
-int skl_tplg_update_pipe_params(struct device *dev,
- struct skl_module_cfg *mconfig,
- struct skl_pipe_params *params)
-{
- struct skl_module_res *res;
- struct skl_dev *skl = get_skl_ctx(dev);
- struct skl_module_fmt *format = NULL;
- u8 cfg_idx = mconfig->pipe->cur_config_idx;
-
- res = &mconfig->module->resources[mconfig->res_idx];
- skl_tplg_fill_dma_id(mconfig, params);
- mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx;
- mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx;
-
- if (skl->nr_modules)
- return 0;
-
- if (params->stream == SNDRV_PCM_STREAM_PLAYBACK)
- format = &mconfig->module->formats[mconfig->fmt_idx].inputs[0].fmt;
- else
- format = &mconfig->module->formats[mconfig->fmt_idx].outputs[0].fmt;
-
- /* set the hw_params */
- format->s_freq = params->s_freq;
- format->channels = params->ch;
- format->valid_bit_depth = skl_get_bit_depth(params->s_fmt);
-
- /*
- * 16 bit is 16 bit container whereas 24 bit is in 32 bit
- * container so update bit depth accordingly
- */
- switch (format->valid_bit_depth) {
- case SKL_DEPTH_16BIT:
- format->bit_depth = format->valid_bit_depth;
- break;
-
- case SKL_DEPTH_24BIT:
- case SKL_DEPTH_32BIT:
- format->bit_depth = SKL_DEPTH_32BIT;
- break;
-
- default:
- dev_err(dev, "Invalid bit depth %x for pipe\n",
- format->valid_bit_depth);
- return -EINVAL;
- }
-
- if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- res->ibs = (format->s_freq / 1000) *
- (format->channels) *
- (format->bit_depth >> 3);
- } else {
- res->obs = (format->s_freq / 1000) *
- (format->channels) *
- (format->bit_depth >> 3);
- }
-
- return 0;
-}
-
-/*
- * Query the module config for the FE DAI
- * This is used to find the hw_params set for that DAI and apply to FE
- * pipeline
- */
-struct skl_module_cfg *
-skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
-{
- struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(dai, stream);
- struct snd_soc_dapm_path *p = NULL;
-
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- snd_soc_dapm_widget_for_each_sink_path(w, p) {
- if (p->connect && p->sink->power &&
- !is_skl_dsp_widget_type(p->sink, dai->dev))
- continue;
-
- if (p->sink->priv) {
- dev_dbg(dai->dev, "set params for %s\n",
- p->sink->name);
- return p->sink->priv;
- }
- }
- } else {
- snd_soc_dapm_widget_for_each_source_path(w, p) {
- if (p->connect && p->source->power &&
- !is_skl_dsp_widget_type(p->source, dai->dev))
- continue;
-
- if (p->source->priv) {
- dev_dbg(dai->dev, "set params for %s\n",
- p->source->name);
- return p->source->priv;
- }
- }
- }
-
- return NULL;
-}
-
-static struct skl_module_cfg *skl_get_mconfig_pb_cpr(
- struct snd_soc_dai *dai, struct snd_soc_dapm_widget *w)
-{
- struct snd_soc_dapm_path *p;
- struct skl_module_cfg *mconfig = NULL;
-
- snd_soc_dapm_widget_for_each_source_path(w, p) {
- if (w->endpoints[SND_SOC_DAPM_DIR_OUT] > 0) {
- if (p->connect &&
- (p->sink->id == snd_soc_dapm_aif_out) &&
- p->source->priv) {
- mconfig = p->source->priv;
- return mconfig;
- }
- mconfig = skl_get_mconfig_pb_cpr(dai, p->source);
- if (mconfig)
- return mconfig;
- }
- }
- return mconfig;
-}
-
-static struct skl_module_cfg *skl_get_mconfig_cap_cpr(
- struct snd_soc_dai *dai, struct snd_soc_dapm_widget *w)
-{
- struct snd_soc_dapm_path *p;
- struct skl_module_cfg *mconfig = NULL;
-
- snd_soc_dapm_widget_for_each_sink_path(w, p) {
- if (w->endpoints[SND_SOC_DAPM_DIR_IN] > 0) {
- if (p->connect &&
- (p->source->id == snd_soc_dapm_aif_in) &&
- p->sink->priv) {
- mconfig = p->sink->priv;
- return mconfig;
- }
- mconfig = skl_get_mconfig_cap_cpr(dai, p->sink);
- if (mconfig)
- return mconfig;
- }
- }
- return mconfig;
-}
-
-struct skl_module_cfg *
-skl_tplg_be_get_cpr_module(struct snd_soc_dai *dai, int stream)
-{
- struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(dai, stream);
- struct skl_module_cfg *mconfig;
-
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- mconfig = skl_get_mconfig_pb_cpr(dai, w);
- } else {
- mconfig = skl_get_mconfig_cap_cpr(dai, w);
- }
- return mconfig;
-}
-
-static u8 skl_tplg_be_link_type(int dev_type)
-{
- int ret;
-
- switch (dev_type) {
- case SKL_DEVICE_BT:
- ret = NHLT_LINK_SSP;
- break;
-
- case SKL_DEVICE_DMIC:
- ret = NHLT_LINK_DMIC;
- break;
-
- case SKL_DEVICE_I2S:
- ret = NHLT_LINK_SSP;
- break;
-
- case SKL_DEVICE_HDALINK:
- ret = NHLT_LINK_HDA;
- break;
-
- default:
- ret = NHLT_LINK_INVALID;
- break;
- }
-
- return ret;
-}
-
-/*
- * Fill the BE gateway parameters
- * The BE gateway expects a blob of parameters which are kept in the ACPI
- * NHLT blob, so query the blob for interface type (i2s/pdm) and instance.
- * The port can have multiple settings so pick based on the pipeline
- * parameters
- */
-static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
- struct skl_module_cfg *mconfig,
- struct skl_pipe_params *params)
-{
- struct nhlt_specific_cfg *cfg;
- struct skl_pipe *pipe = mconfig->pipe;
- struct skl_pipe_params save = *pipe->p_params;
- struct skl_pipe_fmt *pipe_fmt;
- struct skl_dev *skl = get_skl_ctx(dai->dev);
- int link_type = skl_tplg_be_link_type(mconfig->dev_type);
- u8 dev_type = skl_tplg_be_dev_type(mconfig->dev_type);
- int ret;
-
- skl_tplg_fill_dma_id(mconfig, params);
-
- if (link_type == NHLT_LINK_HDA)
- return 0;
-
- *pipe->p_params = *params;
- ret = skl_tplg_get_pipe_config(skl, mconfig);
- if (ret)
- goto err;
-
- dev_dbg(skl->dev, "%s using pipe config: %d\n", __func__, pipe->cur_config_idx);
- if (pipe->direction == SNDRV_PCM_STREAM_PLAYBACK)
- pipe_fmt = &pipe->configs[pipe->cur_config_idx].out_fmt;
- else
- pipe_fmt = &pipe->configs[pipe->cur_config_idx].in_fmt;
-
- /* update the blob based on virtual bus_id*/
- cfg = intel_nhlt_get_endpoint_blob(dai->dev, skl->nhlt,
- mconfig->vbus_id, link_type,
- pipe_fmt->bps, params->s_cont,
- pipe_fmt->channels, pipe_fmt->freq,
- pipe->direction, dev_type);
- if (cfg) {
- mconfig->formats_config[SKL_PARAM_INIT].caps_size = cfg->size;
- mconfig->formats_config[SKL_PARAM_INIT].caps = (u32 *)&cfg->caps;
- } else {
- dev_err(dai->dev, "Blob NULL for id:%d type:%d dirn:%d ch:%d, freq:%d, fmt:%d\n",
- mconfig->vbus_id, link_type, params->stream,
- params->ch, params->s_freq, params->s_fmt);
- ret = -EINVAL;
- goto err;
- }
-
- return 0;
-
-err:
- *pipe->p_params = save;
- return ret;
-}
-
-static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai,
- struct snd_soc_dapm_widget *w,
- struct skl_pipe_params *params)
-{
- struct snd_soc_dapm_path *p;
- int ret = -EIO;
-
- snd_soc_dapm_widget_for_each_source_path(w, p) {
- if (p->connect && is_skl_dsp_widget_type(p->source, dai->dev) &&
- p->source->priv) {
-
- ret = skl_tplg_be_fill_pipe_params(dai,
- p->source->priv, params);
- if (ret < 0)
- return ret;
- } else {
- ret = skl_tplg_be_set_src_pipe_params(dai,
- p->source, params);
- if (ret < 0)
- return ret;
- }
- }
-
- return ret;
-}
-
-static int skl_tplg_be_set_sink_pipe_params(struct snd_soc_dai *dai,
- struct snd_soc_dapm_widget *w, struct skl_pipe_params *params)
-{
- struct snd_soc_dapm_path *p;
- int ret = -EIO;
-
- snd_soc_dapm_widget_for_each_sink_path(w, p) {
- if (p->connect && is_skl_dsp_widget_type(p->sink, dai->dev) &&
- p->sink->priv) {
-
- ret = skl_tplg_be_fill_pipe_params(dai,
- p->sink->priv, params);
- if (ret < 0)
- return ret;
- } else {
- ret = skl_tplg_be_set_sink_pipe_params(
- dai, p->sink, params);
- if (ret < 0)
- return ret;
- }
- }
-
- return ret;
-}
-
-/*
- * BE hw_params can be a source parameters (capture) or sink parameters
- * (playback). Based on sink and source we need to either find the source
- * list or the sink list and set the pipeline parameters
- */
-int skl_tplg_be_update_params(struct snd_soc_dai *dai,
- struct skl_pipe_params *params)
-{
- struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(dai, params->stream);
-
- if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- return skl_tplg_be_set_src_pipe_params(dai, w, params);
- } else {
- return skl_tplg_be_set_sink_pipe_params(dai, w, params);
- }
-}
-
-static const struct snd_soc_tplg_widget_events skl_tplg_widget_ops[] = {
- {SKL_MIXER_EVENT, skl_tplg_mixer_event},
- {SKL_VMIXER_EVENT, skl_tplg_mixer_event},
- {SKL_PGA_EVENT, skl_tplg_pga_event},
-};
-
-static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = {
- {SKL_CONTROL_TYPE_BYTE_TLV, skl_tplg_tlv_control_get,
- skl_tplg_tlv_control_set},
-};
-
-static const struct snd_soc_tplg_kcontrol_ops skl_tplg_kcontrol_ops[] = {
- {
- .id = SKL_CONTROL_TYPE_MIC_SELECT,
- .get = skl_tplg_mic_control_get,
- .put = skl_tplg_mic_control_set,
- },
- {
- .id = SKL_CONTROL_TYPE_MULTI_IO_SELECT,
- .get = skl_tplg_multi_config_get,
- .put = skl_tplg_multi_config_set,
- },
- {
- .id = SKL_CONTROL_TYPE_MULTI_IO_SELECT_DMIC,
- .get = skl_tplg_multi_config_get_dmic,
- .put = skl_tplg_multi_config_set_dmic,
- }
-};
-
-static int skl_tplg_fill_pipe_cfg(struct device *dev,
- struct skl_pipe *pipe, u32 tkn,
- u32 tkn_val, int conf_idx, int dir)
-{
- struct skl_pipe_fmt *fmt;
- struct skl_path_config *config;
-
- switch (dir) {
- case SKL_DIR_IN:
- fmt = &pipe->configs[conf_idx].in_fmt;
- break;
-
- case SKL_DIR_OUT:
- fmt = &pipe->configs[conf_idx].out_fmt;
- break;
-
- default:
- dev_err(dev, "Invalid direction: %d\n", dir);
- return -EINVAL;
- }
-
- config = &pipe->configs[conf_idx];
-
- switch (tkn) {
- case SKL_TKN_U32_CFG_FREQ:
- fmt->freq = tkn_val;
- break;
-
- case SKL_TKN_U8_CFG_CHAN:
- fmt->channels = tkn_val;
- break;
-
- case SKL_TKN_U8_CFG_BPS:
- fmt->bps = tkn_val;
- break;
-
- case SKL_TKN_U32_PATH_MEM_PGS:
- config->mem_pages = tkn_val;
- break;
-
- default:
- dev_err(dev, "Invalid token config: %d\n", tkn);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int skl_tplg_fill_pipe_tkn(struct device *dev,
- struct skl_pipe *pipe, u32 tkn,
- u32 tkn_val)
-{
-
- switch (tkn) {
- case SKL_TKN_U32_PIPE_CONN_TYPE:
- pipe->conn_type = tkn_val;
- break;
-
- case SKL_TKN_U32_PIPE_PRIORITY:
- pipe->pipe_priority = tkn_val;
- break;
-
- case SKL_TKN_U32_PIPE_MEM_PGS:
- pipe->memory_pages = tkn_val;
- break;
-
- case SKL_TKN_U32_PMODE:
- pipe->lp_mode = tkn_val;
- break;
-
- case SKL_TKN_U32_PIPE_DIRECTION:
- pipe->direction = tkn_val;
- break;
-
- case SKL_TKN_U32_NUM_CONFIGS:
- pipe->nr_cfgs = tkn_val;
- break;
-
- default:
- dev_err(dev, "Token not handled %d\n", tkn);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * Add pipeline by parsing the relevant tokens
- * Return an existing pipe if the pipe already exists.
- */
-static int skl_tplg_add_pipe(struct device *dev,
- struct skl_module_cfg *mconfig, struct skl_dev *skl,
- struct snd_soc_tplg_vendor_value_elem *tkn_elem)
-{
- struct skl_pipeline *ppl;
- struct skl_pipe *pipe;
- struct skl_pipe_params *params;
-
- list_for_each_entry(ppl, &skl->ppl_list, node) {
- if (ppl->pipe->ppl_id == tkn_elem->value) {
- mconfig->pipe = ppl->pipe;
- return -EEXIST;
- }
- }
-
- ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL);
- if (!ppl)
- return -ENOMEM;
-
- pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL);
- if (!pipe)
- return -ENOMEM;
-
- params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
- if (!params)
- return -ENOMEM;
-
- pipe->p_params = params;
- pipe->ppl_id = tkn_elem->value;
- INIT_LIST_HEAD(&pipe->w_list);
-
- ppl->pipe = pipe;
- list_add(&ppl->node, &skl->ppl_list);
-
- mconfig->pipe = pipe;
- mconfig->pipe->state = SKL_PIPE_INVALID;
-
- return 0;
-}
-
-static int skl_tplg_get_uuid(struct device *dev, guid_t *guid,
- struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
-{
- if (uuid_tkn->token == SKL_TKN_UUID) {
- import_guid(guid, uuid_tkn->uuid);
- return 0;
- }
-
- dev_err(dev, "Not an UUID token %d\n", uuid_tkn->token);
-
- return -EINVAL;
-}
-
-static int skl_tplg_fill_pin(struct device *dev,
- struct snd_soc_tplg_vendor_value_elem *tkn_elem,
- struct skl_module_pin *m_pin,
- int pin_index)
-{
- int ret;
-
- switch (tkn_elem->token) {
- case SKL_TKN_U32_PIN_MOD_ID:
- m_pin[pin_index].id.module_id = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_PIN_INST_ID:
- m_pin[pin_index].id.instance_id = tkn_elem->value;
- break;
-
- case SKL_TKN_UUID:
- ret = skl_tplg_get_uuid(dev, &m_pin[pin_index].id.mod_uuid,
- (struct snd_soc_tplg_vendor_uuid_elem *)tkn_elem);
- if (ret < 0)
- return ret;
-
- break;
-
- default:
- dev_err(dev, "%d Not a pin token\n", tkn_elem->token);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * Parse for pin config specific tokens to fill up the
- * module private data
- */
-static int skl_tplg_fill_pins_info(struct device *dev,
- struct skl_module_cfg *mconfig,
- struct snd_soc_tplg_vendor_value_elem *tkn_elem,
- int dir, int pin_count)
-{
- int ret;
- struct skl_module_pin *m_pin;
-
- switch (dir) {
- case SKL_DIR_IN:
- m_pin = mconfig->m_in_pin;
- break;
-
- case SKL_DIR_OUT:
- m_pin = mconfig->m_out_pin;
- break;
-
- default:
- dev_err(dev, "Invalid direction value\n");
- return -EINVAL;
- }
-
- ret = skl_tplg_fill_pin(dev, tkn_elem, m_pin, pin_count);
- if (ret < 0)
- return ret;
-
- m_pin[pin_count].in_use = false;
- m_pin[pin_count].pin_state = SKL_PIN_UNBIND;
-
- return 0;
-}
-
-/*
- * Fill up input/output module config format based
- * on the direction
- */
-static int skl_tplg_fill_fmt(struct device *dev,
- struct skl_module_fmt *dst_fmt,
- u32 tkn, u32 value)
-{
- switch (tkn) {
- case SKL_TKN_U32_FMT_CH:
- dst_fmt->channels = value;
- break;
-
- case SKL_TKN_U32_FMT_FREQ:
- dst_fmt->s_freq = value;
- break;
-
- case SKL_TKN_U32_FMT_BIT_DEPTH:
- dst_fmt->bit_depth = value;
- break;
-
- case SKL_TKN_U32_FMT_SAMPLE_SIZE:
- dst_fmt->valid_bit_depth = value;
- break;
-
- case SKL_TKN_U32_FMT_CH_CONFIG:
- dst_fmt->ch_cfg = value;
- break;
-
- case SKL_TKN_U32_FMT_INTERLEAVE:
- dst_fmt->interleaving_style = value;
- break;
-
- case SKL_TKN_U32_FMT_SAMPLE_TYPE:
- dst_fmt->sample_type = value;
- break;
-
- case SKL_TKN_U32_FMT_CH_MAP:
- dst_fmt->ch_map = value;
- break;
-
- default:
- dev_err(dev, "Invalid token %d\n", tkn);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int skl_tplg_widget_fill_fmt(struct device *dev,
- struct skl_module_iface *fmt,
- u32 tkn, u32 val, u32 dir, int fmt_idx)
-{
- struct skl_module_fmt *dst_fmt;
-
- if (!fmt)
- return -EINVAL;
-
- switch (dir) {
- case SKL_DIR_IN:
- dst_fmt = &fmt->inputs[fmt_idx].fmt;
- break;
-
- case SKL_DIR_OUT:
- dst_fmt = &fmt->outputs[fmt_idx].fmt;
- break;
-
- default:
- dev_err(dev, "Invalid direction: %d\n", dir);
- return -EINVAL;
- }
-
- return skl_tplg_fill_fmt(dev, dst_fmt, tkn, val);
-}
-
-static void skl_tplg_fill_pin_dynamic_val(
- struct skl_module_pin *mpin, u32 pin_count, u32 value)
-{
- int i;
-
- for (i = 0; i < pin_count; i++)
- mpin[i].is_dynamic = value;
-}
-
-/*
- * Resource table in the manifest has pin specific resources
- * like pin and pin buffer size
- */
-static int skl_tplg_manifest_pin_res_tkn(struct device *dev,
- struct snd_soc_tplg_vendor_value_elem *tkn_elem,
- struct skl_module_res *res, int pin_idx, int dir)
-{
- struct skl_module_pin_resources *m_pin;
-
- switch (dir) {
- case SKL_DIR_IN:
- m_pin = &res->input[pin_idx];
- break;
-
- case SKL_DIR_OUT:
- m_pin = &res->output[pin_idx];
- break;
-
- default:
- dev_err(dev, "Invalid pin direction: %d\n", dir);
- return -EINVAL;
- }
-
- switch (tkn_elem->token) {
- case SKL_TKN_MM_U32_RES_PIN_ID:
- m_pin->pin_index = tkn_elem->value;
- break;
-
- case SKL_TKN_MM_U32_PIN_BUF:
- m_pin->buf_size = tkn_elem->value;
- break;
-
- default:
- dev_err(dev, "Invalid token: %d\n", tkn_elem->token);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * Fill module specific resources from the manifest's resource
- * table like CPS, DMA size, mem_pages.
- */
-static int skl_tplg_fill_res_tkn(struct device *dev,
- struct snd_soc_tplg_vendor_value_elem *tkn_elem,
- struct skl_module_res *res,
- int pin_idx, int dir)
-{
- int ret, tkn_count = 0;
-
- if (!res)
- return -EINVAL;
-
- switch (tkn_elem->token) {
- case SKL_TKN_MM_U32_DMA_SIZE:
- res->dma_buffer_size = tkn_elem->value;
- break;
-
- case SKL_TKN_MM_U32_CPC:
- res->cpc = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_MEM_PAGES:
- res->is_pages = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_OBS:
- res->obs = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_IBS:
- res->ibs = tkn_elem->value;
- break;
-
- case SKL_TKN_MM_U32_RES_PIN_ID:
- case SKL_TKN_MM_U32_PIN_BUF:
- ret = skl_tplg_manifest_pin_res_tkn(dev, tkn_elem, res,
- pin_idx, dir);
- if (ret < 0)
- return ret;
- break;
-
- case SKL_TKN_MM_U32_CPS:
- case SKL_TKN_U32_MAX_MCPS:
- /* ignore unused tokens */
- break;
-
- default:
- dev_err(dev, "Not a res type token: %d", tkn_elem->token);
- return -EINVAL;
-
- }
- tkn_count++;
-
- return tkn_count;
-}
-
-/*
- * Parse tokens to fill up the module private data
- */
-static int skl_tplg_get_token(struct device *dev,
- struct snd_soc_tplg_vendor_value_elem *tkn_elem,
- struct skl_dev *skl, struct skl_module_cfg *mconfig)
-{
- int tkn_count = 0;
- int ret;
- static int is_pipe_exists;
- static int pin_index, dir, conf_idx;
- struct skl_module_iface *iface = NULL;
- struct skl_module_res *res = NULL;
- int res_idx = mconfig->res_idx;
- int fmt_idx = mconfig->fmt_idx;
-
- /*
- * If the manifest structure contains no modules, fill all
- * the module data to 0th index.
- * res_idx and fmt_idx are default set to 0.
- */
- if (skl->nr_modules == 0) {
- res = &mconfig->module->resources[res_idx];
- iface = &mconfig->module->formats[fmt_idx];
- }
-
- if (tkn_elem->token > SKL_TKN_MAX)
- return -EINVAL;
-
- switch (tkn_elem->token) {
- case SKL_TKN_U8_IN_QUEUE_COUNT:
- mconfig->module->max_input_pins = tkn_elem->value;
- break;
-
- case SKL_TKN_U8_OUT_QUEUE_COUNT:
- mconfig->module->max_output_pins = tkn_elem->value;
- break;
-
- case SKL_TKN_U8_DYN_IN_PIN:
- if (!mconfig->m_in_pin)
- mconfig->m_in_pin =
- devm_kcalloc(dev, MAX_IN_QUEUE,
- sizeof(*mconfig->m_in_pin),
- GFP_KERNEL);
- if (!mconfig->m_in_pin)
- return -ENOMEM;
-
- skl_tplg_fill_pin_dynamic_val(mconfig->m_in_pin, MAX_IN_QUEUE,
- tkn_elem->value);
- break;
-
- case SKL_TKN_U8_DYN_OUT_PIN:
- if (!mconfig->m_out_pin)
- mconfig->m_out_pin =
- devm_kcalloc(dev, MAX_IN_QUEUE,
- sizeof(*mconfig->m_in_pin),
- GFP_KERNEL);
- if (!mconfig->m_out_pin)
- return -ENOMEM;
-
- skl_tplg_fill_pin_dynamic_val(mconfig->m_out_pin, MAX_OUT_QUEUE,
- tkn_elem->value);
- break;
-
- case SKL_TKN_U8_TIME_SLOT:
- mconfig->time_slot = tkn_elem->value;
- break;
-
- case SKL_TKN_U8_CORE_ID:
- mconfig->core_id = tkn_elem->value;
- break;
-
- case SKL_TKN_U8_MOD_TYPE:
- mconfig->m_type = tkn_elem->value;
- break;
-
- case SKL_TKN_U8_DEV_TYPE:
- mconfig->dev_type = tkn_elem->value;
- break;
-
- case SKL_TKN_U8_HW_CONN_TYPE:
- mconfig->hw_conn_type = tkn_elem->value;
- break;
-
- case SKL_TKN_U16_MOD_INST_ID:
- mconfig->id.instance_id =
- tkn_elem->value;
- break;
-
- case SKL_TKN_U32_MEM_PAGES:
- case SKL_TKN_U32_MAX_MCPS:
- case SKL_TKN_U32_OBS:
- case SKL_TKN_U32_IBS:
- ret = skl_tplg_fill_res_tkn(dev, tkn_elem, res, pin_index, dir);
- if (ret < 0)
- return ret;
-
- break;
-
- case SKL_TKN_U32_VBUS_ID:
- mconfig->vbus_id = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_PARAMS_FIXUP:
- mconfig->params_fixup = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_CONVERTER:
- mconfig->converter = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_D0I3_CAPS:
- mconfig->d0i3_caps = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_PIPE_ID:
- ret = skl_tplg_add_pipe(dev,
- mconfig, skl, tkn_elem);
-
- if (ret < 0) {
- if (ret == -EEXIST) {
- is_pipe_exists = 1;
- break;
- }
- return is_pipe_exists;
- }
-
- break;
-
- case SKL_TKN_U32_PIPE_CONFIG_ID:
- conf_idx = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_PIPE_CONN_TYPE:
- case SKL_TKN_U32_PIPE_PRIORITY:
- case SKL_TKN_U32_PIPE_MEM_PGS:
- case SKL_TKN_U32_PMODE:
- case SKL_TKN_U32_PIPE_DIRECTION:
- case SKL_TKN_U32_NUM_CONFIGS:
- if (is_pipe_exists) {
- ret = skl_tplg_fill_pipe_tkn(dev, mconfig->pipe,
- tkn_elem->token, tkn_elem->value);
- if (ret < 0)
- return ret;
- }
-
- break;
-
- case SKL_TKN_U32_PATH_MEM_PGS:
- case SKL_TKN_U32_CFG_FREQ:
- case SKL_TKN_U8_CFG_CHAN:
- case SKL_TKN_U8_CFG_BPS:
- if (mconfig->pipe->nr_cfgs) {
- ret = skl_tplg_fill_pipe_cfg(dev, mconfig->pipe,
- tkn_elem->token, tkn_elem->value,
- conf_idx, dir);
- if (ret < 0)
- return ret;
- }
- break;
-
- case SKL_TKN_CFG_MOD_RES_ID:
- mconfig->mod_cfg[conf_idx].res_idx = tkn_elem->value;
- break;
-
- case SKL_TKN_CFG_MOD_FMT_ID:
- mconfig->mod_cfg[conf_idx].fmt_idx = tkn_elem->value;
- break;
-
- /*
- * SKL_TKN_U32_DIR_PIN_COUNT token has the value for both
- * direction and the pin count. The first four bits represent
- * direction and next four the pin count.
- */
- case SKL_TKN_U32_DIR_PIN_COUNT:
- dir = tkn_elem->value & SKL_IN_DIR_BIT_MASK;
- pin_index = (tkn_elem->value &
- SKL_PIN_COUNT_MASK) >> 4;
-
- break;
-
- case SKL_TKN_U32_FMT_CH:
- case SKL_TKN_U32_FMT_FREQ:
- case SKL_TKN_U32_FMT_BIT_DEPTH:
- case SKL_TKN_U32_FMT_SAMPLE_SIZE:
- case SKL_TKN_U32_FMT_CH_CONFIG:
- case SKL_TKN_U32_FMT_INTERLEAVE:
- case SKL_TKN_U32_FMT_SAMPLE_TYPE:
- case SKL_TKN_U32_FMT_CH_MAP:
- ret = skl_tplg_widget_fill_fmt(dev, iface, tkn_elem->token,
- tkn_elem->value, dir, pin_index);
-
- if (ret < 0)
- return ret;
-
- break;
-
- case SKL_TKN_U32_PIN_MOD_ID:
- case SKL_TKN_U32_PIN_INST_ID:
- case SKL_TKN_UUID:
- ret = skl_tplg_fill_pins_info(dev,
- mconfig, tkn_elem, dir,
- pin_index);
- if (ret < 0)
- return ret;
-
- break;
-
- case SKL_TKN_U32_FMT_CFG_IDX:
- if (tkn_elem->value > SKL_MAX_PARAMS_TYPES)
- return -EINVAL;
-
- mconfig->fmt_cfg_idx = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_CAPS_SIZE:
- mconfig->formats_config[mconfig->fmt_cfg_idx].caps_size =
- tkn_elem->value;
-
- break;
-
- case SKL_TKN_U32_CAPS_SET_PARAMS:
- mconfig->formats_config[mconfig->fmt_cfg_idx].set_params =
- tkn_elem->value;
- break;
-
- case SKL_TKN_U32_CAPS_PARAMS_ID:
- mconfig->formats_config[mconfig->fmt_cfg_idx].param_id =
- tkn_elem->value;
- break;
-
- case SKL_TKN_U32_PROC_DOMAIN:
- mconfig->domain =
- tkn_elem->value;
-
- break;
-
- case SKL_TKN_U32_DMA_BUF_SIZE:
- mconfig->dma_buffer_size = tkn_elem->value;
- break;
-
- case SKL_TKN_U8_IN_PIN_TYPE:
- case SKL_TKN_U8_OUT_PIN_TYPE:
- case SKL_TKN_U8_CONN_TYPE:
- break;
-
- default:
- dev_err(dev, "Token %d not handled\n",
- tkn_elem->token);
- return -EINVAL;
- }
-
- tkn_count++;
-
- return tkn_count;
-}
-
-/*
- * Parse the vendor array for specific tokens to construct
- * module private data
- */
-static int skl_tplg_get_tokens(struct device *dev,
- char *pvt_data, struct skl_dev *skl,
- struct skl_module_cfg *mconfig, int block_size)
-{
- struct snd_soc_tplg_vendor_array *array;
- struct snd_soc_tplg_vendor_value_elem *tkn_elem;
- int tkn_count = 0, ret;
- int off = 0, tuple_size = 0;
- bool is_module_guid = true;
-
- if (block_size <= 0)
- return -EINVAL;
-
- while (tuple_size < block_size) {
- array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off);
-
- off += array->size;
-
- switch (array->type) {
- case SND_SOC_TPLG_TUPLE_TYPE_STRING:
- dev_warn(dev, "no string tokens expected for skl tplg\n");
- continue;
-
- case SND_SOC_TPLG_TUPLE_TYPE_UUID:
- if (is_module_guid) {
- ret = skl_tplg_get_uuid(dev, (guid_t *)mconfig->guid,
- array->uuid);
- is_module_guid = false;
- } else {
- ret = skl_tplg_get_token(dev, array->value, skl,
- mconfig);
- }
-
- if (ret < 0)
- return ret;
-
- tuple_size += sizeof(*array->uuid);
-
- continue;
-
- default:
- tkn_elem = array->value;
- tkn_count = 0;
- break;
- }
-
- while (tkn_count <= (array->num_elems - 1)) {
- ret = skl_tplg_get_token(dev, tkn_elem,
- skl, mconfig);
-
- if (ret < 0)
- return ret;
-
- tkn_count = tkn_count + ret;
- tkn_elem++;
- }
-
- tuple_size += tkn_count * sizeof(*tkn_elem);
- }
-
- return off;
-}
-
-/*
- * Every data block is preceded by a descriptor to read the number
- * of data blocks, they type of the block and it's size
- */
-static int skl_tplg_get_desc_blocks(struct device *dev,
- struct snd_soc_tplg_vendor_array *array)
-{
- struct snd_soc_tplg_vendor_value_elem *tkn_elem;
-
- tkn_elem = array->value;
-
- switch (tkn_elem->token) {
- case SKL_TKN_U8_NUM_BLOCKS:
- case SKL_TKN_U8_BLOCK_TYPE:
- case SKL_TKN_U16_BLOCK_SIZE:
- return tkn_elem->value;
-
- default:
- dev_err(dev, "Invalid descriptor token %d\n", tkn_elem->token);
- break;
- }
-
- return -EINVAL;
-}
-
-/* Functions to parse private data from configuration file format v4 */
-
-/*
- * Add pipeline from topology binary into driver pipeline list
- *
- * If already added we return that instance
- * Otherwise we create a new instance and add into driver list
- */
-static int skl_tplg_add_pipe_v4(struct device *dev,
- struct skl_module_cfg *mconfig, struct skl_dev *skl,
- struct skl_dfw_v4_pipe *dfw_pipe)
-{
- struct skl_pipeline *ppl;
- struct skl_pipe *pipe;
- struct skl_pipe_params *params;
-
- list_for_each_entry(ppl, &skl->ppl_list, node) {
- if (ppl->pipe->ppl_id == dfw_pipe->pipe_id) {
- mconfig->pipe = ppl->pipe;
- return 0;
- }
- }
-
- ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL);
- if (!ppl)
- return -ENOMEM;
-
- pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL);
- if (!pipe)
- return -ENOMEM;
-
- params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
- if (!params)
- return -ENOMEM;
-
- pipe->ppl_id = dfw_pipe->pipe_id;
- pipe->memory_pages = dfw_pipe->memory_pages;
- pipe->pipe_priority = dfw_pipe->pipe_priority;
- pipe->conn_type = dfw_pipe->conn_type;
- pipe->state = SKL_PIPE_INVALID;
- pipe->p_params = params;
- INIT_LIST_HEAD(&pipe->w_list);
-
- ppl->pipe = pipe;
- list_add(&ppl->node, &skl->ppl_list);
-
- mconfig->pipe = pipe;
-
- return 0;
-}
-
-static void skl_fill_module_pin_info_v4(struct skl_dfw_v4_module_pin *dfw_pin,
- struct skl_module_pin *m_pin,
- bool is_dynamic, int max_pin)
-{
- int i;
-
- for (i = 0; i < max_pin; i++) {
- m_pin[i].id.module_id = dfw_pin[i].module_id;
- m_pin[i].id.instance_id = dfw_pin[i].instance_id;
- m_pin[i].in_use = false;
- m_pin[i].is_dynamic = is_dynamic;
- m_pin[i].pin_state = SKL_PIN_UNBIND;
- }
-}
-
-static void skl_tplg_fill_fmt_v4(struct skl_module_pin_fmt *dst_fmt,
- struct skl_dfw_v4_module_fmt *src_fmt,
- int pins)
-{
- int i;
-
- for (i = 0; i < pins; i++) {
- dst_fmt[i].fmt.channels = src_fmt[i].channels;
- dst_fmt[i].fmt.s_freq = src_fmt[i].freq;
- dst_fmt[i].fmt.bit_depth = src_fmt[i].bit_depth;
- dst_fmt[i].fmt.valid_bit_depth = src_fmt[i].valid_bit_depth;
- dst_fmt[i].fmt.ch_cfg = src_fmt[i].ch_cfg;
- dst_fmt[i].fmt.ch_map = src_fmt[i].ch_map;
- dst_fmt[i].fmt.interleaving_style =
- src_fmt[i].interleaving_style;
- dst_fmt[i].fmt.sample_type = src_fmt[i].sample_type;
- }
-}
-
-static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
- struct skl_dev *skl, struct device *dev,
- struct skl_module_cfg *mconfig)
-{
- struct skl_dfw_v4_module *dfw =
- (struct skl_dfw_v4_module *)tplg_w->priv.data;
- int ret;
- int idx = mconfig->fmt_cfg_idx;
-
- dev_dbg(dev, "Parsing Skylake v4 widget topology data\n");
-
- ret = guid_parse(dfw->uuid, (guid_t *)mconfig->guid);
- if (ret)
- return ret;
- mconfig->id.module_id = -1;
- mconfig->id.instance_id = dfw->instance_id;
- mconfig->module->resources[0].cpc = dfw->max_mcps / 1000;
- mconfig->module->resources[0].ibs = dfw->ibs;
- mconfig->module->resources[0].obs = dfw->obs;
- mconfig->core_id = dfw->core_id;
- mconfig->module->max_input_pins = dfw->max_in_queue;
- mconfig->module->max_output_pins = dfw->max_out_queue;
- mconfig->module->loadable = dfw->is_loadable;
- skl_tplg_fill_fmt_v4(mconfig->module->formats[0].inputs, dfw->in_fmt,
- MAX_IN_QUEUE);
- skl_tplg_fill_fmt_v4(mconfig->module->formats[0].outputs, dfw->out_fmt,
- MAX_OUT_QUEUE);
-
- mconfig->params_fixup = dfw->params_fixup;
- mconfig->converter = dfw->converter;
- mconfig->m_type = dfw->module_type;
- mconfig->vbus_id = dfw->vbus_id;
- mconfig->module->resources[0].is_pages = dfw->mem_pages;
-
- ret = skl_tplg_add_pipe_v4(dev, mconfig, skl, &dfw->pipe);
- if (ret)
- return ret;
-
- mconfig->dev_type = dfw->dev_type;
- mconfig->hw_conn_type = dfw->hw_conn_type;
- mconfig->time_slot = dfw->time_slot;
- mconfig->formats_config[idx].caps_size = dfw->caps.caps_size;
-
- mconfig->m_in_pin = devm_kcalloc(dev,
- MAX_IN_QUEUE, sizeof(*mconfig->m_in_pin),
- GFP_KERNEL);
- if (!mconfig->m_in_pin)
- return -ENOMEM;
-
- mconfig->m_out_pin = devm_kcalloc(dev,
- MAX_OUT_QUEUE, sizeof(*mconfig->m_out_pin),
- GFP_KERNEL);
- if (!mconfig->m_out_pin)
- return -ENOMEM;
-
- skl_fill_module_pin_info_v4(dfw->in_pin, mconfig->m_in_pin,
- dfw->is_dynamic_in_pin,
- mconfig->module->max_input_pins);
- skl_fill_module_pin_info_v4(dfw->out_pin, mconfig->m_out_pin,
- dfw->is_dynamic_out_pin,
- mconfig->module->max_output_pins);
-
- if (mconfig->formats_config[idx].caps_size) {
- mconfig->formats_config[idx].set_params = dfw->caps.set_params;
- mconfig->formats_config[idx].param_id = dfw->caps.param_id;
- mconfig->formats_config[idx].caps =
- devm_kzalloc(dev, mconfig->formats_config[idx].caps_size,
- GFP_KERNEL);
- if (!mconfig->formats_config[idx].caps)
- return -ENOMEM;
- memcpy(mconfig->formats_config[idx].caps, dfw->caps.caps,
- dfw->caps.caps_size);
- }
-
- return 0;
-}
-
-static int skl_tplg_get_caps_data(struct device *dev, char *data,
- struct skl_module_cfg *mconfig)
-{
- int idx = mconfig->fmt_cfg_idx;
-
- if (mconfig->formats_config[idx].caps_size > 0) {
- mconfig->formats_config[idx].caps =
- devm_kzalloc(dev, mconfig->formats_config[idx].caps_size,
- GFP_KERNEL);
- if (!mconfig->formats_config[idx].caps)
- return -ENOMEM;
- memcpy(mconfig->formats_config[idx].caps, data,
- mconfig->formats_config[idx].caps_size);
- }
-
- return mconfig->formats_config[idx].caps_size;
-}
-
-/*
- * Parse the private data for the token and corresponding value.
- * The private data can have multiple data blocks. So, a data block
- * is preceded by a descriptor for number of blocks and a descriptor
- * for the type and size of the suceeding data block.
- */
-static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
- struct skl_dev *skl, struct device *dev,
- struct skl_module_cfg *mconfig)
-{
- struct snd_soc_tplg_vendor_array *array;
- int num_blocks, block_size, block_type, off = 0;
- char *data;
- int ret;
-
- /*
- * v4 configuration files have a valid UUID at the start of
- * the widget's private data.
- */
- if (uuid_is_valid((char *)tplg_w->priv.data))
- return skl_tplg_get_pvt_data_v4(tplg_w, skl, dev, mconfig);
-
- /* Read the NUM_DATA_BLOCKS descriptor */
- array = (struct snd_soc_tplg_vendor_array *)tplg_w->priv.data;
- ret = skl_tplg_get_desc_blocks(dev, array);
- if (ret < 0)
- return ret;
- num_blocks = ret;
-
- off += array->size;
- /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
- while (num_blocks > 0) {
- array = (struct snd_soc_tplg_vendor_array *)
- (tplg_w->priv.data + off);
-
- ret = skl_tplg_get_desc_blocks(dev, array);
-
- if (ret < 0)
- return ret;
- block_type = ret;
- off += array->size;
-
- array = (struct snd_soc_tplg_vendor_array *)
- (tplg_w->priv.data + off);
-
- ret = skl_tplg_get_desc_blocks(dev, array);
-
- if (ret < 0)
- return ret;
- block_size = ret;
- off += array->size;
-
- data = (tplg_w->priv.data + off);
-
- if (block_type == SKL_TYPE_TUPLE) {
- ret = skl_tplg_get_tokens(dev, data,
- skl, mconfig, block_size);
- } else {
- ret = skl_tplg_get_caps_data(dev, data, mconfig);
- }
-
- if (ret < 0)
- return ret;
-
- --num_blocks;
- off += ret;
- }
-
- return 0;
-}
-
-static void skl_clear_pin_config(struct snd_soc_component *component,
- struct snd_soc_dapm_widget *w)
-{
- int i;
- struct skl_module_cfg *mconfig;
- struct skl_pipe *pipe;
-
- if (!strncmp(w->dapm->component->name, component->name,
- strlen(component->name))) {
- mconfig = w->priv;
- pipe = mconfig->pipe;
- for (i = 0; i < mconfig->module->max_input_pins; i++) {
- mconfig->m_in_pin[i].in_use = false;
- mconfig->m_in_pin[i].pin_state = SKL_PIN_UNBIND;
- }
- for (i = 0; i < mconfig->module->max_output_pins; i++) {
- mconfig->m_out_pin[i].in_use = false;
- mconfig->m_out_pin[i].pin_state = SKL_PIN_UNBIND;
- }
- pipe->state = SKL_PIPE_INVALID;
- mconfig->m_state = SKL_MODULE_UNINIT;
- }
-}
-
-void skl_cleanup_resources(struct skl_dev *skl)
-{
- struct snd_soc_component *soc_component = skl->component;
- struct snd_soc_dapm_widget *w;
- struct snd_soc_card *card;
-
- if (soc_component == NULL)
- return;
-
- card = soc_component->card;
- if (!snd_soc_card_is_instantiated(card))
- return;
-
- list_for_each_entry(w, &card->widgets, list) {
- if (is_skl_dsp_widget_type(w, skl->dev) && w->priv != NULL)
- skl_clear_pin_config(soc_component, w);
- }
-
- skl_clear_module_cnt(skl->dsp);
-}
-
-/*
- * Topology core widget load callback
- *
- * This is used to save the private data for each widget which gives
- * information to the driver about module and pipeline parameters which DSP
- * FW expects like ids, resource values, formats etc
- */
-static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, int index,
- struct snd_soc_dapm_widget *w,
- struct snd_soc_tplg_dapm_widget *tplg_w)
-{
- int ret;
- struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt);
- struct skl_dev *skl = bus_to_skl(bus);
- struct skl_module_cfg *mconfig;
-
- if (!tplg_w->priv.size)
- goto bind_event;
-
- mconfig = devm_kzalloc(bus->dev, sizeof(*mconfig), GFP_KERNEL);
-
- if (!mconfig)
- return -ENOMEM;
-
- if (skl->nr_modules == 0) {
- mconfig->module = devm_kzalloc(bus->dev,
- sizeof(*mconfig->module), GFP_KERNEL);
- if (!mconfig->module)
- return -ENOMEM;
- }
-
- w->priv = mconfig;
-
- /*
- * module binary can be loaded later, so set it to query when
- * module is load for a use case
- */
- mconfig->id.module_id = -1;
-
- /* To provide backward compatibility, set default as SKL_PARAM_INIT */
- mconfig->fmt_cfg_idx = SKL_PARAM_INIT;
-
- /* Parse private data for tuples */
- ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig);
- if (ret < 0)
- return ret;
-
- skl_debug_init_module(skl->debugfs, w, mconfig);
-
-bind_event:
- if (tplg_w->event_type == 0) {
- dev_dbg(bus->dev, "ASoC: No event handler required\n");
- return 0;
- }
-
- ret = snd_soc_tplg_widget_bind_event(w, skl_tplg_widget_ops,
- ARRAY_SIZE(skl_tplg_widget_ops),
- tplg_w->event_type);
-
- if (ret) {
- dev_err(bus->dev, "%s: No matching event handlers found for %d\n",
- __func__, tplg_w->event_type);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int skl_init_algo_data(struct device *dev, struct soc_bytes_ext *be,
- struct snd_soc_tplg_bytes_control *bc)
-{
- struct skl_algo_data *ac;
- struct skl_dfw_algo_data *dfw_ac =
- (struct skl_dfw_algo_data *)bc->priv.data;
-
- ac = devm_kzalloc(dev, sizeof(*ac), GFP_KERNEL);
- if (!ac)
- return -ENOMEM;
-
- /* Fill private data */
- ac->max = dfw_ac->max;
- ac->param_id = dfw_ac->param_id;
- ac->set_params = dfw_ac->set_params;
- ac->size = dfw_ac->max;
-
- if (ac->max) {
- ac->params = devm_kzalloc(dev, ac->max, GFP_KERNEL);
- if (!ac->params)
- return -ENOMEM;
-
- memcpy(ac->params, dfw_ac->params, ac->max);
- }
-
- be->dobj.private = ac;
- return 0;
-}
-
-static int skl_init_enum_data(struct device *dev, struct soc_enum *se,
- struct snd_soc_tplg_enum_control *ec)
-{
-
- void *data;
-
- if (ec->priv.size) {
- data = devm_kzalloc(dev, sizeof(ec->priv.size), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
- memcpy(data, ec->priv.data, ec->priv.size);
- se->dobj.private = data;
- }
-
- return 0;
-
-}
-
-static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
- int index,
- struct snd_kcontrol_new *kctl,
- struct snd_soc_tplg_ctl_hdr *hdr)
-{
- struct soc_bytes_ext *sb;
- struct snd_soc_tplg_bytes_control *tplg_bc;
- struct snd_soc_tplg_enum_control *tplg_ec;
- struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt);
- struct soc_enum *se;
-
- switch (hdr->ops.info) {
- case SND_SOC_TPLG_CTL_BYTES:
- tplg_bc = container_of(hdr,
- struct snd_soc_tplg_bytes_control, hdr);
- if (kctl->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
- sb = (struct soc_bytes_ext *)kctl->private_value;
- if (tplg_bc->priv.size)
- return skl_init_algo_data(
- bus->dev, sb, tplg_bc);
- }
- break;
-
- case SND_SOC_TPLG_CTL_ENUM:
- tplg_ec = container_of(hdr,
- struct snd_soc_tplg_enum_control, hdr);
- if (kctl->access & SNDRV_CTL_ELEM_ACCESS_READ) {
- se = (struct soc_enum *)kctl->private_value;
- if (tplg_ec->priv.size)
- skl_init_enum_data(bus->dev, se, tplg_ec);
- }
-
- /*
- * now that the control initializations are done, remove
- * write permission for the DMIC configuration enums to
- * avoid conflicts between NHLT settings and user interaction
- */
-
- if (hdr->ops.get == SKL_CONTROL_TYPE_MULTI_IO_SELECT_DMIC)
- kctl->access = SNDRV_CTL_ELEM_ACCESS_READ;
-
- break;
-
- default:
- dev_dbg(bus->dev, "Control load not supported %d:%d:%d\n",
- hdr->ops.get, hdr->ops.put, hdr->ops.info);
- break;
- }
-
- return 0;
-}
-
-static int skl_tplg_fill_str_mfest_tkn(struct device *dev,
- struct snd_soc_tplg_vendor_string_elem *str_elem,
- struct skl_dev *skl)
-{
- int tkn_count = 0;
- static int ref_count;
-
- switch (str_elem->token) {
- case SKL_TKN_STR_LIB_NAME:
- if (ref_count > skl->lib_count - 1) {
- ref_count = 0;
- return -EINVAL;
- }
-
- strncpy(skl->lib_info[ref_count].name,
- str_elem->string,
- ARRAY_SIZE(skl->lib_info[ref_count].name));
- ref_count++;
- break;
-
- default:
- dev_err(dev, "Not a string token %d\n", str_elem->token);
- break;
- }
- tkn_count++;
-
- return tkn_count;
-}
-
-static int skl_tplg_get_str_tkn(struct device *dev,
- struct snd_soc_tplg_vendor_array *array,
- struct skl_dev *skl)
-{
- int tkn_count = 0, ret;
- struct snd_soc_tplg_vendor_string_elem *str_elem;
-
- str_elem = (struct snd_soc_tplg_vendor_string_elem *)array->value;
- while (tkn_count < array->num_elems) {
- ret = skl_tplg_fill_str_mfest_tkn(dev, str_elem, skl);
- str_elem++;
-
- if (ret < 0)
- return ret;
-
- tkn_count = tkn_count + ret;
- }
-
- return tkn_count;
-}
-
-static int skl_tplg_manifest_fill_fmt(struct device *dev,
- struct skl_module_iface *fmt,
- struct snd_soc_tplg_vendor_value_elem *tkn_elem,
- u32 dir, int fmt_idx)
-{
- struct skl_module_pin_fmt *dst_fmt;
- struct skl_module_fmt *mod_fmt;
- int ret;
-
- if (!fmt)
- return -EINVAL;
-
- switch (dir) {
- case SKL_DIR_IN:
- dst_fmt = &fmt->inputs[fmt_idx];
- break;
-
- case SKL_DIR_OUT:
- dst_fmt = &fmt->outputs[fmt_idx];
- break;
-
- default:
- dev_err(dev, "Invalid direction: %d\n", dir);
- return -EINVAL;
- }
-
- mod_fmt = &dst_fmt->fmt;
-
- switch (tkn_elem->token) {
- case SKL_TKN_MM_U32_INTF_PIN_ID:
- dst_fmt->id = tkn_elem->value;
- break;
-
- default:
- ret = skl_tplg_fill_fmt(dev, mod_fmt, tkn_elem->token,
- tkn_elem->value);
- if (ret < 0)
- return ret;
- break;
- }
-
- return 0;
-}
-
-static int skl_tplg_fill_mod_info(struct device *dev,
- struct snd_soc_tplg_vendor_value_elem *tkn_elem,
- struct skl_module *mod)
-{
-
- if (!mod)
- return -EINVAL;
-
- switch (tkn_elem->token) {
- case SKL_TKN_U8_IN_PIN_TYPE:
- mod->input_pin_type = tkn_elem->value;
- break;
-
- case SKL_TKN_U8_OUT_PIN_TYPE:
- mod->output_pin_type = tkn_elem->value;
- break;
-
- case SKL_TKN_U8_IN_QUEUE_COUNT:
- mod->max_input_pins = tkn_elem->value;
- break;
-
- case SKL_TKN_U8_OUT_QUEUE_COUNT:
- mod->max_output_pins = tkn_elem->value;
- break;
-
- case SKL_TKN_MM_U8_NUM_RES:
- mod->nr_resources = tkn_elem->value;
- break;
-
- case SKL_TKN_MM_U8_NUM_INTF:
- mod->nr_interfaces = tkn_elem->value;
- break;
-
- default:
- dev_err(dev, "Invalid mod info token %d", tkn_elem->token);
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-static int skl_tplg_get_int_tkn(struct device *dev,
- struct snd_soc_tplg_vendor_value_elem *tkn_elem,
- struct skl_dev *skl)
-{
- int tkn_count = 0, ret;
- static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx;
- struct skl_module_res *res = NULL;
- struct skl_module_iface *fmt = NULL;
- struct skl_module *mod = NULL;
- static struct skl_astate_param *astate_table;
- static int astate_cfg_idx, count;
- int i;
- size_t size;
-
- if (skl->modules) {
- mod = skl->modules[mod_idx];
- res = &mod->resources[res_val_idx];
- fmt = &mod->formats[intf_val_idx];
- }
-
- switch (tkn_elem->token) {
- case SKL_TKN_U32_LIB_COUNT:
- skl->lib_count = tkn_elem->value;
- break;
-
- case SKL_TKN_U8_NUM_MOD:
- skl->nr_modules = tkn_elem->value;
- skl->modules = devm_kcalloc(dev, skl->nr_modules,
- sizeof(*skl->modules), GFP_KERNEL);
- if (!skl->modules)
- return -ENOMEM;
-
- for (i = 0; i < skl->nr_modules; i++) {
- skl->modules[i] = devm_kzalloc(dev,
- sizeof(struct skl_module), GFP_KERNEL);
- if (!skl->modules[i])
- return -ENOMEM;
- }
- break;
-
- case SKL_TKN_MM_U8_MOD_IDX:
- mod_idx = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_ASTATE_COUNT:
- if (astate_table != NULL) {
- dev_err(dev, "More than one entry for A-State count");
- return -EINVAL;
- }
-
- if (tkn_elem->value > SKL_MAX_ASTATE_CFG) {
- dev_err(dev, "Invalid A-State count %d\n",
- tkn_elem->value);
- return -EINVAL;
- }
-
- size = struct_size(skl->cfg.astate_cfg, astate_table,
- tkn_elem->value);
- skl->cfg.astate_cfg = devm_kzalloc(dev, size, GFP_KERNEL);
- if (!skl->cfg.astate_cfg)
- return -ENOMEM;
-
- astate_table = skl->cfg.astate_cfg->astate_table;
- count = skl->cfg.astate_cfg->count = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_ASTATE_IDX:
- if (tkn_elem->value >= count) {
- dev_err(dev, "Invalid A-State index %d\n",
- tkn_elem->value);
- return -EINVAL;
- }
-
- astate_cfg_idx = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_ASTATE_KCPS:
- astate_table[astate_cfg_idx].kcps = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_ASTATE_CLK_SRC:
- astate_table[astate_cfg_idx].clk_src = tkn_elem->value;
- break;
-
- case SKL_TKN_U8_IN_PIN_TYPE:
- case SKL_TKN_U8_OUT_PIN_TYPE:
- case SKL_TKN_U8_IN_QUEUE_COUNT:
- case SKL_TKN_U8_OUT_QUEUE_COUNT:
- case SKL_TKN_MM_U8_NUM_RES:
- case SKL_TKN_MM_U8_NUM_INTF:
- ret = skl_tplg_fill_mod_info(dev, tkn_elem, mod);
- if (ret < 0)
- return ret;
- break;
-
- case SKL_TKN_U32_DIR_PIN_COUNT:
- dir = tkn_elem->value & SKL_IN_DIR_BIT_MASK;
- pin_idx = (tkn_elem->value & SKL_PIN_COUNT_MASK) >> 4;
- break;
-
- case SKL_TKN_MM_U32_RES_ID:
- if (!res)
- return -EINVAL;
-
- res->id = tkn_elem->value;
- res_val_idx = tkn_elem->value;
- break;
-
- case SKL_TKN_MM_U32_FMT_ID:
- if (!fmt)
- return -EINVAL;
-
- fmt->fmt_idx = tkn_elem->value;
- intf_val_idx = tkn_elem->value;
- break;
-
- case SKL_TKN_MM_U32_CPS:
- case SKL_TKN_MM_U32_DMA_SIZE:
- case SKL_TKN_MM_U32_CPC:
- case SKL_TKN_U32_MEM_PAGES:
- case SKL_TKN_U32_OBS:
- case SKL_TKN_U32_IBS:
- case SKL_TKN_MM_U32_RES_PIN_ID:
- case SKL_TKN_MM_U32_PIN_BUF:
- ret = skl_tplg_fill_res_tkn(dev, tkn_elem, res, pin_idx, dir);
- if (ret < 0)
- return ret;
-
- break;
-
- case SKL_TKN_MM_U32_NUM_IN_FMT:
- if (!fmt)
- return -EINVAL;
-
- res->nr_input_pins = tkn_elem->value;
- break;
-
- case SKL_TKN_MM_U32_NUM_OUT_FMT:
- if (!fmt)
- return -EINVAL;
-
- res->nr_output_pins = tkn_elem->value;
- break;
-
- case SKL_TKN_U32_FMT_CH:
- case SKL_TKN_U32_FMT_FREQ:
- case SKL_TKN_U32_FMT_BIT_DEPTH:
- case SKL_TKN_U32_FMT_SAMPLE_SIZE:
- case SKL_TKN_U32_FMT_CH_CONFIG:
- case SKL_TKN_U32_FMT_INTERLEAVE:
- case SKL_TKN_U32_FMT_SAMPLE_TYPE:
- case SKL_TKN_U32_FMT_CH_MAP:
- case SKL_TKN_MM_U32_INTF_PIN_ID:
- ret = skl_tplg_manifest_fill_fmt(dev, fmt, tkn_elem,
- dir, pin_idx);
- if (ret < 0)
- return ret;
- break;
-
- default:
- dev_err(dev, "Not a manifest token %d\n", tkn_elem->token);
- return -EINVAL;
- }
- tkn_count++;
-
- return tkn_count;
-}
-
-/*
- * Fill the manifest structure by parsing the tokens based on the
- * type.
- */
-static int skl_tplg_get_manifest_tkn(struct device *dev,
- char *pvt_data, struct skl_dev *skl,
- int block_size)
-{
- int tkn_count = 0, ret;
- int off = 0, tuple_size = 0;
- u8 uuid_index = 0;
- struct snd_soc_tplg_vendor_array *array;
- struct snd_soc_tplg_vendor_value_elem *tkn_elem;
-
- if (block_size <= 0)
- return -EINVAL;
-
- while (tuple_size < block_size) {
- array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off);
- off += array->size;
- switch (array->type) {
- case SND_SOC_TPLG_TUPLE_TYPE_STRING:
- ret = skl_tplg_get_str_tkn(dev, array, skl);
-
- if (ret < 0)
- return ret;
- tkn_count = ret;
-
- tuple_size += tkn_count *
- sizeof(struct snd_soc_tplg_vendor_string_elem);
- continue;
-
- case SND_SOC_TPLG_TUPLE_TYPE_UUID:
- if (array->uuid->token != SKL_TKN_UUID) {
- dev_err(dev, "Not an UUID token: %d\n",
- array->uuid->token);
- return -EINVAL;
- }
- if (uuid_index >= skl->nr_modules) {
- dev_err(dev, "Too many UUID tokens\n");
- return -EINVAL;
- }
- import_guid(&skl->modules[uuid_index++]->uuid,
- array->uuid->uuid);
-
- tuple_size += sizeof(*array->uuid);
- continue;
-
- default:
- tkn_elem = array->value;
- tkn_count = 0;
- break;
- }
-
- while (tkn_count <= array->num_elems - 1) {
- ret = skl_tplg_get_int_tkn(dev,
- tkn_elem, skl);
- if (ret < 0)
- return ret;
-
- tkn_count = tkn_count + ret;
- tkn_elem++;
- }
- tuple_size += (tkn_count * sizeof(*tkn_elem));
- tkn_count = 0;
- }
-
- return off;
-}
-
-/*
- * Parse manifest private data for tokens. The private data block is
- * preceded by descriptors for type and size of data block.
- */
-static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest,
- struct device *dev, struct skl_dev *skl)
-{
- struct snd_soc_tplg_vendor_array *array;
- int num_blocks, block_size = 0, block_type, off = 0;
- char *data;
- int ret;
-
- /* Read the NUM_DATA_BLOCKS descriptor */
- array = (struct snd_soc_tplg_vendor_array *)manifest->priv.data;
- ret = skl_tplg_get_desc_blocks(dev, array);
- if (ret < 0)
- return ret;
- num_blocks = ret;
-
- off += array->size;
- /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
- while (num_blocks > 0) {
- array = (struct snd_soc_tplg_vendor_array *)
- (manifest->priv.data + off);
- ret = skl_tplg_get_desc_blocks(dev, array);
-
- if (ret < 0)
- return ret;
- block_type = ret;
- off += array->size;
-
- array = (struct snd_soc_tplg_vendor_array *)
- (manifest->priv.data + off);
-
- ret = skl_tplg_get_desc_blocks(dev, array);
-
- if (ret < 0)
- return ret;
- block_size = ret;
- off += array->size;
-
- data = (manifest->priv.data + off);
-
- if (block_type == SKL_TYPE_TUPLE) {
- ret = skl_tplg_get_manifest_tkn(dev, data, skl,
- block_size);
-
- if (ret < 0)
- return ret;
-
- --num_blocks;
- } else {
- return -EINVAL;
- }
- off += ret;
- }
-
- return 0;
-}
-
-static int skl_manifest_load(struct snd_soc_component *cmpnt, int index,
- struct snd_soc_tplg_manifest *manifest)
-{
- struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt);
- struct skl_dev *skl = bus_to_skl(bus);
-
- /* proceed only if we have private data defined */
- if (manifest->priv.size == 0)
- return 0;
-
- skl_tplg_get_manifest_data(manifest, bus->dev, skl);
-
- if (skl->lib_count > SKL_MAX_LIB) {
- dev_err(bus->dev, "Exceeding max Library count. Got:%d\n",
- skl->lib_count);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int skl_tplg_complete(struct snd_soc_component *component)
-{
- struct snd_soc_dobj *dobj;
- struct snd_soc_acpi_mach *mach;
- struct snd_ctl_elem_value *val;
- int i;
-
- val = kmalloc(sizeof(*val), GFP_KERNEL);
- if (!val)
- return -ENOMEM;
-
- mach = dev_get_platdata(component->card->dev);
- list_for_each_entry(dobj, &component->dobj_list, list) {
- struct snd_kcontrol *kcontrol = dobj->control.kcontrol;
- struct soc_enum *se;
- char **texts;
- char chan_text[4];
-
- if (dobj->type != SND_SOC_DOBJ_ENUM || !kcontrol ||
- kcontrol->put != skl_tplg_multi_config_set_dmic)
- continue;
-
- se = (struct soc_enum *)kcontrol->private_value;
- texts = dobj->control.dtexts;
- sprintf(chan_text, "c%d", mach->mach_params.dmic_num);
-
- for (i = 0; i < se->items; i++) {
- if (strstr(texts[i], chan_text)) {
- memset(val, 0, sizeof(*val));
- val->value.enumerated.item[0] = i;
- kcontrol->put(kcontrol, val);
- }
- }
- }
-
- kfree(val);
- return 0;
-}
-
-static struct snd_soc_tplg_ops skl_tplg_ops = {
- .widget_load = skl_tplg_widget_load,
- .control_load = skl_tplg_control_load,
- .bytes_ext_ops = skl_tlv_ops,
- .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops),
- .io_ops = skl_tplg_kcontrol_ops,
- .io_ops_count = ARRAY_SIZE(skl_tplg_kcontrol_ops),
- .manifest = skl_manifest_load,
- .dai_load = skl_dai_load,
- .complete = skl_tplg_complete,
-};
-
-/*
- * A pipe can have multiple modules, each of them will be a DAPM widget as
- * well. While managing a pipeline we need to get the list of all the
- * widgets in a pipelines, so this helper - skl_tplg_create_pipe_widget_list()
- * helps to get the SKL type widgets in that pipeline
- */
-static int skl_tplg_create_pipe_widget_list(struct snd_soc_component *component)
-{
- struct snd_soc_dapm_widget *w;
- struct skl_module_cfg *mcfg = NULL;
- struct skl_pipe_module *p_module = NULL;
- struct skl_pipe *pipe;
-
- list_for_each_entry(w, &component->card->widgets, list) {
- if (is_skl_dsp_widget_type(w, component->dev) && w->priv) {
- mcfg = w->priv;
- pipe = mcfg->pipe;
-
- p_module = devm_kzalloc(component->dev,
- sizeof(*p_module), GFP_KERNEL);
- if (!p_module)
- return -ENOMEM;
-
- p_module->w = w;
- list_add_tail(&p_module->node, &pipe->w_list);
- }
- }
-
- return 0;
-}
-
-static void skl_tplg_set_pipe_type(struct skl_dev *skl, struct skl_pipe *pipe)
-{
- struct skl_pipe_module *w_module;
- struct snd_soc_dapm_widget *w;
- struct skl_module_cfg *mconfig;
- bool host_found = false, link_found = false;
-
- list_for_each_entry(w_module, &pipe->w_list, node) {
- w = w_module->w;
- mconfig = w->priv;
-
- if (mconfig->dev_type == SKL_DEVICE_HDAHOST)
- host_found = true;
- else if (mconfig->dev_type != SKL_DEVICE_NONE)
- link_found = true;
- }
-
- if (host_found && link_found)
- pipe->passthru = true;
- else
- pipe->passthru = false;
-}
-
-/*
- * SKL topology init routine
- */
-int skl_tplg_init(struct snd_soc_component *component, struct hdac_bus *bus)
-{
- int ret;
- const struct firmware *fw;
- struct skl_dev *skl = bus_to_skl(bus);
- struct skl_pipeline *ppl;
-
- ret = request_firmware(&fw, skl->tplg_name, bus->dev);
- if (ret < 0) {
- char alt_tplg_name[64];
-
- snprintf(alt_tplg_name, sizeof(alt_tplg_name), "%s-tplg.bin",
- skl->mach->drv_name);
- dev_info(bus->dev, "tplg fw %s load failed with %d, trying alternative tplg name %s",
- skl->tplg_name, ret, alt_tplg_name);
-
- ret = request_firmware(&fw, alt_tplg_name, bus->dev);
- if (!ret)
- goto component_load;
-
- dev_info(bus->dev, "tplg %s failed with %d, falling back to dfw_sst.bin",
- alt_tplg_name, ret);
-
- ret = request_firmware(&fw, "dfw_sst.bin", bus->dev);
- if (ret < 0) {
- dev_err(bus->dev, "Fallback tplg fw %s load failed with %d\n",
- "dfw_sst.bin", ret);
- return ret;
- }
- }
-
-component_load:
- ret = snd_soc_tplg_component_load(component, &skl_tplg_ops, fw);
- if (ret < 0) {
- dev_err(bus->dev, "tplg component load failed%d\n", ret);
- goto err;
- }
-
- ret = skl_tplg_create_pipe_widget_list(component);
- if (ret < 0) {
- dev_err(bus->dev, "tplg create pipe widget list failed%d\n",
- ret);
- goto err;
- }
-
- list_for_each_entry(ppl, &skl->ppl_list, node)
- skl_tplg_set_pipe_type(skl, ppl->pipe);
-
-err:
- release_firmware(fw);
- return ret;
-}
-
-void skl_tplg_exit(struct snd_soc_component *component, struct hdac_bus *bus)
-{
- struct skl_dev *skl = bus_to_skl(bus);
- struct skl_pipeline *ppl, *tmp;
-
- list_for_each_entry_safe(ppl, tmp, &skl->ppl_list, node)
- list_del(&ppl->node);
-
- /* clean up topology */
- snd_soc_tplg_component_remove(component);
-}
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
deleted file mode 100644
index 30a0977af943..000000000000
--- a/sound/soc/intel/skylake/skl-topology.h
+++ /dev/null
@@ -1,524 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * skl_topology.h - Intel HDA Platform topology header file
- *
- * Copyright (C) 2014-15 Intel Corp
- * Author: Jeeja KP <jeeja.kp@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#ifndef __SKL_TOPOLOGY_H__
-#define __SKL_TOPOLOGY_H__
-
-#include <linux/types.h>
-
-#include <sound/hdaudio_ext.h>
-#include <sound/soc.h>
-#include <uapi/sound/skl-tplg-interface.h>
-#include "skl.h"
-
-#define BITS_PER_BYTE 8
-#define MAX_TS_GROUPS 8
-#define MAX_DMIC_TS_GROUPS 4
-#define MAX_FIXED_DMIC_PARAMS_SIZE 727
-
-/* Maximum number of coefficients up down mixer module */
-#define UP_DOWN_MIXER_MAX_COEFF 8
-
-#define MODULE_MAX_IN_PINS 8
-#define MODULE_MAX_OUT_PINS 8
-
-#define SKL_MIC_CH_SUPPORT 4
-#define SKL_MIC_MAX_CH_SUPPORT 8
-#define SKL_DEFAULT_MIC_SEL_GAIN 0x3FF
-#define SKL_MIC_SEL_SWITCH 0x3
-
-#define SKL_OUTPUT_PIN 0
-#define SKL_INPUT_PIN 1
-#define SKL_MAX_PATH_CONFIGS 8
-#define SKL_MAX_MODULES_IN_PIPE 8
-#define SKL_MAX_MODULE_FORMATS 32
-#define SKL_MAX_MODULE_RESOURCES 32
-
-enum skl_channel_index {
- SKL_CHANNEL_LEFT = 0,
- SKL_CHANNEL_RIGHT = 1,
- SKL_CHANNEL_CENTER = 2,
- SKL_CHANNEL_LEFT_SURROUND = 3,
- SKL_CHANNEL_CENTER_SURROUND = 3,
- SKL_CHANNEL_RIGHT_SURROUND = 4,
- SKL_CHANNEL_LFE = 7,
- SKL_CHANNEL_INVALID = 0xF,
-};
-
-enum skl_bitdepth {
- SKL_DEPTH_8BIT = 8,
- SKL_DEPTH_16BIT = 16,
- SKL_DEPTH_24BIT = 24,
- SKL_DEPTH_32BIT = 32,
- SKL_DEPTH_INVALID
-};
-
-
-enum skl_s_freq {
- SKL_FS_8000 = 8000,
- SKL_FS_11025 = 11025,
- SKL_FS_12000 = 12000,
- SKL_FS_16000 = 16000,
- SKL_FS_22050 = 22050,
- SKL_FS_24000 = 24000,
- SKL_FS_32000 = 32000,
- SKL_FS_44100 = 44100,
- SKL_FS_48000 = 48000,
- SKL_FS_64000 = 64000,
- SKL_FS_88200 = 88200,
- SKL_FS_96000 = 96000,
- SKL_FS_128000 = 128000,
- SKL_FS_176400 = 176400,
- SKL_FS_192000 = 192000,
- SKL_FS_INVALID
-};
-
-#define SKL_MAX_PARAMS_TYPES 4
-
-enum skl_widget_type {
- SKL_WIDGET_VMIXER = 1,
- SKL_WIDGET_MIXER = 2,
- SKL_WIDGET_PGA = 3,
- SKL_WIDGET_MUX = 4
-};
-
-struct skl_audio_data_format {
- enum skl_s_freq s_freq;
- enum skl_bitdepth bit_depth;
- u32 channel_map;
- enum skl_ch_cfg ch_cfg;
- enum skl_interleaving interleaving;
- u8 number_of_channels;
- u8 valid_bit_depth;
- u8 sample_type;
- u8 reserved;
-} __packed;
-
-struct skl_base_cfg {
- u32 cpc;
- u32 ibs;
- u32 obs;
- u32 is_pages;
- struct skl_audio_data_format audio_fmt;
-};
-
-struct skl_cpr_gtw_cfg {
- u32 node_id;
- u32 dma_buffer_size;
- u32 config_length;
- /* not mandatory; required only for DMIC/I2S */
- struct {
- u32 gtw_attrs;
- u32 data[];
- } config_data;
-} __packed;
-
-struct skl_dma_control {
- u32 node_id;
- u32 config_length;
- u32 config_data[];
-} __packed;
-
-struct skl_cpr_cfg {
- struct skl_base_cfg base_cfg;
- struct skl_audio_data_format out_fmt;
- u32 cpr_feature_mask;
- struct skl_cpr_gtw_cfg gtw_cfg;
-} __packed;
-
-struct skl_cpr_pin_fmt {
- u32 sink_id;
- struct skl_audio_data_format src_fmt;
- struct skl_audio_data_format dst_fmt;
-} __packed;
-
-struct skl_src_module_cfg {
- struct skl_base_cfg base_cfg;
- enum skl_s_freq src_cfg;
-} __packed;
-
-struct skl_up_down_mixer_cfg {
- struct skl_base_cfg base_cfg;
- enum skl_ch_cfg out_ch_cfg;
- /* This should be set to 1 if user coefficients are required */
- u32 coeff_sel;
- /* Pass the user coeff in this array */
- s32 coeff[UP_DOWN_MIXER_MAX_COEFF];
- u32 ch_map;
-} __packed;
-
-struct skl_pin_format {
- u32 pin_idx;
- u32 buf_size;
- struct skl_audio_data_format audio_fmt;
-} __packed;
-
-struct skl_base_cfg_ext {
- u16 nr_input_pins;
- u16 nr_output_pins;
- u8 reserved[8];
- u32 priv_param_length;
- /* Input pin formats followed by output ones. */
- struct skl_pin_format pins_fmt[];
-} __packed;
-
-struct skl_algo_cfg {
- struct skl_base_cfg base_cfg;
- char params[];
-} __packed;
-
-struct skl_base_outfmt_cfg {
- struct skl_base_cfg base_cfg;
- struct skl_audio_data_format out_fmt;
-} __packed;
-
-enum skl_dma_type {
- SKL_DMA_HDA_HOST_OUTPUT_CLASS = 0,
- SKL_DMA_HDA_HOST_INPUT_CLASS = 1,
- SKL_DMA_HDA_HOST_INOUT_CLASS = 2,
- SKL_DMA_HDA_LINK_OUTPUT_CLASS = 8,
- SKL_DMA_HDA_LINK_INPUT_CLASS = 9,
- SKL_DMA_HDA_LINK_INOUT_CLASS = 0xA,
- SKL_DMA_DMIC_LINK_INPUT_CLASS = 0xB,
- SKL_DMA_I2S_LINK_OUTPUT_CLASS = 0xC,
- SKL_DMA_I2S_LINK_INPUT_CLASS = 0xD,
-};
-
-union skl_ssp_dma_node {
- u8 val;
- struct {
- u8 time_slot_index:4;
- u8 i2s_instance:4;
- } dma_node;
-};
-
-union skl_connector_node_id {
- u32 val;
- struct {
- u32 vindex:8;
- u32 dma_type:4;
- u32 rsvd:20;
- } node;
-};
-
-struct skl_module_fmt {
- u32 channels;
- u32 s_freq;
- u32 bit_depth;
- u32 valid_bit_depth;
- u32 ch_cfg;
- u32 interleaving_style;
- u32 sample_type;
- u32 ch_map;
-};
-
-struct skl_module_cfg;
-
-struct skl_mod_inst_map {
- u16 mod_id;
- u16 inst_id;
-};
-
-struct skl_uuid_inst_map {
- u16 inst_id;
- u16 reserved;
- guid_t mod_uuid;
-} __packed;
-
-struct skl_kpb_params {
- u32 num_modules;
- union {
- DECLARE_FLEX_ARRAY(struct skl_mod_inst_map, map);
- DECLARE_FLEX_ARRAY(struct skl_uuid_inst_map, map_uuid);
- } u;
-};
-
-struct skl_module_inst_id {
- guid_t mod_uuid;
- int module_id;
- u32 instance_id;
- int pvt_id;
-};
-
-enum skl_module_pin_state {
- SKL_PIN_UNBIND = 0,
- SKL_PIN_BIND_DONE = 1,
-};
-
-struct skl_module_pin {
- struct skl_module_inst_id id;
- bool is_dynamic;
- bool in_use;
- enum skl_module_pin_state pin_state;
- struct skl_module_cfg *tgt_mcfg;
-};
-
-struct skl_specific_cfg {
- u32 set_params;
- u32 param_id;
- u32 caps_size;
- u32 *caps;
-};
-
-enum skl_pipe_state {
- SKL_PIPE_INVALID = 0,
- SKL_PIPE_CREATED = 1,
- SKL_PIPE_PAUSED = 2,
- SKL_PIPE_STARTED = 3,
- SKL_PIPE_RESET = 4
-};
-
-struct skl_pipe_module {
- struct snd_soc_dapm_widget *w;
- struct list_head node;
-};
-
-struct skl_pipe_params {
- u8 host_dma_id;
- u8 link_dma_id;
- u32 ch;
- u32 s_freq;
- u32 s_fmt;
- u32 s_cont;
- u8 linktype;
- snd_pcm_format_t format;
- int link_index;
- int stream;
- unsigned int host_bps;
- unsigned int link_bps;
-};
-
-struct skl_pipe_fmt {
- u32 freq;
- u8 channels;
- u8 bps;
-};
-
-struct skl_pipe_mcfg {
- u8 res_idx;
- u8 fmt_idx;
-};
-
-struct skl_path_config {
- u8 mem_pages;
- struct skl_pipe_fmt in_fmt;
- struct skl_pipe_fmt out_fmt;
-};
-
-struct skl_pipe {
- u8 ppl_id;
- u8 pipe_priority;
- u16 conn_type;
- u32 memory_pages;
- u8 lp_mode;
- struct skl_pipe_params *p_params;
- enum skl_pipe_state state;
- u8 direction;
- u8 cur_config_idx;
- u8 nr_cfgs;
- struct skl_path_config configs[SKL_MAX_PATH_CONFIGS];
- struct list_head w_list;
- bool passthru;
-};
-
-enum skl_module_state {
- SKL_MODULE_UNINIT = 0,
- SKL_MODULE_INIT_DONE = 1,
- SKL_MODULE_BIND_DONE = 2,
-};
-
-enum d0i3_capability {
- SKL_D0I3_NONE = 0,
- SKL_D0I3_STREAMING = 1,
- SKL_D0I3_NON_STREAMING = 2,
-};
-
-struct skl_module_pin_fmt {
- u8 id;
- struct skl_module_fmt fmt;
-};
-
-struct skl_module_iface {
- u8 fmt_idx;
- u8 nr_in_fmt;
- u8 nr_out_fmt;
- struct skl_module_pin_fmt inputs[MAX_IN_QUEUE];
- struct skl_module_pin_fmt outputs[MAX_OUT_QUEUE];
-};
-
-struct skl_module_pin_resources {
- u8 pin_index;
- u32 buf_size;
-};
-
-struct skl_module_res {
- u8 id;
- u32 is_pages;
- u32 ibs;
- u32 obs;
- u32 dma_buffer_size;
- u32 cpc;
- u8 nr_input_pins;
- u8 nr_output_pins;
- struct skl_module_pin_resources input[MAX_IN_QUEUE];
- struct skl_module_pin_resources output[MAX_OUT_QUEUE];
-};
-
-struct skl_module {
- guid_t uuid;
- u8 loadable;
- u8 input_pin_type;
- u8 output_pin_type;
- u8 max_input_pins;
- u8 max_output_pins;
- u8 nr_resources;
- u8 nr_interfaces;
- struct skl_module_res resources[SKL_MAX_MODULE_RESOURCES];
- struct skl_module_iface formats[SKL_MAX_MODULE_FORMATS];
-};
-
-struct skl_module_cfg {
- u8 guid[16];
- struct skl_module_inst_id id;
- struct skl_module *module;
- int res_idx;
- int fmt_idx;
- int fmt_cfg_idx;
- u8 domain;
- bool homogenous_inputs;
- bool homogenous_outputs;
- struct skl_module_fmt in_fmt[MODULE_MAX_IN_PINS];
- struct skl_module_fmt out_fmt[MODULE_MAX_OUT_PINS];
- u8 max_in_queue;
- u8 max_out_queue;
- u8 in_queue_mask;
- u8 out_queue_mask;
- u8 in_queue;
- u8 out_queue;
- u8 is_loadable;
- u8 core_id;
- u8 dev_type;
- u8 dma_id;
- u8 time_slot;
- u8 dmic_ch_combo_index;
- u32 dmic_ch_type;
- u32 params_fixup;
- u32 converter;
- u32 vbus_id;
- u32 mem_pages;
- enum d0i3_capability d0i3_caps;
- u32 dma_buffer_size; /* in milli seconds */
- struct skl_module_pin *m_in_pin;
- struct skl_module_pin *m_out_pin;
- enum skl_module_type m_type;
- enum skl_hw_conn_type hw_conn_type;
- enum skl_module_state m_state;
- struct skl_pipe *pipe;
- struct skl_specific_cfg formats_config[SKL_MAX_PARAMS_TYPES];
- struct skl_pipe_mcfg mod_cfg[SKL_MAX_MODULES_IN_PIPE];
-};
-
-struct skl_algo_data {
- u32 param_id;
- u32 set_params;
- u32 max;
- u32 size;
- char *params;
-};
-
-struct skl_pipeline {
- struct skl_pipe *pipe;
- struct list_head node;
-};
-
-struct skl_module_deferred_bind {
- struct skl_module_cfg *src;
- struct skl_module_cfg *dst;
- struct list_head node;
-};
-
-struct skl_mic_sel_config {
- u16 mic_switch;
- u16 flags;
- u16 blob[SKL_MIC_MAX_CH_SUPPORT][SKL_MIC_MAX_CH_SUPPORT];
-} __packed;
-
-enum skl_channel {
- SKL_CH_MONO = 1,
- SKL_CH_STEREO = 2,
- SKL_CH_TRIO = 3,
- SKL_CH_QUATRO = 4,
-};
-
-static inline struct skl_dev *get_skl_ctx(struct device *dev)
-{
- struct hdac_bus *bus = dev_get_drvdata(dev);
-
- return bus_to_skl(bus);
-}
-
-int skl_tplg_be_update_params(struct snd_soc_dai *dai,
- struct skl_pipe_params *params);
-int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps,
- u32 caps_size, u32 node_id);
-void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,
- struct skl_pipe_params *params, int stream);
-int skl_tplg_init(struct snd_soc_component *component,
- struct hdac_bus *bus);
-void skl_tplg_exit(struct snd_soc_component *component,
- struct hdac_bus *bus);
-struct skl_module_cfg *skl_tplg_fe_get_cpr_module(
- struct snd_soc_dai *dai, int stream);
-int skl_tplg_update_pipe_params(struct device *dev,
- struct skl_module_cfg *mconfig, struct skl_pipe_params *params);
-
-void skl_tplg_d0i3_get(struct skl_dev *skl, enum d0i3_capability caps);
-void skl_tplg_d0i3_put(struct skl_dev *skl, enum d0i3_capability caps);
-
-int skl_create_pipeline(struct skl_dev *skl, struct skl_pipe *pipe);
-
-int skl_run_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
-
-int skl_pause_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
-
-int skl_delete_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
-
-int skl_stop_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
-
-int skl_reset_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
-
-int skl_init_module(struct skl_dev *skl, struct skl_module_cfg *mconfig);
-
-int skl_bind_modules(struct skl_dev *skl, struct skl_module_cfg
- *src_mcfg, struct skl_module_cfg *dst_mcfg);
-
-int skl_unbind_modules(struct skl_dev *skl, struct skl_module_cfg
- *src_mcfg, struct skl_module_cfg *dst_mcfg);
-
-int skl_set_module_params(struct skl_dev *skl, u32 *params, int size,
- u32 param_id, struct skl_module_cfg *mcfg);
-int skl_get_module_params(struct skl_dev *skl, u32 *params, int size,
- u32 param_id, struct skl_module_cfg *mcfg);
-
-struct skl_module_cfg *skl_tplg_be_get_cpr_module(struct snd_soc_dai *dai,
- int stream);
-enum skl_bitdepth skl_get_bit_depth(int params);
-int skl_pcm_host_dma_prepare(struct device *dev,
- struct skl_pipe_params *params);
-int skl_pcm_link_dma_prepare(struct device *dev,
- struct skl_pipe_params *params);
-
-int skl_dai_load(struct snd_soc_component *cmp, int index,
- struct snd_soc_dai_driver *dai_drv,
- struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai);
-void skl_tplg_add_moduleid_in_bind_params(struct skl_dev *skl,
- struct snd_soc_dapm_widget *w);
-#endif
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
deleted file mode 100644
index 117125187793..000000000000
--- a/sound/soc/intel/skylake/skl.c
+++ /dev/null
@@ -1,1177 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * skl.c - Implementation of ASoC Intel SKL HD Audio driver
- *
- * Copyright (C) 2014-2015 Intel Corp
- * Author: Jeeja KP <jeeja.kp@intel.com>
- *
- * Derived mostly from Intel HDA driver with following copyrights:
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- * PeiSen Hou <pshou@realtek.com.tw>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/pm_runtime.h>
-#include <linux/platform_device.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <sound/pcm.h>
-#include <sound/soc-acpi.h>
-#include <sound/soc-acpi-intel-match.h>
-#include <sound/hda_register.h>
-#include <sound/hdaudio.h>
-#include <sound/hda_i915.h>
-#include <sound/hda_codec.h>
-#include <sound/intel-nhlt.h>
-#include <sound/intel-dsp-config.h>
-#include "skl.h"
-#include "skl-sst-dsp.h"
-#include "skl-sst-ipc.h"
-
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
-#include "../../../soc/codecs/hdac_hda.h"
-#endif
-static int skl_pci_binding;
-module_param_named(pci_binding, skl_pci_binding, int, 0444);
-MODULE_PARM_DESC(pci_binding, "PCI binding (0=auto, 1=only legacy, 2=only asoc");
-
-/*
- * initialize the PCI registers
- */
-static void skl_update_pci_byte(struct pci_dev *pci, unsigned int reg,
- unsigned char mask, unsigned char val)
-{
- unsigned char data;
-
- pci_read_config_byte(pci, reg, &data);
- data &= ~mask;
- data |= (val & mask);
- pci_write_config_byte(pci, reg, data);
-}
-
-static void skl_init_pci(struct skl_dev *skl)
-{
- struct hdac_bus *bus = skl_to_bus(skl);
-
- /*
- * Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
- * TCSEL == Traffic Class Select Register, which sets PCI express QOS
- * Ensuring these bits are 0 clears playback static on some HD Audio
- * codecs.
- * The PCI register TCSEL is defined in the Intel manuals.
- */
- dev_dbg(bus->dev, "Clearing TCSEL\n");
- skl_update_pci_byte(skl->pci, AZX_PCIREG_TCSEL, 0x07, 0);
-}
-
-static void update_pci_dword(struct pci_dev *pci,
- unsigned int reg, u32 mask, u32 val)
-{
- u32 data = 0;
-
- pci_read_config_dword(pci, reg, &data);
- data &= ~mask;
- data |= (val & mask);
- pci_write_config_dword(pci, reg, data);
-}
-
-/*
- * skl_enable_miscbdcge - enable/dsiable CGCTL.MISCBDCGE bits
- *
- * @dev: device pointer
- * @enable: enable/disable flag
- */
-static void skl_enable_miscbdcge(struct device *dev, bool enable)
-{
- struct pci_dev *pci = to_pci_dev(dev);
- u32 val;
-
- val = enable ? AZX_CGCTL_MISCBDCGE_MASK : 0;
-
- update_pci_dword(pci, AZX_PCIREG_CGCTL, AZX_CGCTL_MISCBDCGE_MASK, val);
-}
-
-/**
- * skl_clock_power_gating: Enable/Disable clock and power gating
- *
- * @dev: Device pointer
- * @enable: Enable/Disable flag
- */
-static void skl_clock_power_gating(struct device *dev, bool enable)
-{
- struct pci_dev *pci = to_pci_dev(dev);
- struct hdac_bus *bus = pci_get_drvdata(pci);
- u32 val;
-
- /* Update PDCGE bit of CGCTL register */
- val = enable ? AZX_CGCTL_ADSPDCGE : 0;
- update_pci_dword(pci, AZX_PCIREG_CGCTL, AZX_CGCTL_ADSPDCGE, val);
-
- /* Update L1SEN bit of EM2 register */
- val = enable ? AZX_REG_VS_EM2_L1SEN : 0;
- snd_hdac_chip_updatel(bus, VS_EM2, AZX_REG_VS_EM2_L1SEN, val);
-
- /* Update ADSPPGD bit of PGCTL register */
- val = enable ? 0 : AZX_PGCTL_ADSPPGD;
- update_pci_dword(pci, AZX_PCIREG_PGCTL, AZX_PGCTL_ADSPPGD, val);
-}
-
-/*
- * While performing reset, controller may not come back properly causing
- * issues, so recommendation is to set CGCTL.MISCBDCGE to 0 then do reset
- * (init chip) and then again set CGCTL.MISCBDCGE to 1
- */
-static int skl_init_chip(struct hdac_bus *bus, bool full_reset)
-{
- struct hdac_ext_link *hlink;
- int ret;
-
- snd_hdac_set_codec_wakeup(bus, true);
- skl_enable_miscbdcge(bus->dev, false);
- ret = snd_hdac_bus_init_chip(bus, full_reset);
-
- /* Reset stream-to-link mapping */
- list_for_each_entry(hlink, &bus->hlink_list, list)
- writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
-
- skl_enable_miscbdcge(bus->dev, true);
- snd_hdac_set_codec_wakeup(bus, false);
-
- return ret;
-}
-
-void skl_update_d0i3c(struct device *dev, bool enable)
-{
- struct pci_dev *pci = to_pci_dev(dev);
- struct hdac_bus *bus = pci_get_drvdata(pci);
- u8 reg;
- int timeout = 50;
-
- reg = snd_hdac_chip_readb(bus, VS_D0I3C);
- /* Do not write to D0I3C until command in progress bit is cleared */
- while ((reg & AZX_REG_VS_D0I3C_CIP) && --timeout) {
- udelay(10);
- reg = snd_hdac_chip_readb(bus, VS_D0I3C);
- }
-
- /* Highly unlikely. But if it happens, flag error explicitly */
- if (!timeout) {
- dev_err(bus->dev, "Before D0I3C update: D0I3C CIP timeout\n");
- return;
- }
-
- if (enable)
- reg = reg | AZX_REG_VS_D0I3C_I3;
- else
- reg = reg & (~AZX_REG_VS_D0I3C_I3);
-
- snd_hdac_chip_writeb(bus, VS_D0I3C, reg);
-
- timeout = 50;
- /* Wait for cmd in progress to be cleared before exiting the function */
- reg = snd_hdac_chip_readb(bus, VS_D0I3C);
- while ((reg & AZX_REG_VS_D0I3C_CIP) && --timeout) {
- udelay(10);
- reg = snd_hdac_chip_readb(bus, VS_D0I3C);
- }
-
- /* Highly unlikely. But if it happens, flag error explicitly */
- if (!timeout) {
- dev_err(bus->dev, "After D0I3C update: D0I3C CIP timeout\n");
- return;
- }
-
- dev_dbg(bus->dev, "D0I3C register = 0x%x\n",
- snd_hdac_chip_readb(bus, VS_D0I3C));
-}
-
-/**
- * skl_dum_set - set DUM bit in EM2 register
- * @bus: HD-audio core bus
- *
- * Addresses incorrect position reporting for capture streams.
- * Used on device power up.
- */
-static void skl_dum_set(struct hdac_bus *bus)
-{
- /* For the DUM bit to be set, CRST needs to be out of reset state */
- if (!(snd_hdac_chip_readb(bus, GCTL) & AZX_GCTL_RESET)) {
- skl_enable_miscbdcge(bus->dev, false);
- snd_hdac_bus_exit_link_reset(bus);
- skl_enable_miscbdcge(bus->dev, true);
- }
-
- snd_hdac_chip_updatel(bus, VS_EM2, AZX_VS_EM2_DUM, AZX_VS_EM2_DUM);
-}
-
-/* called from IRQ */
-static void skl_stream_update(struct hdac_bus *bus, struct hdac_stream *hstr)
-{
- snd_pcm_period_elapsed(hstr->substream);
-}
-
-static irqreturn_t skl_interrupt(int irq, void *dev_id)
-{
- struct hdac_bus *bus = dev_id;
- u32 status;
-
- if (!pm_runtime_active(bus->dev))
- return IRQ_NONE;
-
- spin_lock(&bus->reg_lock);
-
- status = snd_hdac_chip_readl(bus, INTSTS);
- if (status == 0 || status == 0xffffffff) {
- spin_unlock(&bus->reg_lock);
- return IRQ_NONE;
- }
-
- /* clear rirb int */
- status = snd_hdac_chip_readb(bus, RIRBSTS);
- if (status & RIRB_INT_MASK) {
- if (status & RIRB_INT_RESPONSE)
- snd_hdac_bus_update_rirb(bus);
- snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
- }
-
- spin_unlock(&bus->reg_lock);
-
- return snd_hdac_chip_readl(bus, INTSTS) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
-}
-
-static irqreturn_t skl_threaded_handler(int irq, void *dev_id)
-{
- struct hdac_bus *bus = dev_id;
- u32 status;
-
- status = snd_hdac_chip_readl(bus, INTSTS);
-
- snd_hdac_bus_handle_stream_irq(bus, status, skl_stream_update);
-
- return IRQ_HANDLED;
-}
-
-static int skl_acquire_irq(struct hdac_bus *bus, int do_disconnect)
-{
- struct skl_dev *skl = bus_to_skl(bus);
- int ret;
-
- ret = request_threaded_irq(skl->pci->irq, skl_interrupt,
- skl_threaded_handler,
- IRQF_SHARED,
- KBUILD_MODNAME, bus);
- if (ret) {
- dev_err(bus->dev,
- "unable to grab IRQ %d, disabling device\n",
- skl->pci->irq);
- return ret;
- }
-
- bus->irq = skl->pci->irq;
- pci_intx(skl->pci, 1);
-
- return 0;
-}
-
-static int skl_suspend_late(struct device *dev)
-{
- struct pci_dev *pci = to_pci_dev(dev);
- struct hdac_bus *bus = pci_get_drvdata(pci);
- struct skl_dev *skl = bus_to_skl(bus);
-
- return skl_suspend_late_dsp(skl);
-}
-
-#ifdef CONFIG_PM
-static int _skl_suspend(struct hdac_bus *bus)
-{
- struct skl_dev *skl = bus_to_skl(bus);
- struct pci_dev *pci = to_pci_dev(bus->dev);
- int ret;
-
- snd_hdac_ext_bus_link_power_down_all(bus);
-
- ret = skl_suspend_dsp(skl);
- if (ret < 0)
- return ret;
-
- snd_hdac_bus_stop_chip(bus);
- update_pci_dword(pci, AZX_PCIREG_PGCTL,
- AZX_PGCTL_LSRMD_MASK, AZX_PGCTL_LSRMD_MASK);
- skl_enable_miscbdcge(bus->dev, false);
- snd_hdac_bus_enter_link_reset(bus);
- skl_enable_miscbdcge(bus->dev, true);
- skl_cleanup_resources(skl);
-
- return 0;
-}
-
-static int _skl_resume(struct hdac_bus *bus)
-{
- struct skl_dev *skl = bus_to_skl(bus);
-
- skl_init_pci(skl);
- skl_dum_set(bus);
- skl_init_chip(bus, true);
-
- return skl_resume_dsp(skl);
-}
-#endif
-
-#ifdef CONFIG_PM_SLEEP
-/*
- * power management
- */
-static int skl_suspend(struct device *dev)
-{
- struct pci_dev *pci = to_pci_dev(dev);
- struct hdac_bus *bus = pci_get_drvdata(pci);
- struct skl_dev *skl = bus_to_skl(bus);
- int ret;
-
- /*
- * Do not suspend if streams which are marked ignore suspend are
- * running, we need to save the state for these and continue
- */
- if (skl->supend_active) {
- /* turn off the links and stop the CORB/RIRB DMA if it is On */
- snd_hdac_ext_bus_link_power_down_all(bus);
-
- if (bus->cmd_dma_state)
- snd_hdac_bus_stop_cmd_io(bus);
-
- enable_irq_wake(bus->irq);
- pci_save_state(pci);
- } else {
- ret = _skl_suspend(bus);
- if (ret < 0)
- return ret;
- skl->fw_loaded = false;
- }
-
- return 0;
-}
-
-static int skl_resume(struct device *dev)
-{
- struct pci_dev *pci = to_pci_dev(dev);
- struct hdac_bus *bus = pci_get_drvdata(pci);
- struct skl_dev *skl = bus_to_skl(bus);
- struct hdac_ext_link *hlink;
- int ret;
-
- /*
- * resume only when we are not in suspend active, otherwise need to
- * restore the device
- */
- if (skl->supend_active) {
- pci_restore_state(pci);
- snd_hdac_ext_bus_link_power_up_all(bus);
- disable_irq_wake(bus->irq);
- /*
- * turn On the links which are On before active suspend
- * and start the CORB/RIRB DMA if On before
- * active suspend.
- */
- list_for_each_entry(hlink, &bus->hlink_list, list) {
- if (hlink->ref_count)
- snd_hdac_ext_bus_link_power_up(hlink);
- }
-
- ret = 0;
- if (bus->cmd_dma_state)
- snd_hdac_bus_init_cmd_io(bus);
- } else {
- ret = _skl_resume(bus);
- }
-
- return ret;
-}
-#endif /* CONFIG_PM_SLEEP */
-
-#ifdef CONFIG_PM
-static int skl_runtime_suspend(struct device *dev)
-{
- struct pci_dev *pci = to_pci_dev(dev);
- struct hdac_bus *bus = pci_get_drvdata(pci);
-
- dev_dbg(bus->dev, "in %s\n", __func__);
-
- return _skl_suspend(bus);
-}
-
-static int skl_runtime_resume(struct device *dev)
-{
- struct pci_dev *pci = to_pci_dev(dev);
- struct hdac_bus *bus = pci_get_drvdata(pci);
-
- dev_dbg(bus->dev, "in %s\n", __func__);
-
- return _skl_resume(bus);
-}
-#endif /* CONFIG_PM */
-
-static const struct dev_pm_ops skl_pm = {
- SET_SYSTEM_SLEEP_PM_OPS(skl_suspend, skl_resume)
- SET_RUNTIME_PM_OPS(skl_runtime_suspend, skl_runtime_resume, NULL)
- .suspend_late = skl_suspend_late,
-};
-
-/*
- * destructor
- */
-static int skl_free(struct hdac_bus *bus)
-{
- struct skl_dev *skl = bus_to_skl(bus);
-
- skl->init_done = 0; /* to be sure */
-
- snd_hdac_stop_streams_and_chip(bus);
-
- if (bus->irq >= 0)
- free_irq(bus->irq, (void *)bus);
- snd_hdac_bus_free_stream_pages(bus);
- snd_hdac_ext_stream_free_all(bus);
- snd_hdac_ext_link_free_all(bus);
-
- if (bus->remap_addr)
- iounmap(bus->remap_addr);
-
- pci_release_regions(skl->pci);
- pci_disable_device(skl->pci);
-
- snd_hdac_ext_bus_exit(bus);
-
- if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
- snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
- snd_hdac_i915_exit(bus);
- }
-
- return 0;
-}
-
-/*
- * For each ssp there are 3 clocks (mclk/sclk/sclkfs).
- * e.g. for ssp0, clocks will be named as
- * "ssp0_mclk", "ssp0_sclk", "ssp0_sclkfs"
- * So for skl+, there are 6 ssps, so 18 clocks will be created.
- */
-static struct skl_ssp_clk skl_ssp_clks[] = {
- {.name = "ssp0_mclk"}, {.name = "ssp1_mclk"}, {.name = "ssp2_mclk"},
- {.name = "ssp3_mclk"}, {.name = "ssp4_mclk"}, {.name = "ssp5_mclk"},
- {.name = "ssp0_sclk"}, {.name = "ssp1_sclk"}, {.name = "ssp2_sclk"},
- {.name = "ssp3_sclk"}, {.name = "ssp4_sclk"}, {.name = "ssp5_sclk"},
- {.name = "ssp0_sclkfs"}, {.name = "ssp1_sclkfs"},
- {.name = "ssp2_sclkfs"},
- {.name = "ssp3_sclkfs"}, {.name = "ssp4_sclkfs"},
- {.name = "ssp5_sclkfs"},
-};
-
-static struct snd_soc_acpi_mach *skl_find_hda_machine(struct skl_dev *skl,
- struct snd_soc_acpi_mach *machines)
-{
- struct snd_soc_acpi_mach *mach;
-
- /* point to common table */
- mach = snd_soc_acpi_intel_hda_machines;
-
- /* all entries in the machine table use the same firmware */
- mach->fw_filename = machines->fw_filename;
-
- return mach;
-}
-
-static int skl_find_machine(struct skl_dev *skl, void *driver_data)
-{
- struct hdac_bus *bus = skl_to_bus(skl);
- struct snd_soc_acpi_mach *mach = driver_data;
- struct skl_machine_pdata *pdata;
-
- mach = snd_soc_acpi_find_machine(mach);
- if (!mach) {
- dev_dbg(bus->dev, "No matching I2S machine driver found\n");
- mach = skl_find_hda_machine(skl, driver_data);
- if (!mach) {
- dev_err(bus->dev, "No matching machine driver found\n");
- return -ENODEV;
- }
- }
-
- skl->mach = mach;
- skl->fw_name = mach->fw_filename;
- pdata = mach->pdata;
-
- if (pdata) {
- skl->use_tplg_pcm = pdata->use_tplg_pcm;
- mach->mach_params.dmic_num =
- intel_nhlt_get_dmic_geo(&skl->pci->dev,
- skl->nhlt);
- }
-
- return 0;
-}
-
-static int skl_machine_device_register(struct skl_dev *skl)
-{
- struct snd_soc_acpi_mach *mach = skl->mach;
- struct hdac_bus *bus = skl_to_bus(skl);
- struct platform_device *pdev;
- int ret;
-
- pdev = platform_device_alloc(mach->drv_name, -1);
- if (pdev == NULL) {
- dev_err(bus->dev, "platform device alloc failed\n");
- return -EIO;
- }
-
- mach->mach_params.platform = dev_name(bus->dev);
- mach->mach_params.codec_mask = bus->codec_mask;
-
- ret = platform_device_add_data(pdev, (const void *)mach, sizeof(*mach));
- if (ret) {
- dev_err(bus->dev, "failed to add machine device platform data\n");
- platform_device_put(pdev);
- return ret;
- }
-
- ret = platform_device_add(pdev);
- if (ret) {
- dev_err(bus->dev, "failed to add machine device\n");
- platform_device_put(pdev);
- return -EIO;
- }
-
-
- skl->i2s_dev = pdev;
-
- return 0;
-}
-
-static void skl_machine_device_unregister(struct skl_dev *skl)
-{
- if (skl->i2s_dev)
- platform_device_unregister(skl->i2s_dev);
-}
-
-static int skl_dmic_device_register(struct skl_dev *skl)
-{
- struct hdac_bus *bus = skl_to_bus(skl);
- struct platform_device *pdev;
- int ret;
-
- /* SKL has one dmic port, so allocate dmic device for this */
- pdev = platform_device_alloc("dmic-codec", -1);
- if (!pdev) {
- dev_err(bus->dev, "failed to allocate dmic device\n");
- return -ENOMEM;
- }
-
- ret = platform_device_add(pdev);
- if (ret) {
- dev_err(bus->dev, "failed to add dmic device: %d\n", ret);
- platform_device_put(pdev);
- return ret;
- }
- skl->dmic_dev = pdev;
-
- return 0;
-}
-
-static void skl_dmic_device_unregister(struct skl_dev *skl)
-{
- if (skl->dmic_dev)
- platform_device_unregister(skl->dmic_dev);
-}
-
-static struct skl_clk_parent_src skl_clk_src[] = {
- { .clk_id = SKL_XTAL, .name = "xtal" },
- { .clk_id = SKL_CARDINAL, .name = "cardinal", .rate = 24576000 },
- { .clk_id = SKL_PLL, .name = "pll", .rate = 96000000 },
-};
-
-struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(skl_clk_src); i++) {
- if (skl_clk_src[i].clk_id == clk_id)
- return &skl_clk_src[i];
- }
-
- return NULL;
-}
-
-static void init_skl_xtal_rate(int pci_id)
-{
- switch (pci_id) {
- case PCI_DEVICE_ID_INTEL_HDA_SKL_LP:
- case PCI_DEVICE_ID_INTEL_HDA_KBL_LP:
- skl_clk_src[0].rate = 24000000;
- return;
-
- default:
- skl_clk_src[0].rate = 19200000;
- return;
- }
-}
-
-static int skl_clock_device_register(struct skl_dev *skl)
-{
- struct platform_device_info pdevinfo = {NULL};
- struct skl_clk_pdata *clk_pdata;
-
- if (!skl->nhlt)
- return 0;
-
- clk_pdata = devm_kzalloc(&skl->pci->dev, sizeof(*clk_pdata),
- GFP_KERNEL);
- if (!clk_pdata)
- return -ENOMEM;
-
- init_skl_xtal_rate(skl->pci->device);
-
- clk_pdata->parent_clks = skl_clk_src;
- clk_pdata->ssp_clks = skl_ssp_clks;
- clk_pdata->num_clks = ARRAY_SIZE(skl_ssp_clks);
-
- /* Query NHLT to fill the rates and parent */
- skl_get_clks(skl, clk_pdata->ssp_clks);
- clk_pdata->pvt_data = skl;
-
- /* Register Platform device */
- pdevinfo.parent = &skl->pci->dev;
- pdevinfo.id = -1;
- pdevinfo.name = "skl-ssp-clk";
- pdevinfo.data = clk_pdata;
- pdevinfo.size_data = sizeof(*clk_pdata);
- skl->clk_dev = platform_device_register_full(&pdevinfo);
- return PTR_ERR_OR_ZERO(skl->clk_dev);
-}
-
-static void skl_clock_device_unregister(struct skl_dev *skl)
-{
- if (skl->clk_dev)
- platform_device_unregister(skl->clk_dev);
-}
-
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
-
-#define IDISP_INTEL_VENDOR_ID 0x80860000
-
-/*
- * load the legacy codec driver
- */
-static void load_codec_module(struct hda_codec *codec)
-{
-#ifdef MODULE
- char modalias[MODULE_NAME_LEN];
- const char *mod = NULL;
-
- snd_hdac_codec_modalias(&codec->core, modalias, sizeof(modalias));
- mod = modalias;
- dev_dbg(&codec->core.dev, "loading %s codec module\n", mod);
- request_module(mod);
-#endif
-}
-
-#endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */
-
-static struct hda_codec *skl_codec_device_init(struct hdac_bus *bus, int addr)
-{
- struct hda_codec *codec;
- int ret;
-
- codec = snd_hda_codec_device_init(to_hda_bus(bus), addr, "ehdaudio%dD%d", bus->idx, addr);
- if (IS_ERR(codec)) {
- dev_err(bus->dev, "device init failed for hdac device\n");
- return codec;
- }
-
- codec->core.type = HDA_DEV_ASOC;
-
- ret = snd_hdac_device_register(&codec->core);
- if (ret) {
- dev_err(bus->dev, "failed to register hdac device\n");
- put_device(&codec->core.dev);
- return ERR_PTR(ret);
- }
-
- return codec;
-}
-
-/*
- * Probe the given codec address
- */
-static int probe_codec(struct hdac_bus *bus, int addr)
-{
- unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
- (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
- unsigned int res = -1;
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
- struct skl_dev *skl = bus_to_skl(bus);
- struct hdac_hda_priv *hda_codec;
-#endif
- struct hda_codec *codec;
-
- mutex_lock(&bus->cmd_mutex);
- snd_hdac_bus_send_cmd(bus, cmd);
- snd_hdac_bus_get_response(bus, addr, &res);
- mutex_unlock(&bus->cmd_mutex);
- if (res == -1)
- return -EIO;
- dev_dbg(bus->dev, "codec #%d probed OK: %x\n", addr, res);
-
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
- hda_codec = devm_kzalloc(&skl->pci->dev, sizeof(*hda_codec),
- GFP_KERNEL);
- if (!hda_codec)
- return -ENOMEM;
-
- codec = skl_codec_device_init(bus, addr);
- if (IS_ERR(codec))
- return PTR_ERR(codec);
-
- hda_codec->codec = codec;
- hda_codec->dev_index = addr;
- dev_set_drvdata(&codec->core.dev, hda_codec);
-
- /* use legacy bus only for HDA codecs, idisp uses ext bus */
- if ((res & 0xFFFF0000) != IDISP_INTEL_VENDOR_ID) {
- codec->core.type = HDA_DEV_LEGACY;
- load_codec_module(hda_codec->codec);
- }
- return 0;
-#else
- codec = skl_codec_device_init(bus, addr);
- return PTR_ERR_OR_ZERO(codec);
-#endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */
-}
-
-/* Codec initialization */
-static void skl_codec_create(struct hdac_bus *bus)
-{
- int c, max_slots;
-
- max_slots = HDA_MAX_CODECS;
-
- /* First try to probe all given codec slots */
- for (c = 0; c < max_slots; c++) {
- if ((bus->codec_mask & (1 << c))) {
- if (probe_codec(bus, c) < 0) {
- /*
- * Some BIOSen give you wrong codec addresses
- * that don't exist
- */
- dev_warn(bus->dev,
- "Codec #%d probe error; disabling it...\n", c);
- bus->codec_mask &= ~(1 << c);
- /*
- * More badly, accessing to a non-existing
- * codec often screws up the controller bus,
- * and disturbs the further communications.
- * Thus if an error occurs during probing,
- * better to reset the controller bus to get
- * back to the sanity state.
- */
- snd_hdac_bus_stop_chip(bus);
- skl_init_chip(bus, true);
- }
- }
- }
-}
-
-static void skl_probe_work(struct work_struct *work)
-{
- struct skl_dev *skl = container_of(work, struct skl_dev, probe_work);
- struct hdac_bus *bus = skl_to_bus(skl);
- struct hdac_ext_link *hlink;
- int err;
-
- if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI))
- snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true);
-
- skl_init_pci(skl);
- skl_dum_set(bus);
-
- err = skl_init_chip(bus, true);
- if (err < 0) {
- dev_err(bus->dev, "Init chip failed with err: %d\n", err);
- goto out_err;
- }
-
- /* codec detection */
- if (!bus->codec_mask)
- dev_info(bus->dev, "no hda codecs found!\n");
-
- /* create codec instances */
- skl_codec_create(bus);
-
- /* register platform dai and controls */
- err = skl_platform_register(bus->dev);
- if (err < 0) {
- dev_err(bus->dev, "platform register failed: %d\n", err);
- goto out_err;
- }
-
- err = skl_machine_device_register(skl);
- if (err < 0) {
- dev_err(bus->dev, "machine register failed: %d\n", err);
- goto out_err;
- }
-
- /*
- * we are done probing so decrement link counts
- */
- list_for_each_entry(hlink, &bus->hlink_list, list)
- snd_hdac_ext_bus_link_put(bus, hlink);
-
- if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI))
- snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
-
- /* configure PM */
- pm_runtime_put_noidle(bus->dev);
- pm_runtime_allow(bus->dev);
- skl->init_done = 1;
-
- return;
-
-out_err:
- if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI))
- snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
-}
-
-/*
- * constructor
- */
-static int skl_create(struct pci_dev *pci,
- struct skl_dev **rskl)
-{
- struct hdac_ext_bus_ops *ext_ops = NULL;
- struct skl_dev *skl;
- struct hdac_bus *bus;
- struct hda_bus *hbus;
- int err;
-
- *rskl = NULL;
-
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- skl = devm_kzalloc(&pci->dev, sizeof(*skl), GFP_KERNEL);
- if (!skl) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- hbus = skl_to_hbus(skl);
- bus = skl_to_bus(skl);
-
- INIT_LIST_HEAD(&skl->ppl_list);
- INIT_LIST_HEAD(&skl->bind_list);
-
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
- ext_ops = snd_soc_hdac_hda_get_ops();
-#endif
- snd_hdac_ext_bus_init(bus, &pci->dev, NULL, ext_ops);
- bus->use_posbuf = 1;
- skl->pci = pci;
- INIT_WORK(&skl->probe_work, skl_probe_work);
- bus->bdl_pos_adj = 0;
-
- mutex_init(&hbus->prepare_mutex);
- hbus->pci = pci;
- hbus->mixer_assigned = -1;
- hbus->modelname = "sklbus";
-
- *rskl = skl;
-
- return 0;
-}
-
-static int skl_first_init(struct hdac_bus *bus)
-{
- struct skl_dev *skl = bus_to_skl(bus);
- struct pci_dev *pci = skl->pci;
- int err;
- unsigned short gcap;
- int cp_streams, pb_streams, start_idx;
-
- err = pci_request_regions(pci, "Skylake HD audio");
- if (err < 0)
- return err;
-
- bus->addr = pci_resource_start(pci, 0);
- bus->remap_addr = pci_ioremap_bar(pci, 0);
- if (bus->remap_addr == NULL) {
- dev_err(bus->dev, "ioremap error\n");
- return -ENXIO;
- }
-
- snd_hdac_bus_parse_capabilities(bus);
-
- /* check if PPCAP exists */
- if (!bus->ppcap) {
- dev_err(bus->dev, "bus ppcap not set, HDAudio or DSP not present?\n");
- return -ENODEV;
- }
-
- if (skl_acquire_irq(bus, 0) < 0)
- return -EBUSY;
-
- pci_set_master(pci);
- synchronize_irq(bus->irq);
-
- gcap = snd_hdac_chip_readw(bus, GCAP);
- dev_dbg(bus->dev, "chipset global capabilities = 0x%x\n", gcap);
-
- /* read number of streams from GCAP register */
- cp_streams = (gcap >> 8) & 0x0f;
- pb_streams = (gcap >> 12) & 0x0f;
-
- if (!pb_streams && !cp_streams) {
- dev_err(bus->dev, "no streams found in GCAP definitions?\n");
- return -EIO;
- }
-
- bus->num_streams = cp_streams + pb_streams;
-
- /* allow 64bit DMA address if supported by H/W */
- if (dma_set_mask_and_coherent(bus->dev, DMA_BIT_MASK(64)))
- dma_set_mask_and_coherent(bus->dev, DMA_BIT_MASK(32));
- dma_set_max_seg_size(bus->dev, UINT_MAX);
-
- /* initialize streams */
- snd_hdac_ext_stream_init_all
- (bus, 0, cp_streams, SNDRV_PCM_STREAM_CAPTURE);
- start_idx = cp_streams;
- snd_hdac_ext_stream_init_all
- (bus, start_idx, pb_streams, SNDRV_PCM_STREAM_PLAYBACK);
-
- err = snd_hdac_bus_alloc_stream_pages(bus);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int skl_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- struct skl_dev *skl;
- struct hdac_bus *bus = NULL;
- int err;
-
- switch (skl_pci_binding) {
- case SND_SKL_PCI_BIND_AUTO:
- err = snd_intel_dsp_driver_probe(pci);
- if (err != SND_INTEL_DSP_DRIVER_ANY &&
- err != SND_INTEL_DSP_DRIVER_SST)
- return -ENODEV;
- break;
- case SND_SKL_PCI_BIND_LEGACY:
- dev_info(&pci->dev, "Module parameter forced binding with HDAudio legacy, aborting probe\n");
- return -ENODEV;
- case SND_SKL_PCI_BIND_ASOC:
- dev_info(&pci->dev, "Module parameter forced binding with SKL driver, bypassed detection logic\n");
- break;
- default:
- dev_err(&pci->dev, "invalid value for skl_pci_binding module parameter, ignored\n");
- break;
- }
-
- /* we use ext core ops, so provide NULL for ops here */
- err = skl_create(pci, &skl);
- if (err < 0)
- return err;
-
- bus = skl_to_bus(skl);
-
- err = skl_first_init(bus);
- if (err < 0) {
- dev_err(bus->dev, "skl_first_init failed with err: %d\n", err);
- goto out_free;
- }
-
- skl->pci_id = pci->device;
-
- device_disable_async_suspend(bus->dev);
-
- skl->nhlt = intel_nhlt_init(bus->dev);
-
- if (skl->nhlt == NULL) {
-#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
- dev_err(bus->dev, "no nhlt info found\n");
- err = -ENODEV;
- goto out_free;
-#else
- dev_warn(bus->dev, "no nhlt info found, continuing to try to enable HDAudio codec\n");
-#endif
- } else {
-
- err = skl_nhlt_create_sysfs(skl);
- if (err < 0) {
- dev_err(bus->dev, "skl_nhlt_create_sysfs failed with err: %d\n", err);
- goto out_nhlt_free;
- }
-
- skl_nhlt_update_topology_bin(skl);
-
- /* create device for dsp clk */
- err = skl_clock_device_register(skl);
- if (err < 0) {
- dev_err(bus->dev, "skl_clock_device_register failed with err: %d\n", err);
- goto out_clk_free;
- }
- }
-
- pci_set_drvdata(skl->pci, bus);
-
-
- err = skl_find_machine(skl, (void *)pci_id->driver_data);
- if (err < 0) {
- dev_err(bus->dev, "skl_find_machine failed with err: %d\n", err);
- goto out_nhlt_free;
- }
-
- err = skl_init_dsp(skl);
- if (err < 0) {
- dev_dbg(bus->dev, "error failed to register dsp\n");
- goto out_nhlt_free;
- }
- skl->enable_miscbdcge = skl_enable_miscbdcge;
- skl->clock_power_gating = skl_clock_power_gating;
-
- if (bus->mlcap)
- snd_hdac_ext_bus_get_ml_capabilities(bus);
-
- /* create device for soc dmic */
- err = skl_dmic_device_register(skl);
- if (err < 0) {
- dev_err(bus->dev, "skl_dmic_device_register failed with err: %d\n", err);
- goto out_dsp_free;
- }
-
- if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
- err = snd_hdac_i915_init(bus);
- if (err < 0)
- goto out_dmic_unregister;
- }
- schedule_work(&skl->probe_work);
-
- return 0;
-
-out_dmic_unregister:
- skl_dmic_device_unregister(skl);
-out_dsp_free:
- skl_free_dsp(skl);
-out_clk_free:
- skl_clock_device_unregister(skl);
-out_nhlt_free:
- if (skl->nhlt)
- intel_nhlt_free(skl->nhlt);
-out_free:
- skl_free(bus);
-
- return err;
-}
-
-static void skl_shutdown(struct pci_dev *pci)
-{
- struct hdac_bus *bus = pci_get_drvdata(pci);
- struct hdac_stream *s;
- struct hdac_ext_stream *stream;
- struct skl_dev *skl;
-
- if (!bus)
- return;
-
- skl = bus_to_skl(bus);
-
- if (!skl->init_done)
- return;
-
- snd_hdac_stop_streams(bus);
- snd_hdac_ext_bus_link_power_down_all(bus);
- skl_dsp_sleep(skl->dsp);
-
- list_for_each_entry(s, &bus->stream_list, list) {
- stream = stream_to_hdac_ext_stream(s);
- snd_hdac_ext_stream_decouple(bus, stream, false);
- }
-
- snd_hdac_bus_stop_chip(bus);
-}
-
-static void skl_remove(struct pci_dev *pci)
-{
- struct hdac_bus *bus = pci_get_drvdata(pci);
- struct skl_dev *skl = bus_to_skl(bus);
-
- cancel_work_sync(&skl->probe_work);
-
- pm_runtime_get_noresume(&pci->dev);
-
- /* codec removal, invoke bus_device_remove */
- snd_hdac_ext_bus_device_remove(bus);
-
- skl_platform_unregister(&pci->dev);
- skl_free_dsp(skl);
- skl_machine_device_unregister(skl);
- skl_dmic_device_unregister(skl);
- skl_clock_device_unregister(skl);
- skl_nhlt_remove_sysfs(skl);
- if (skl->nhlt)
- intel_nhlt_free(skl->nhlt);
- skl_free(bus);
-}
-
-/* PCI IDs */
-static const struct pci_device_id skl_ids[] = {
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL)
- { PCI_DEVICE_DATA(INTEL, HDA_SKL_LP, &snd_soc_acpi_intel_skl_machines) },
-#endif
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL)
- { PCI_DEVICE_DATA(INTEL, HDA_APL, &snd_soc_acpi_intel_bxt_machines) },
-#endif
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL)
- { PCI_DEVICE_DATA(INTEL, HDA_KBL_LP, &snd_soc_acpi_intel_kbl_machines) },
-#endif
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_GLK)
- { PCI_DEVICE_DATA(INTEL, HDA_GML, &snd_soc_acpi_intel_glk_machines) },
-#endif
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CNL)
- { PCI_DEVICE_DATA(INTEL, HDA_CNL_LP, &snd_soc_acpi_intel_cnl_machines) },
-#endif
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CFL)
- { PCI_DEVICE_DATA(INTEL, HDA_CNL_H, &snd_soc_acpi_intel_cnl_machines) },
-#endif
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CML_LP)
- { PCI_DEVICE_DATA(INTEL, HDA_CML_LP, &snd_soc_acpi_intel_cnl_machines) },
-#endif
-#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CML_H)
- { PCI_DEVICE_DATA(INTEL, HDA_CML_H, &snd_soc_acpi_intel_cnl_machines) },
-#endif
- { 0, }
-};
-MODULE_DEVICE_TABLE(pci, skl_ids);
-
-/* pci_driver definition */
-static struct pci_driver skl_driver = {
- .name = KBUILD_MODNAME,
- .id_table = skl_ids,
- .probe = skl_probe,
- .remove = skl_remove,
- .shutdown = skl_shutdown,
- .driver = {
- .pm = &skl_pm,
- },
-};
-module_pci_driver(skl_driver);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Intel Skylake ASoC HDA driver");
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
deleted file mode 100644
index f55f8b3dbdc3..000000000000
--- a/sound/soc/intel/skylake/skl.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * skl.h - HD Audio skylake definitions.
- *
- * Copyright (C) 2015 Intel Corp
- * Author: Jeeja KP <jeeja.kp@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#ifndef __SOUND_SOC_SKL_H
-#define __SOUND_SOC_SKL_H
-
-#include <sound/hda_register.h>
-#include <sound/hdaudio_ext.h>
-#include <sound/hda_codec.h>
-#include <sound/soc.h>
-#include "skl-ssp-clk.h"
-#include "skl-sst-ipc.h"
-
-#define SKL_SUSPEND_DELAY 2000
-
-#define SKL_MAX_ASTATE_CFG 3
-
-#define AZX_PCIREG_PGCTL 0x44
-#define AZX_PGCTL_LSRMD_MASK (1 << 4)
-#define AZX_PGCTL_ADSPPGD BIT(2)
-#define AZX_PCIREG_CGCTL 0x48
-#define AZX_CGCTL_MISCBDCGE_MASK (1 << 6)
-#define AZX_CGCTL_ADSPDCGE BIT(1)
-/* D0I3C Register fields */
-#define AZX_REG_VS_D0I3C_CIP 0x1 /* Command in progress */
-#define AZX_REG_VS_D0I3C_I3 0x4 /* D0i3 enable */
-#define SKL_MAX_DMACTRL_CFG 18
-#define DMA_CLK_CONTROLS 1
-#define DMA_TRANSMITION_START 2
-#define DMA_TRANSMITION_STOP 3
-
-#define AZX_VS_EM2_DUM BIT(23)
-#define AZX_REG_VS_EM2_L1SEN BIT(13)
-
-struct skl_debug;
-
-struct skl_astate_param {
- u32 kcps;
- u32 clk_src;
-};
-
-struct skl_astate_config {
- u32 count;
- struct skl_astate_param astate_table[];
-};
-
-struct skl_fw_config {
- struct skl_astate_config *astate_cfg;
-};
-
-struct skl_dev {
- struct hda_bus hbus;
- struct pci_dev *pci;
-
- unsigned int init_done:1; /* delayed init status */
- struct platform_device *dmic_dev;
- struct platform_device *i2s_dev;
- struct platform_device *clk_dev;
- struct snd_soc_component *component;
- struct snd_soc_dai_driver *dais;
-
- struct nhlt_acpi_table *nhlt; /* nhlt ptr */
-
- struct list_head ppl_list;
- struct list_head bind_list;
-
- const char *fw_name;
- char tplg_name[64];
- unsigned short pci_id;
-
- int supend_active;
-
- struct work_struct probe_work;
-
- struct skl_debug *debugfs;
- u8 nr_modules;
- struct skl_module **modules;
- bool use_tplg_pcm;
- struct skl_fw_config cfg;
- struct snd_soc_acpi_mach *mach;
-
- struct device *dev;
- struct sst_dsp *dsp;
-
- /* boot */
- wait_queue_head_t boot_wait;
- bool boot_complete;
-
- /* module load */
- wait_queue_head_t mod_load_wait;
- bool mod_load_complete;
- bool mod_load_status;
-
- /* IPC messaging */
- struct sst_generic_ipc ipc;
-
- /* callback for miscbdge */
- void (*enable_miscbdcge)(struct device *dev, bool enable);
- /* Is CGCTL.MISCBDCGE disabled */
- bool miscbdcg_disabled;
-
- /* Populate module information */
- struct list_head uuid_list;
-
- /* Is firmware loaded */
- bool fw_loaded;
-
- /* first boot ? */
- bool is_first_boot;
-
- /* multi-core */
- struct skl_dsp_cores cores;
-
- /* library info */
- struct skl_lib_info lib_info[SKL_MAX_LIB];
- int lib_count;
-
- /* Callback to update D0i3C register */
- void (*update_d0i3c)(struct device *dev, bool enable);
-
- struct skl_d0i3_data d0i3;
-
- const struct skl_dsp_ops *dsp_ops;
-
- /* Callback to update dynamic clock and power gating registers */
- void (*clock_power_gating)(struct device *dev, bool enable);
-};
-
-#define skl_to_bus(s) (&(s)->hbus.core)
-#define bus_to_skl(bus) container_of(bus, struct skl_dev, hbus.core)
-
-#define skl_to_hbus(s) (&(s)->hbus)
-#define hbus_to_skl(hbus) container_of((hbus), struct skl_dev, (hbus))
-
-/* to pass dai dma data */
-struct skl_dma_params {
- u32 format;
- u8 stream_tag;
-};
-
-struct skl_machine_pdata {
- bool use_tplg_pcm; /* use dais and dai links from topology */
-};
-
-struct skl_dsp_ops {
- int id;
- unsigned int num_cores;
- struct skl_dsp_loader_ops (*loader_ops)(void);
- int (*init)(struct device *dev, void __iomem *mmio_base,
- int irq, const char *fw_name,
- struct skl_dsp_loader_ops loader_ops,
- struct skl_dev **skl_sst);
- int (*init_fw)(struct device *dev, struct skl_dev *skl);
- void (*cleanup)(struct device *dev, struct skl_dev *skl);
-};
-
-int skl_platform_unregister(struct device *dev);
-int skl_platform_register(struct device *dev);
-
-int skl_nhlt_update_topology_bin(struct skl_dev *skl);
-int skl_init_dsp(struct skl_dev *skl);
-int skl_free_dsp(struct skl_dev *skl);
-int skl_suspend_late_dsp(struct skl_dev *skl);
-int skl_suspend_dsp(struct skl_dev *skl);
-int skl_resume_dsp(struct skl_dev *skl);
-void skl_cleanup_resources(struct skl_dev *skl);
-const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id);
-void skl_update_d0i3c(struct device *dev, bool enable);
-int skl_nhlt_create_sysfs(struct skl_dev *skl);
-void skl_nhlt_remove_sysfs(struct skl_dev *skl);
-void skl_get_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks);
-struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id);
-int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps,
- u32 caps_size, u32 node_id);
-
-struct skl_module_cfg;
-
-#ifdef CONFIG_DEBUG_FS
-struct skl_debug *skl_debugfs_init(struct skl_dev *skl);
-void skl_debugfs_exit(struct skl_dev *skl);
-void skl_debug_init_module(struct skl_debug *d,
- struct snd_soc_dapm_widget *w,
- struct skl_module_cfg *mconfig);
-#else
-static inline struct skl_debug *skl_debugfs_init(struct skl_dev *skl)
-{
- return NULL;
-}
-
-static inline void skl_debugfs_exit(struct skl_dev *skl)
-{}
-
-static inline void skl_debug_init_module(struct skl_debug *d,
- struct snd_soc_dapm_widget *w,
- struct skl_module_cfg *mconfig)
-{}
-#endif
-
-#endif /* __SOUND_SOC_SKL_H */