summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2019-09-09 09:55:20 -0400
committerMark Brown <broonie@kernel.org>2019-09-09 09:55:20 -0400
commitbb831786117519fc16dfd3eaa7b84e4f6bbb8d99 (patch)
tree18f8333bbaf6918a0246113eeb0f056011e436f2
parent6652ddbb5d83ecfc2591b92be063519714e40ebf (diff)
parent6fa5963c37a2e3335eba0b7455e35a01318ebc15 (diff)
Merge branch 'asoc-5.4' into asoc-next
-rw-r--r--Documentation/devicetree/bindings/dsp/fsl,dsp.yaml88
-rw-r--r--Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml4
-rw-r--r--Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml39
-rw-r--r--Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml57
-rw-r--r--Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt9
-rw-r--r--Documentation/devicetree/bindings/sound/amlogic,axg-pdm.txt6
-rw-r--r--Documentation/devicetree/bindings/sound/amlogic,axg-spdifin.txt6
-rw-r--r--Documentation/devicetree/bindings/sound/amlogic,axg-spdifout.txt6
-rw-r--r--Documentation/devicetree/bindings/sound/amlogic,axg-tdm-formatters.txt4
-rw-r--r--Documentation/devicetree/bindings/sound/amlogic,g12a-tohdmitx.txt5
-rw-r--r--Documentation/devicetree/bindings/sound/everest,es8316.txt23
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,esai.txt7
-rw-r--r--Documentation/devicetree/bindings/sound/fsl-sai.txt4
-rw-r--r--Documentation/devicetree/bindings/sound/sun50i-codec-analog.txt14
-rw-r--r--Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt63
-rw-r--r--Documentation/devicetree/bindings/sound/uda1334.txt17
-rw-r--r--include/sound/hdaudio.h69
-rw-r--r--include/sound/hdaudio_ext.h1
-rw-r--r--include/sound/hdmi-codec.h17
-rw-r--r--include/sound/intel-nhlt.h (renamed from sound/soc/intel/skylake/skl-nhlt.h)51
-rw-r--r--include/sound/pcm.h5
-rw-r--r--include/sound/soc-acpi-intel-match.h2
-rw-r--r--include/sound/soc-component.h387
-rw-r--r--include/sound/soc-dai.h28
-rw-r--r--include/sound/soc-dapm.h11
-rw-r--r--include/sound/soc-dpcm.h9
-rw-r--r--include/sound/soc.h348
-rw-r--r--include/sound/sof/dai-intel.h12
-rw-r--r--include/sound/sof/dai.h5
-rw-r--r--include/uapi/sound/sof/abi.h2
-rw-r--r--include/uapi/sound/sof/tokens.h9
-rw-r--r--sound/core/pcm_native.c2
-rw-r--r--sound/hda/Kconfig8
-rw-r--r--sound/hda/Makefile3
-rw-r--r--sound/hda/ext/hdac_ext_bus.c60
-rw-r--r--sound/hda/hdac_bus.c37
-rw-r--r--sound/hda/hdac_controller.c18
-rw-r--r--sound/hda/hdac_stream.c8
-rw-r--r--sound/hda/intel-nhlt.c107
-rw-r--r--sound/pci/hda/Kconfig11
-rw-r--r--sound/pci/hda/hda_codec.c8
-rw-r--r--sound/pci/hda/hda_controller.c6
-rw-r--r--sound/pci/hda/hda_controller.h3
-rw-r--r--sound/pci/hda/hda_intel.c105
-rw-r--r--sound/pci/hda/hda_tegra.c84
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile3
-rw-r--r--sound/soc/amd/acp-pcm-dma.c3
-rw-r--r--sound/soc/atmel/Kconfig30
-rw-r--r--sound/soc/atmel/atmel-classd.c7
-rw-r--r--sound/soc/atmel/atmel-pdmic.c7
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c293
-rw-r--r--sound/soc/atmel/mchp-i2s-mcc.c70
-rw-r--r--sound/soc/au1x/psc-ac97.c5
-rw-r--r--sound/soc/au1x/psc-i2s.c5
-rw-r--r--sound/soc/bcm/bcm2835-i2s.c4
-rw-r--r--sound/soc/bcm/cygnus-pcm.c6
-rw-r--r--sound/soc/bcm/cygnus-ssp.c7
-rw-r--r--sound/soc/cirrus/ep93xx-ac97.c4
-rw-r--r--sound/soc/cirrus/ep93xx-i2s.c4
-rw-r--r--sound/soc/codecs/88pm860x-codec.c15
-rw-r--r--sound/soc/codecs/Kconfig21
-rw-r--r--sound/soc/codecs/Makefile6
-rw-r--r--sound/soc/codecs/ad193x.c19
-rw-r--r--sound/soc/codecs/cs4271.c6
-rw-r--r--sound/soc/codecs/cs42l56.c8
-rw-r--r--sound/soc/codecs/cs42l73.c6
-rw-r--r--sound/soc/codecs/cs42xx8.c2
-rw-r--r--sound/soc/codecs/cs47l15.c1490
-rw-r--r--sound/soc/codecs/cs47l35.c2
-rw-r--r--sound/soc/codecs/cs47l90.c9
-rw-r--r--sound/soc/codecs/cs47l92.c2039
-rw-r--r--sound/soc/codecs/es8316.c66
-rw-r--r--sound/soc/codecs/es8328.c1
-rw-r--r--sound/soc/codecs/hdmi-codec.c46
-rw-r--r--sound/soc/codecs/inno_rk3036.c4
-rw-r--r--sound/soc/codecs/jz4725b.c4
-rw-r--r--sound/soc/codecs/jz4740.c4
-rw-r--r--sound/soc/codecs/madera.c531
-rw-r--r--sound/soc/codecs/madera.h10
-rw-r--r--sound/soc/codecs/max98371.c4
-rw-r--r--sound/soc/codecs/max98373.c34
-rw-r--r--sound/soc/codecs/max98373.h1
-rw-r--r--sound/soc/codecs/max9850.c13
-rw-r--r--sound/soc/codecs/max98926.c9
-rw-r--r--sound/soc/codecs/ml26124.c1
-rw-r--r--sound/soc/codecs/msm8916-wcd-analog.c12
-rw-r--r--sound/soc/codecs/msm8916-wcd-digital.c4
-rw-r--r--sound/soc/codecs/mt6351.c5
-rw-r--r--sound/soc/codecs/mt6358.c10
-rw-r--r--sound/soc/codecs/pcm3168a.c133
-rw-r--r--sound/soc/codecs/rk3328_codec.c4
-rw-r--r--sound/soc/codecs/rt1011.c29
-rw-r--r--sound/soc/codecs/rt1011.h3
-rw-r--r--sound/soc/codecs/rt1305.c3
-rw-r--r--sound/soc/codecs/rt1308.c51
-rw-r--r--sound/soc/codecs/rt1308.h6
-rw-r--r--sound/soc/codecs/rt5665.c8
-rw-r--r--sound/soc/codecs/rt5677.c20
-rw-r--r--sound/soc/codecs/sgtl5000.c248
-rw-r--r--sound/soc/codecs/sgtl5000.h2
-rw-r--r--sound/soc/codecs/sirf-audio-codec.c4
-rw-r--r--sound/soc/codecs/tlv320aic23.c2
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c8
-rw-r--r--sound/soc/codecs/tscs454.c1
-rw-r--r--sound/soc/codecs/twl6040.c4
-rw-r--r--sound/soc/codecs/uda1334.c295
-rw-r--r--sound/soc/codecs/wcd-clsh-v2.c2
-rw-r--r--sound/soc/codecs/wcd9335.c23
-rw-r--r--sound/soc/codecs/wm8955.c4
-rw-r--r--sound/soc/codecs/wm8988.c2
-rw-r--r--sound/soc/codecs/wm_adsp.c6
-rw-r--r--sound/soc/codecs/wm_adsp.h4
-rw-r--r--sound/soc/fsl/fsl_asrc.c4
-rw-r--r--sound/soc/fsl/fsl_audmix.c4
-rw-r--r--sound/soc/fsl/fsl_esai.c267
-rw-r--r--sound/soc/fsl/fsl_sai.c358
-rw-r--r--sound/soc/fsl/fsl_sai.h85
-rw-r--r--sound/soc/fsl/fsl_spdif.c4
-rw-r--r--sound/soc/fsl/fsl_ssi.c4
-rw-r--r--sound/soc/fsl/imx-audmix.c4
-rw-r--r--sound/soc/fsl/imx-audmux.c4
-rw-r--r--sound/soc/fsl/imx-ssi.c4
-rw-r--r--sound/soc/generic/audio-graph-card.c19
-rw-r--r--sound/soc/generic/simple-card-utils.c7
-rw-r--r--sound/soc/generic/simple-card.c22
-rw-r--r--sound/soc/intel/Kconfig1
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-ipc.c65
-rw-r--r--sound/soc/intel/boards/Kconfig28
-rw-r--r--sound/soc/intel/boards/bdw-rt5677.c6
-rw-r--r--sound/soc/intel/boards/broadwell.c6
-rw-r--r--sound/soc/intel/boards/bxt_da7219_max98357a.c31
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c3
-rw-r--r--sound/soc/intel/boards/haswell.c6
-rw-r--r--sound/soc/intel/boards/skl_hda_dsp_common.c5
-rw-r--r--sound/soc/intel/boards/skl_hda_dsp_generic.c4
-rw-r--r--sound/soc/intel/boards/sof_rt5682.c3
-rw-r--r--sound/soc/intel/common/Makefile1
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-cnl-match.c12
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-ehl-match.c18
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-tgl-match.c24
-rw-r--r--sound/soc/intel/common/soc-intel-quirks.h5
-rw-r--r--sound/soc/intel/common/sst-acpi.c3
-rw-r--r--sound/soc/intel/common/sst-ipc.c69
-rw-r--r--sound/soc/intel/common/sst-ipc.h28
-rw-r--r--sound/soc/intel/haswell/sst-haswell-ipc.c164
-rw-r--r--sound/soc/intel/skylake/Makefile12
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c50
-rw-r--r--sound/soc/intel/skylake/cnl-sst-dsp.h7
-rw-r--r--sound/soc/intel/skylake/cnl-sst.c43
-rw-r--r--sound/soc/intel/skylake/skl-debug.c42
-rw-r--r--sound/soc/intel/skylake/skl-messages.c264
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c107
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c74
-rw-r--r--sound/soc/intel/skylake/skl-ssp-clk.c5
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.c10
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h29
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c160
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h55
-rw-r--r--sound/soc/intel/skylake/skl-sst-utils.c37
-rw-r--r--sound/soc/intel/skylake/skl-sst.c54
-rw-r--r--sound/soc/intel/skylake/skl-topology.c494
-rw-r--r--sound/soc/intel/skylake/skl-topology.h43
-rw-r--r--sound/soc/intel/skylake/skl.c73
-rw-r--r--sound/soc/intel/skylake/skl.h105
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c8
-rw-r--r--sound/soc/mediatek/common/mtk-btcvsd.c4
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-common.h21
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-pcm.c38
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-afe-pcm.c5
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-afe-pcm.c8
-rw-r--r--sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c15
-rw-r--r--sound/soc/mediatek/mt8183/mt8183-dai-tdm.c177
-rw-r--r--sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c150
-rw-r--r--sound/soc/mediatek/mt8183/mt8183-reg.h8
-rw-r--r--sound/soc/meson/axg-card.c11
-rw-r--r--sound/soc/meson/axg-fifo.c6
-rw-r--r--sound/soc/meson/axg-fifo.h1
-rw-r--r--sound/soc/meson/axg-frddr.c105
-rw-r--r--sound/soc/meson/axg-pdm.c4
-rw-r--r--sound/soc/meson/axg-spdifin.c4
-rw-r--r--sound/soc/meson/axg-spdifout.c4
-rw-r--r--sound/soc/meson/axg-tdm-formatter.c4
-rw-r--r--sound/soc/meson/axg-tdmin.c47
-rw-r--r--sound/soc/meson/axg-tdmout.c103
-rw-r--r--sound/soc/meson/axg-toddr.c83
-rw-r--r--sound/soc/meson/g12a-tohdmitx.c38
-rw-r--r--sound/soc/mxs/mxs-saif.c13
-rw-r--r--sound/soc/nuc900/Kconfig29
-rw-r--r--sound/soc/nuc900/Makefile12
-rw-r--r--sound/soc/nuc900/nuc900-ac97.c391
-rw-r--r--sound/soc/nuc900/nuc900-audio.c73
-rw-r--r--sound/soc/nuc900/nuc900-audio.h108
-rw-r--r--sound/soc/nuc900/nuc900-pcm.c321
-rw-r--r--sound/soc/pxa/mmp-sspa.c4
-rw-r--r--sound/soc/qcom/common.c22
-rw-r--r--sound/soc/qcom/lpass-platform.c5
-rw-r--r--sound/soc/rockchip/rockchip_i2s.c3
-rw-r--r--sound/soc/rockchip/rockchip_max98090.c7
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c3
-rw-r--r--sound/soc/samsung/speyside.c3
-rw-r--r--sound/soc/samsung/tm2_wm5110.c10
-rw-r--r--sound/soc/sh/rcar/core.c16
-rw-r--r--sound/soc/sh/rcar/rsnd.h12
-rw-r--r--sound/soc/sirf/sirf-usp.c4
-rw-r--r--sound/soc/soc-component.c561
-rw-r--r--sound/soc/soc-compress.c57
-rw-r--r--sound/soc/soc-core.c1225
-rw-r--r--sound/soc/soc-dai.c407
-rw-r--r--sound/soc/soc-dapm.c361
-rw-r--r--sound/soc/soc-jack.c18
-rw-r--r--sound/soc/soc-pcm.c546
-rw-r--r--sound/soc/soc-topology.c2
-rw-r--r--sound/soc/soc-utils.c199
-rw-r--r--sound/soc/sof/Kconfig11
-rw-r--r--sound/soc/sof/Makefile8
-rw-r--r--sound/soc/sof/core.c4
-rw-r--r--sound/soc/sof/debug.c50
-rw-r--r--sound/soc/sof/imx/Kconfig23
-rw-r--r--sound/soc/sof/imx/Makefile4
-rw-r--r--sound/soc/sof/imx/imx8.c394
-rw-r--r--sound/soc/sof/intel/Kconfig33
-rw-r--r--sound/soc/sof/intel/apl.c4
-rw-r--r--sound/soc/sof/intel/bdw.c166
-rw-r--r--sound/soc/sof/intel/byt.c174
-rw-r--r--sound/soc/sof/intel/cnl.c36
-rw-r--r--sound/soc/sof/intel/hda-bus.c86
-rw-r--r--sound/soc/sof/intel/hda-codec.c50
-rw-r--r--sound/soc/sof/intel/hda-ctrl.c21
-rw-r--r--sound/soc/sof/intel/hda-dai.c38
-rw-r--r--sound/soc/sof/intel/hda-dsp.c100
-rw-r--r--sound/soc/sof/intel/hda-ipc.c150
-rw-r--r--sound/soc/sof/intel/hda.c112
-rw-r--r--sound/soc/sof/intel/hda.h18
-rw-r--r--sound/soc/sof/ipc.c8
-rw-r--r--sound/soc/sof/loader.c182
-rw-r--r--sound/soc/sof/ops.h46
-rw-r--r--sound/soc/sof/pcm.c66
-rw-r--r--sound/soc/sof/pm.c6
-rw-r--r--sound/soc/sof/sof-of-dev.c143
-rw-r--r--sound/soc/sof/sof-pci-dev.c47
-rw-r--r--sound/soc/sof/sof-priv.h19
-rw-r--r--sound/soc/sof/topology.c275
-rw-r--r--sound/soc/sof/trace.c9
-rw-r--r--sound/soc/spear/spdif_in.c5
-rw-r--r--sound/soc/sprd/sprd-mcdt.c4
-rw-r--r--sound/soc/sti/sti_uniperif.c4
-rw-r--r--sound/soc/stm/stm32_i2s.c5
-rw-r--r--sound/soc/stm/stm32_sai.c8
-rw-r--r--sound/soc/stm/stm32_spdifrx.c4
-rw-r--r--sound/soc/sunxi/sun4i-codec.c14
-rw-r--r--sound/soc/sunxi/sun4i-i2s.c659
-rw-r--r--sound/soc/sunxi/sun50i-codec-analog.c4
-rw-r--r--sound/soc/sunxi/sun8i-codec-analog.c4
-rw-r--r--sound/soc/sunxi/sun8i-codec.c4
-rw-r--r--sound/soc/tegra/tegra20_das.c4
-rw-r--r--sound/soc/tegra/tegra30_ahub.c5
-rw-r--r--sound/soc/tegra/tegra30_i2s.c4
-rw-r--r--sound/soc/ti/Kconfig4
-rw-r--r--sound/soc/ti/davinci-evm.c2
-rw-r--r--sound/soc/ti/davinci-i2s.c8
-rw-r--r--sound/soc/ti/davinci-mcasp.c185
-rw-r--r--sound/soc/ti/edma-pcm.c17
-rw-r--r--sound/soc/ti/n810.c1
-rw-r--r--sound/soc/ti/rx51.c15
-rw-r--r--sound/soc/uniphier/aio-dma.c8
-rw-r--r--sound/soc/uniphier/evea.c4
-rw-r--r--sound/soc/xilinx/xlnx_formatter_pcm.c2
-rw-r--r--sound/soc/xilinx/xlnx_i2s.c4
-rw-r--r--sound/soc/xilinx/xlnx_spdif.c3
-rw-r--r--sound/soc/xtensa/xtfpga-i2s.c5
-rw-r--r--sound/soc/zte/zx-tdm.c1
272 files changed, 12088 insertions, 6831 deletions
diff --git a/Documentation/devicetree/bindings/dsp/fsl,dsp.yaml b/Documentation/devicetree/bindings/dsp/fsl,dsp.yaml
new file mode 100644
index 000000000000..3248595dc93c
--- /dev/null
+++ b/Documentation/devicetree/bindings/dsp/fsl,dsp.yaml
@@ -0,0 +1,88 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/dsp/fsl,dsp.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: NXP i.MX8 DSP core
8
9maintainers:
10 - Daniel Baluta <daniel.baluta@nxp.com>
11
12description: |
13 Some boards from i.MX8 family contain a DSP core used for
14 advanced pre- and post- audio processing.
15
16properties:
17 compatible:
18 enum:
19 - fsl,imx8qxp-dsp
20
21 reg:
22 description: Should contain register location and length
23
24 clocks:
25 items:
26 - description: ipg clock
27 - description: ocram clock
28 - description: core clock
29
30 clock-names:
31 items:
32 - const: ipg
33 - const: ocram
34 - const: core
35
36 power-domains:
37 description:
38 List of phandle and PM domain specifier as documented in
39 Documentation/devicetree/bindings/power/power_domain.txt
40 maxItems: 4
41
42 mboxes:
43 description:
44 List of <&phandle type channel> - 2 channels for TXDB, 2 channels for RXDB
45 (see mailbox/fsl,mu.txt)
46 maxItems: 4
47
48 mbox-names:
49 items:
50 - const: txdb0
51 - const: txdb1
52 - const: rxdb0
53 - const: rxdb1
54
55 memory-region:
56 description:
57 phandle to a node describing reserved memory (System RAM memory)
58 used by DSP (see bindings/reserved-memory/reserved-memory.txt)
59 maxItems: 1
60
61required:
62 - compatible
63 - reg
64 - clocks
65 - clock-names
66 - power-domains
67 - mboxes
68 - mbox-names
69 - memory-region
70
71examples:
72 - |
73 #include <dt-bindings/firmware/imx/rsrc.h>
74 #include <dt-bindings/clock/imx8-clock.h>
75 dsp@596e8000 {
76 compatible = "fsl,imx8qxp-dsp";
77 reg = <0x596e8000 0x88000>;
78 clocks = <&adma_lpcg IMX_ADMA_LPCG_DSP_IPG_CLK>,
79 <&adma_lpcg IMX_ADMA_LPCG_OCRAM_IPG_CLK>,
80 <&adma_lpcg IMX_ADMA_LPCG_DSP_CORE_CLK>;
81 clock-names = "ipg", "ocram", "core";
82 power-domains = <&pd IMX_SC_R_MU_13A>,
83 <&pd IMX_SC_R_MU_13B>,
84 <&pd IMX_SC_R_DSP>,
85 <&pd IMX_SC_R_DSP_RAM>;
86 mbox-names = "txdb0", "txdb1", "rxdb0", "rxdb1";
87 mboxes = <&lsio_mu13 2 0>, <&lsio_mu13 2 1>, <&lsio_mu13 3 0>, <&lsio_mu13 3 1>;
88 };
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml
index e0284d8c3b63..38d4cede0860 100644
--- a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml
@@ -70,7 +70,9 @@ allOf:
70 properties: 70 properties:
71 compatible: 71 compatible:
72 contains: 72 contains:
73 const: allwinner,sun8i-h3-spdif 73 enum:
74 - allwinner,sun8i-h3-spdif
75 - allwinner,sun50i-h6-spdif
74 76
75 then: 77 then:
76 properties: 78 properties:
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml
new file mode 100644
index 000000000000..f290eb72a878
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml
@@ -0,0 +1,39 @@
1# SPDX-License-Identifier: GPL-2.0
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/sound/allwinner,sun50i-a64-codec-analog.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Allwinner A64 Analog Codec Device Tree Bindings
8
9maintainers:
10 - Chen-Yu Tsai <wens@csie.org>
11 - Maxime Ripard <maxime.ripard@bootlin.com>
12
13properties:
14 compatible:
15 const: allwinner,sun50i-a64-codec-analog
16
17 reg:
18 maxItems: 1
19
20 cpvdd-supply:
21 description:
22 Regulator for the headphone amplifier
23
24required:
25 - compatible
26 - reg
27 - cpvdd-supply
28
29additionalProperties: false
30
31examples:
32 - |
33 codec_analog: codec-analog@1f015c0 {
34 compatible = "allwinner,sun50i-a64-codec-analog";
35 reg = <0x01f015c0 0x4>;
36 cpvdd-supply = <&reg_eldo1>;
37 };
38
39...
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
new file mode 100644
index 000000000000..5e7cc05bbff1
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
@@ -0,0 +1,57 @@
1# SPDX-License-Identifier: GPL-2.0
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/sound/allwinner,sun8i-a33-codec.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Allwinner A33 Codec Device Tree Bindings
8
9maintainers:
10 - Chen-Yu Tsai <wens@csie.org>
11 - Maxime Ripard <maxime.ripard@bootlin.com>
12
13properties:
14 "#sound-dai-cells":
15 const: 0
16
17 compatible:
18 const: allwinner,sun8i-a33-codec
19
20 reg:
21 maxItems: 1
22
23 interrupts:
24 maxItems: 1
25
26 clocks:
27 items:
28 - description: Bus Clock
29 - description: Module Clock
30
31 clock-names:
32 items:
33 - const: bus
34 - const: mod
35
36required:
37 - "#sound-dai-cells"
38 - compatible
39 - reg
40 - interrupts
41 - clocks
42 - clock-names
43
44additionalProperties: false
45
46examples:
47 - |
48 audio-codec@1c22e00 {
49 #sound-dai-cells = <0>;
50 compatible = "allwinner,sun8i-a33-codec";
51 reg = <0x01c22e00 0x400>;
52 interrupts = <0 29 4>;
53 clocks = <&ccu 47>, <&ccu 92>;
54 clock-names = "bus", "mod";
55 };
56
57...
diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt
index 4330fc9dca6d..3080979350a0 100644
--- a/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt
+++ b/Documentation/devicetree/bindings/sound/amlogic,axg-fifo.txt
@@ -4,13 +4,18 @@ Required properties:
4- compatible: 'amlogic,axg-toddr' or 4- compatible: 'amlogic,axg-toddr' or
5 'amlogic,axg-toddr' or 5 'amlogic,axg-toddr' or
6 'amlogic,g12a-frddr' or 6 'amlogic,g12a-frddr' or
7 'amlogic,g12a-toddr' 7 'amlogic,g12a-toddr' or
8 'amlogic,sm1-frddr' or
9 'amlogic,sm1-toddr'
8- reg: physical base address of the controller and length of memory 10- reg: physical base address of the controller and length of memory
9 mapped region. 11 mapped region.
10- interrupts: interrupt specifier for the fifo. 12- interrupts: interrupt specifier for the fifo.
11- clocks: phandle to the fifo peripheral clock provided by the audio 13- clocks: phandle to the fifo peripheral clock provided by the audio
12 clock controller. 14 clock controller.
13- resets: phandle to memory ARB line provided by the arb reset controller. 15- resets: list of reset phandle, one for each entry reset-names.
16- reset-names: should contain the following:
17 * "arb" : memory ARB line (required)
18 * "rst" : dedicated device reset line (optional)
14- #sound-dai-cells: must be 0. 19- #sound-dai-cells: must be 0.
15 20
16Example of FRDDR A on the A113 SoC: 21Example of FRDDR A on the A113 SoC:
diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-pdm.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-pdm.txt
index 73f473a9365f..716878107a24 100644
--- a/Documentation/devicetree/bindings/sound/amlogic,axg-pdm.txt
+++ b/Documentation/devicetree/bindings/sound/amlogic,axg-pdm.txt
@@ -2,7 +2,8 @@
2 2
3Required properties: 3Required properties:
4- compatible: 'amlogic,axg-pdm' or 4- compatible: 'amlogic,axg-pdm' or
5 'amlogic,g12a-pdm' 5 'amlogic,g12a-pdm' or
6 'amlogic,sm1-pdm'
6- reg: physical base address of the controller and length of memory 7- reg: physical base address of the controller and length of memory
7 mapped region. 8 mapped region.
8- clocks: list of clock phandle, one for each entry clock-names. 9- clocks: list of clock phandle, one for each entry clock-names.
@@ -12,6 +13,9 @@ Required properties:
12 * "sysclk" : dsp system clock 13 * "sysclk" : dsp system clock
13- #sound-dai-cells: must be 0. 14- #sound-dai-cells: must be 0.
14 15
16Optional property:
17- resets: phandle to the dedicated reset line of the pdm input.
18
15Example of PDM on the A113 SoC: 19Example of PDM on the A113 SoC:
16 20
17pdm: audio-controller@ff632000 { 21pdm: audio-controller@ff632000 {
diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-spdifin.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-spdifin.txt
index 0b82504fa419..df92a4ecf288 100644
--- a/Documentation/devicetree/bindings/sound/amlogic,axg-spdifin.txt
+++ b/Documentation/devicetree/bindings/sound/amlogic,axg-spdifin.txt
@@ -2,7 +2,8 @@
2 2
3Required properties: 3Required properties:
4- compatible: 'amlogic,axg-spdifin' or 4- compatible: 'amlogic,axg-spdifin' or
5 'amlogic,g12a-spdifin' 5 'amlogic,g12a-spdifin' or
6 'amlogic,sm1-spdifin'
6- interrupts: interrupt specifier for the spdif input. 7- interrupts: interrupt specifier for the spdif input.
7- clocks: list of clock phandle, one for each entry clock-names. 8- clocks: list of clock phandle, one for each entry clock-names.
8- clock-names: should contain the following: 9- clock-names: should contain the following:
@@ -10,6 +11,9 @@ Required properties:
10 * "refclk" : spdif input reference clock 11 * "refclk" : spdif input reference clock
11- #sound-dai-cells: must be 0. 12- #sound-dai-cells: must be 0.
12 13
14Optional property:
15- resets: phandle to the dedicated reset line of the spdif input.
16
13Example on the A113 SoC: 17Example on the A113 SoC:
14 18
15spdifin: audio-controller@400 { 19spdifin: audio-controller@400 {
diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-spdifout.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-spdifout.txt
index 826152730508..28381dd1f633 100644
--- a/Documentation/devicetree/bindings/sound/amlogic,axg-spdifout.txt
+++ b/Documentation/devicetree/bindings/sound/amlogic,axg-spdifout.txt
@@ -2,13 +2,17 @@
2 2
3Required properties: 3Required properties:
4- compatible: 'amlogic,axg-spdifout' or 4- compatible: 'amlogic,axg-spdifout' or
5 'amlogic,g12a-spdifout' 5 'amlogic,g12a-spdifout' or
6 'amlogic,sm1-spdifout'
6- clocks: list of clock phandle, one for each entry clock-names. 7- clocks: list of clock phandle, one for each entry clock-names.
7- clock-names: should contain the following: 8- clock-names: should contain the following:
8 * "pclk" : peripheral clock. 9 * "pclk" : peripheral clock.
9 * "mclk" : master clock 10 * "mclk" : master clock
10- #sound-dai-cells: must be 0. 11- #sound-dai-cells: must be 0.
11 12
13Optional property:
14- resets: phandle to the dedicated reset line of the spdif output.
15
12Example on the A113 SoC: 16Example on the A113 SoC:
13 17
14spdifout: audio-controller@480 { 18spdifout: audio-controller@480 {
diff --git a/Documentation/devicetree/bindings/sound/amlogic,axg-tdm-formatters.txt b/Documentation/devicetree/bindings/sound/amlogic,axg-tdm-formatters.txt
index 8835a43edfbb..5996c0cd89c2 100644
--- a/Documentation/devicetree/bindings/sound/amlogic,axg-tdm-formatters.txt
+++ b/Documentation/devicetree/bindings/sound/amlogic,axg-tdm-formatters.txt
@@ -4,7 +4,9 @@ Required properties:
4- compatible: 'amlogic,axg-tdmin' or 4- compatible: 'amlogic,axg-tdmin' or
5 'amlogic,axg-tdmout' or 5 'amlogic,axg-tdmout' or
6 'amlogic,g12a-tdmin' or 6 'amlogic,g12a-tdmin' or
7 'amlogic,g12a-tdmout' 7 'amlogic,g12a-tdmout' or
8 'amlogic,sm1-tdmin' or
9 'amlogic,sm1-tdmout
8- reg: physical base address of the controller and length of memory 10- reg: physical base address of the controller and length of memory
9 mapped region. 11 mapped region.
10- clocks: list of clock phandle, one for each entry clock-names. 12- clocks: list of clock phandle, one for each entry clock-names.
diff --git a/Documentation/devicetree/bindings/sound/amlogic,g12a-tohdmitx.txt b/Documentation/devicetree/bindings/sound/amlogic,g12a-tohdmitx.txt
index aa6c35570d31..4e8cd7eb7cec 100644
--- a/Documentation/devicetree/bindings/sound/amlogic,g12a-tohdmitx.txt
+++ b/Documentation/devicetree/bindings/sound/amlogic,g12a-tohdmitx.txt
@@ -1,10 +1,12 @@
1* Amlogic HDMI Tx control glue 1* Amlogic HDMI Tx control glue
2 2
3Required properties: 3Required properties:
4- compatible: "amlogic,g12a-tohdmitx" 4- compatible: "amlogic,g12a-tohdmitx" or
5 "amlogic,sm1-tohdmitx"
5- reg: physical base address of the controller and length of memory 6- reg: physical base address of the controller and length of memory
6 mapped region. 7 mapped region.
7- #sound-dai-cells: should be 1. 8- #sound-dai-cells: should be 1.
9- resets: phandle to the dedicated reset line of the hdmitx glue.
8 10
9Example on the S905X2 SoC: 11Example on the S905X2 SoC:
10 12
@@ -12,6 +14,7 @@ tohdmitx: audio-controller@744 {
12 compatible = "amlogic,g12a-tohdmitx"; 14 compatible = "amlogic,g12a-tohdmitx";
13 reg = <0x0 0x744 0x0 0x4>; 15 reg = <0x0 0x744 0x0 0x4>;
14 #sound-dai-cells = <1>; 16 #sound-dai-cells = <1>;
17 resets = <&clkc_audio AUD_RESET_TOHDMITX>;
15}; 18};
16 19
17Example of an 'amlogic,axg-sound-card': 20Example of an 'amlogic,axg-sound-card':
diff --git a/Documentation/devicetree/bindings/sound/everest,es8316.txt b/Documentation/devicetree/bindings/sound/everest,es8316.txt
new file mode 100644
index 000000000000..1bf03c5f2af4
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/everest,es8316.txt
@@ -0,0 +1,23 @@
1Everest ES8316 audio CODEC
2
3This device supports both I2C and SPI.
4
5Required properties:
6
7 - compatible : should be "everest,es8316"
8 - reg : the I2C address of the device for I2C
9
10Optional properties:
11
12 - clocks : a list of phandle, should contain entries for clock-names
13 - clock-names : should include as follows:
14 "mclk" : master clock (MCLK) of the device
15
16Example:
17
18es8316: codec@11 {
19 compatible = "everest,es8316";
20 reg = <0x11>;
21 clocks = <&clks 10>;
22 clock-names = "mclk";
23};
diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt
index 5b9914367610..0e6e2166f76c 100644
--- a/Documentation/devicetree/bindings/sound/fsl,esai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt
@@ -7,8 +7,11 @@ other DSPs. It has up to six transmitters and four receivers.
7 7
8Required properties: 8Required properties:
9 9
10 - compatible : Compatible list, must contain "fsl,imx35-esai" or 10 - compatible : Compatible list, should contain one of the following
11 "fsl,vf610-esai" 11 compatibles:
12 "fsl,imx35-esai",
13 "fsl,vf610-esai",
14 "fsl,imx6ull-esai",
12 15
13 - reg : Offset and length of the register set for the device. 16 - reg : Offset and length of the register set for the device.
14 17
diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt
index 2e726b983845..0dc83cc4a236 100644
--- a/Documentation/devicetree/bindings/sound/fsl-sai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt
@@ -8,7 +8,9 @@ codec/DSP interfaces.
8Required properties: 8Required properties:
9 9
10 - compatible : Compatible list, contains "fsl,vf610-sai", 10 - compatible : Compatible list, contains "fsl,vf610-sai",
11 "fsl,imx6sx-sai" or "fsl,imx6ul-sai" 11 "fsl,imx6sx-sai", "fsl,imx6ul-sai",
12 "fsl,imx7ulp-sai", "fsl,imx8mq-sai" or
13 "fsl,imx8qm-sai".
12 14
13 - reg : Offset and length of the register set for the device. 15 - reg : Offset and length of the register set for the device.
14 16
diff --git a/Documentation/devicetree/bindings/sound/sun50i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun50i-codec-analog.txt
deleted file mode 100644
index 056a098495cc..000000000000
--- a/Documentation/devicetree/bindings/sound/sun50i-codec-analog.txt
+++ /dev/null
@@ -1,14 +0,0 @@
1* Allwinner A64 Codec Analog Controls
2
3Required properties:
4- compatible: must be one of the following compatibles:
5 - "allwinner,sun50i-a64-codec-analog"
6- reg: must contain the registers location and length
7- cpvdd-supply: Regulator supply for the headphone amplifier
8
9Example:
10 codec_analog: codec-analog@1f015c0 {
11 compatible = "allwinner,sun50i-a64-codec-analog";
12 reg = <0x01f015c0 0x4>;
13 cpvdd-supply = <&reg_eldo1>;
14 };
diff --git a/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt b/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
deleted file mode 100644
index 2ca3d138528e..000000000000
--- a/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
+++ /dev/null
@@ -1,63 +0,0 @@
1Allwinner SUN8I audio codec
2------------------------------------
3
4On Sun8i-A33 SoCs, the audio is separated in different parts:
5 - A DAI driver. It uses the "sun4i-i2s" driver which is
6 documented here:
7 Documentation/devicetree/bindings/sound/sun4i-i2s.txt
8 - An analog part of the codec which is handled as PRCM registers.
9 See Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
10 - An digital part of the codec which is documented in this current
11 binding documentation.
12 - And finally, an audio card which links all the above components.
13 The simple-audio card will be used.
14 See Documentation/devicetree/bindings/sound/simple-card.txt
15
16This bindings documentation exposes Sun8i codec (digital part).
17
18Required properties:
19- compatible: must be "allwinner,sun8i-a33-codec"
20- reg: must contain the registers location and length
21- interrupts: must contain the codec interrupt
22- clocks: a list of phandle + clock-specifer pairs, one for each entry
23 in clock-names.
24- clock-names: should contain followings:
25 - "bus": the parent APB clock for this controller
26 - "mod": the parent module clock
27
28Here is an example to add a sound card and the codec binding on sun8i SoCs that
29are similar to A33 using simple-card:
30
31 sound {
32 compatible = "simple-audio-card";
33 simple-audio-card,name = "sun8i-a33-audio";
34 simple-audio-card,format = "i2s";
35 simple-audio-card,frame-master = <&link_codec>;
36 simple-audio-card,bitclock-master = <&link_codec>;
37 simple-audio-card,mclk-fs = <512>;
38 simple-audio-card,aux-devs = <&codec_analog>;
39 simple-audio-card,routing =
40 "Left DAC", "Digital Left DAC",
41 "Right DAC", "Digital Right DAC";
42
43 simple-audio-card,cpu {
44 sound-dai = <&dai>;
45 };
46
47 link_codec: simple-audio-card,codec {
48 sound-dai = <&codec>;
49 };
50
51 soc@1c00000 {
52 [...]
53
54 audio-codec@1c22e00 {
55 #sound-dai-cells = <0>;
56 compatible = "allwinner,sun8i-a33-codec";
57 reg = <0x01c22e00 0x400>;
58 interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
59 clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
60 clock-names = "bus", "mod";
61 };
62 };
63
diff --git a/Documentation/devicetree/bindings/sound/uda1334.txt b/Documentation/devicetree/bindings/sound/uda1334.txt
new file mode 100644
index 000000000000..f64071b25e8d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/uda1334.txt
@@ -0,0 +1,17 @@
1UDA1334 audio CODEC
2
3This device uses simple GPIO pins for controlling codec settings.
4
5Required properties:
6
7 - compatible : "nxp,uda1334"
8 - nxp,mute-gpios: a GPIO spec for the MUTE pin.
9 - nxp,deemph-gpios: a GPIO spec for the De-emphasis pin
10
11Example:
12
13uda1334: audio-codec {
14 compatible = "nxp,uda1334";
15 nxp,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
16 nxp,deemph-gpios = <&gpio3 3 GPIO_ACTIVE_LOW>;
17};
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 612a17e375d0..4af4af55e854 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -253,24 +253,6 @@ struct hdac_ext_bus_ops {
253 int (*hdev_detach)(struct hdac_device *hdev); 253 int (*hdev_detach)(struct hdac_device *hdev);
254}; 254};
255 255
256/*
257 * Lowlevel I/O operators
258 */
259struct hdac_io_ops {
260 /* mapped register accesses */
261 void (*reg_writel)(u32 value, u32 __iomem *addr);
262 u32 (*reg_readl)(u32 __iomem *addr);
263 void (*reg_writew)(u16 value, u16 __iomem *addr);
264 u16 (*reg_readw)(u16 __iomem *addr);
265 void (*reg_writeb)(u8 value, u8 __iomem *addr);
266 u8 (*reg_readb)(u8 __iomem *addr);
267 /* Allocation ops */
268 int (*dma_alloc_pages)(struct hdac_bus *bus, int type, size_t size,
269 struct snd_dma_buffer *buf);
270 void (*dma_free_pages)(struct hdac_bus *bus,
271 struct snd_dma_buffer *buf);
272};
273
274#define HDA_UNSOL_QUEUE_SIZE 64 256#define HDA_UNSOL_QUEUE_SIZE 64
275#define HDA_MAX_CODECS 8 /* limit by controller side */ 257#define HDA_MAX_CODECS 8 /* limit by controller side */
276 258
@@ -304,7 +286,6 @@ struct hdac_rb {
304struct hdac_bus { 286struct hdac_bus {
305 struct device *dev; 287 struct device *dev;
306 const struct hdac_bus_ops *ops; 288 const struct hdac_bus_ops *ops;
307 const struct hdac_io_ops *io_ops;
308 const struct hdac_ext_bus_ops *ext_ops; 289 const struct hdac_ext_bus_ops *ext_ops;
309 290
310 /* h/w resources */ 291 /* h/w resources */
@@ -344,6 +325,7 @@ struct hdac_bus {
344 /* CORB/RIRB and position buffers */ 325 /* CORB/RIRB and position buffers */
345 struct snd_dma_buffer rb; 326 struct snd_dma_buffer rb;
346 struct snd_dma_buffer posbuf; 327 struct snd_dma_buffer posbuf;
328 int dma_type; /* SNDRV_DMA_TYPE_XXX for CORB/RIRB */
347 329
348 /* hdac_stream linked list */ 330 /* hdac_stream linked list */
349 struct list_head stream_list; 331 struct list_head stream_list;
@@ -384,8 +366,7 @@ struct hdac_bus {
384}; 366};
385 367
386int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, 368int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
387 const struct hdac_bus_ops *ops, 369 const struct hdac_bus_ops *ops);
388 const struct hdac_io_ops *io_ops);
389void snd_hdac_bus_exit(struct hdac_bus *bus); 370void snd_hdac_bus_exit(struct hdac_bus *bus);
390int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr, 371int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr,
391 unsigned int cmd, unsigned int *res); 372 unsigned int cmd, unsigned int *res);
@@ -429,21 +410,38 @@ int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
429int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus); 410int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus);
430void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus); 411void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus);
431 412
413#ifdef CONFIG_SND_HDA_ALIGNED_MMIO
414unsigned int snd_hdac_aligned_read(void __iomem *addr, unsigned int mask);
415void snd_hdac_aligned_write(unsigned int val, void __iomem *addr,
416 unsigned int mask);
417#define snd_hdac_reg_writeb(v, addr) snd_hdac_aligned_write(v, addr, 0xff)
418#define snd_hdac_reg_writew(v, addr) snd_hdac_aligned_write(v, addr, 0xffff)
419#define snd_hdac_reg_readb(addr) snd_hdac_aligned_read(addr, 0xff)
420#define snd_hdac_reg_readw(addr) snd_hdac_aligned_read(addr, 0xffff)
421#else /* CONFIG_SND_HDA_ALIGNED_MMIO */
422#define snd_hdac_reg_writeb(val, addr) writeb(val, addr)
423#define snd_hdac_reg_writew(val, addr) writew(val, addr)
424#define snd_hdac_reg_readb(addr) readb(addr)
425#define snd_hdac_reg_readw(addr) readw(addr)
426#endif /* CONFIG_SND_HDA_ALIGNED_MMIO */
427#define snd_hdac_reg_writel(val, addr) writel(val, addr)
428#define snd_hdac_reg_readl(addr) readl(addr)
429
432/* 430/*
433 * macros for easy use 431 * macros for easy use
434 */ 432 */
435#define _snd_hdac_chip_writeb(chip, reg, value) \ 433#define _snd_hdac_chip_writeb(chip, reg, value) \
436 ((chip)->io_ops->reg_writeb(value, (chip)->remap_addr + (reg))) 434 snd_hdac_reg_writeb(value, (chip)->remap_addr + (reg))
437#define _snd_hdac_chip_readb(chip, reg) \ 435#define _snd_hdac_chip_readb(chip, reg) \
438 ((chip)->io_ops->reg_readb((chip)->remap_addr + (reg))) 436 snd_hdac_reg_readb((chip)->remap_addr + (reg))
439#define _snd_hdac_chip_writew(chip, reg, value) \ 437#define _snd_hdac_chip_writew(chip, reg, value) \
440 ((chip)->io_ops->reg_writew(value, (chip)->remap_addr + (reg))) 438 snd_hdac_reg_writew(value, (chip)->remap_addr + (reg))
441#define _snd_hdac_chip_readw(chip, reg) \ 439#define _snd_hdac_chip_readw(chip, reg) \
442 ((chip)->io_ops->reg_readw((chip)->remap_addr + (reg))) 440 snd_hdac_reg_readw((chip)->remap_addr + (reg))
443#define _snd_hdac_chip_writel(chip, reg, value) \ 441#define _snd_hdac_chip_writel(chip, reg, value) \
444 ((chip)->io_ops->reg_writel(value, (chip)->remap_addr + (reg))) 442 snd_hdac_reg_writel(value, (chip)->remap_addr + (reg))
445#define _snd_hdac_chip_readl(chip, reg) \ 443#define _snd_hdac_chip_readl(chip, reg) \
446 ((chip)->io_ops->reg_readl((chip)->remap_addr + (reg))) 444 snd_hdac_reg_readl((chip)->remap_addr + (reg))
447 445
448/* read/write a register, pass without AZX_REG_ prefix */ 446/* read/write a register, pass without AZX_REG_ prefix */
449#define snd_hdac_chip_writel(chip, reg, value) \ 447#define snd_hdac_chip_writel(chip, reg, value) \
@@ -548,24 +546,19 @@ int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus,
548/* 546/*
549 * macros for easy use 547 * macros for easy use
550 */ 548 */
551#define _snd_hdac_stream_write(type, dev, reg, value) \
552 ((dev)->bus->io_ops->reg_write ## type(value, (dev)->sd_addr + (reg)))
553#define _snd_hdac_stream_read(type, dev, reg) \
554 ((dev)->bus->io_ops->reg_read ## type((dev)->sd_addr + (reg)))
555
556/* read/write a register, pass without AZX_REG_ prefix */ 549/* read/write a register, pass without AZX_REG_ prefix */
557#define snd_hdac_stream_writel(dev, reg, value) \ 550#define snd_hdac_stream_writel(dev, reg, value) \
558 _snd_hdac_stream_write(l, dev, AZX_REG_ ## reg, value) 551 snd_hdac_reg_writel(value, (dev)->sd_addr + AZX_REG_ ## reg)
559#define snd_hdac_stream_writew(dev, reg, value) \ 552#define snd_hdac_stream_writew(dev, reg, value) \
560 _snd_hdac_stream_write(w, dev, AZX_REG_ ## reg, value) 553 snd_hdac_reg_writew(value, (dev)->sd_addr + AZX_REG_ ## reg)
561#define snd_hdac_stream_writeb(dev, reg, value) \ 554#define snd_hdac_stream_writeb(dev, reg, value) \
562 _snd_hdac_stream_write(b, dev, AZX_REG_ ## reg, value) 555 snd_hdac_reg_writeb(value, (dev)->sd_addr + AZX_REG_ ## reg)
563#define snd_hdac_stream_readl(dev, reg) \ 556#define snd_hdac_stream_readl(dev, reg) \
564 _snd_hdac_stream_read(l, dev, AZX_REG_ ## reg) 557 snd_hdac_reg_readl((dev)->sd_addr + AZX_REG_ ## reg)
565#define snd_hdac_stream_readw(dev, reg) \ 558#define snd_hdac_stream_readw(dev, reg) \
566 _snd_hdac_stream_read(w, dev, AZX_REG_ ## reg) 559 snd_hdac_reg_readw((dev)->sd_addr + AZX_REG_ ## reg)
567#define snd_hdac_stream_readb(dev, reg) \ 560#define snd_hdac_stream_readb(dev, reg) \
568 _snd_hdac_stream_read(b, dev, AZX_REG_ ## reg) 561 snd_hdac_reg_readb((dev)->sd_addr + AZX_REG_ ## reg)
569 562
570/* update a register, pass without AZX_REG_ prefix */ 563/* update a register, pass without AZX_REG_ prefix */
571#define snd_hdac_stream_updatel(dev, reg, mask, val) \ 564#define snd_hdac_stream_updatel(dev, reg, mask, val) \
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
index f34aced69ca8..ef88b20c7b0a 100644
--- a/include/sound/hdaudio_ext.h
+++ b/include/sound/hdaudio_ext.h
@@ -6,7 +6,6 @@
6 6
7int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, 7int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
8 const struct hdac_bus_ops *ops, 8 const struct hdac_bus_ops *ops,
9 const struct hdac_io_ops *io_ops,
10 const struct hdac_ext_bus_ops *ext_ops); 9 const struct hdac_ext_bus_ops *ext_ops);
11 10
12void snd_hdac_ext_bus_exit(struct hdac_bus *bus); 11void snd_hdac_ext_bus_exit(struct hdac_bus *bus);
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
index 7fea496f1f34..83b17682e01c 100644
--- a/include/sound/hdmi-codec.h
+++ b/include/sound/hdmi-codec.h
@@ -47,6 +47,9 @@ struct hdmi_codec_params {
47 int channels; 47 int channels;
48}; 48};
49 49
50typedef void (*hdmi_codec_plugged_cb)(struct device *dev,
51 bool plugged);
52
50struct hdmi_codec_pdata; 53struct hdmi_codec_pdata;
51struct hdmi_codec_ops { 54struct hdmi_codec_ops {
52 /* 55 /*
@@ -88,6 +91,14 @@ struct hdmi_codec_ops {
88 */ 91 */
89 int (*get_dai_id)(struct snd_soc_component *comment, 92 int (*get_dai_id)(struct snd_soc_component *comment,
90 struct device_node *endpoint); 93 struct device_node *endpoint);
94
95 /*
96 * Hook callback function to handle connector plug event.
97 * Optional
98 */
99 int (*hook_plugged_cb)(struct device *dev, void *data,
100 hdmi_codec_plugged_cb fn,
101 struct device *codec_dev);
91}; 102};
92 103
93/* HDMI codec initalization data */ 104/* HDMI codec initalization data */
@@ -99,6 +110,12 @@ struct hdmi_codec_pdata {
99 void *data; 110 void *data;
100}; 111};
101 112
113struct snd_soc_component;
114struct snd_soc_jack;
115
116int hdmi_codec_set_jack_detect(struct snd_soc_component *component,
117 struct snd_soc_jack *jack);
118
102#define HDMI_CODEC_DRV_NAME "hdmi-audio-codec" 119#define HDMI_CODEC_DRV_NAME "hdmi-audio-codec"
103 120
104#endif /* __HDMI_CODEC_H__ */ 121#endif /* __HDMI_CODEC_H__ */
diff --git a/sound/soc/intel/skylake/skl-nhlt.h b/include/sound/intel-nhlt.h
index f85fbf9c7ce4..f657fd8fc0ad 100644
--- a/sound/soc/intel/skylake/skl-nhlt.h
+++ b/include/sound/intel-nhlt.h
@@ -1,18 +1,17 @@
1/* SPDX-License-Identifier: GPL-2.0-only */ 1/* SPDX-License-Identifier: GPL-2.0-only */
2/* 2/*
3 * skl-nhlt.h - Intel HDA Platform NHLT header 3 * intel-nhlt.h - Intel HDA Platform NHLT header
4 * 4 *
5 * Copyright (C) 2015 Intel Corp 5 * Copyright (c) 2015-2019 Intel Corporation
6 * Author: Sanjiv Kumar <sanjiv.kumar@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 */ 6 */
11#ifndef __SKL_NHLT_H__ 7
12#define __SKL_NHLT_H__ 8#ifndef __INTEL_NHLT_H__
9#define __INTEL_NHLT_H__
13 10
14#include <linux/acpi.h> 11#include <linux/acpi.h>
15 12
13#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT)
14
16struct wav_fmt { 15struct wav_fmt {
17 u16 fmt_tag; 16 u16 fmt_tag;
18 u16 channels; 17 u16 channels;
@@ -97,16 +96,22 @@ struct nhlt_resource_desc {
97#define MIC_ARRAY_2CH 2 96#define MIC_ARRAY_2CH 2
98#define MIC_ARRAY_4CH 4 97#define MIC_ARRAY_4CH 4
99 98
100struct nhlt_tdm_config { 99struct nhlt_device_specific_config {
101 u8 virtual_slot; 100 u8 virtual_slot;
102 u8 config_type; 101 u8 config_type;
103} __packed; 102} __packed;
104 103
105struct nhlt_dmic_array_config { 104struct nhlt_dmic_array_config {
106 struct nhlt_tdm_config tdm_config; 105 struct nhlt_device_specific_config device_config;
107 u8 array_type; 106 u8 array_type;
108} __packed; 107} __packed;
109 108
109struct nhlt_vendor_dmic_array_config {
110 struct nhlt_dmic_array_config dmic_config;
111 u8 nb_mics;
112 /* TODO add vendor mic config */
113} __packed;
114
110enum { 115enum {
111 NHLT_MIC_ARRAY_2CH_SMALL = 0xa, 116 NHLT_MIC_ARRAY_2CH_SMALL = 0xa,
112 NHLT_MIC_ARRAY_2CH_BIG = 0xb, 117 NHLT_MIC_ARRAY_2CH_BIG = 0xb,
@@ -116,4 +121,30 @@ enum {
116 NHLT_MIC_ARRAY_VENDOR_DEFINED = 0xf, 121 NHLT_MIC_ARRAY_VENDOR_DEFINED = 0xf,
117}; 122};
118 123
124struct nhlt_acpi_table *intel_nhlt_init(struct device *dev);
125
126void intel_nhlt_free(struct nhlt_acpi_table *addr);
127
128int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt);
129
130#else
131
132struct nhlt_acpi_table;
133
134static inline struct nhlt_acpi_table *intel_nhlt_init(struct device *dev)
135{
136 return NULL;
137}
138
139static inline void intel_nhlt_free(struct nhlt_acpi_table *addr)
140{
141}
142
143static inline int intel_nhlt_get_dmic_geo(struct device *dev,
144 struct nhlt_acpi_table *nhlt)
145{
146 return 0;
147}
148#endif
149
119#endif 150#endif
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 1e9bb1c91770..bbe6eb1ff5d2 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -117,6 +117,8 @@ struct snd_pcm_ops {
117#define SNDRV_PCM_RATE_96000 (1<<10) /* 96000Hz */ 117#define SNDRV_PCM_RATE_96000 (1<<10) /* 96000Hz */
118#define SNDRV_PCM_RATE_176400 (1<<11) /* 176400Hz */ 118#define SNDRV_PCM_RATE_176400 (1<<11) /* 176400Hz */
119#define SNDRV_PCM_RATE_192000 (1<<12) /* 192000Hz */ 119#define SNDRV_PCM_RATE_192000 (1<<12) /* 192000Hz */
120#define SNDRV_PCM_RATE_352800 (1<<13) /* 352800Hz */
121#define SNDRV_PCM_RATE_384000 (1<<14) /* 384000Hz */
120 122
121#define SNDRV_PCM_RATE_CONTINUOUS (1<<30) /* continuous range */ 123#define SNDRV_PCM_RATE_CONTINUOUS (1<<30) /* continuous range */
122#define SNDRV_PCM_RATE_KNOT (1<<31) /* supports more non-continuos rates */ 124#define SNDRV_PCM_RATE_KNOT (1<<31) /* supports more non-continuos rates */
@@ -129,6 +131,9 @@ struct snd_pcm_ops {
129 SNDRV_PCM_RATE_88200|SNDRV_PCM_RATE_96000) 131 SNDRV_PCM_RATE_88200|SNDRV_PCM_RATE_96000)
130#define SNDRV_PCM_RATE_8000_192000 (SNDRV_PCM_RATE_8000_96000|SNDRV_PCM_RATE_176400|\ 132#define SNDRV_PCM_RATE_8000_192000 (SNDRV_PCM_RATE_8000_96000|SNDRV_PCM_RATE_176400|\
131 SNDRV_PCM_RATE_192000) 133 SNDRV_PCM_RATE_192000)
134#define SNDRV_PCM_RATE_8000_384000 (SNDRV_PCM_RATE_8000_192000|\
135 SNDRV_PCM_RATE_352800|\
136 SNDRV_PCM_RATE_384000)
132#define _SNDRV_PCM_FMTBIT(fmt) (1ULL << (__force int)SNDRV_PCM_FORMAT_##fmt) 137#define _SNDRV_PCM_FMTBIT(fmt) (1ULL << (__force int)SNDRV_PCM_FORMAT_##fmt)
133#define SNDRV_PCM_FMTBIT_S8 _SNDRV_PCM_FMTBIT(S8) 138#define SNDRV_PCM_FMTBIT_S8 _SNDRV_PCM_FMTBIT(S8)
134#define SNDRV_PCM_FMTBIT_U8 _SNDRV_PCM_FMTBIT(U8) 139#define SNDRV_PCM_FMTBIT_U8 _SNDRV_PCM_FMTBIT(U8)
diff --git a/include/sound/soc-acpi-intel-match.h b/include/sound/soc-acpi-intel-match.h
index bb5e1e4ce8bf..6c9929abd90b 100644
--- a/include/sound/soc-acpi-intel-match.h
+++ b/include/sound/soc-acpi-intel-match.h
@@ -25,6 +25,8 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_bxt_machines[];
25extern struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[]; 25extern struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[];
26extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[]; 26extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[];
27extern struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[]; 27extern struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[];
28extern struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[];
29extern struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[];
28 30
29/* 31/*
30 * generic table used for HDA codec-based platforms, possibly with 32 * generic table used for HDA codec-based platforms, possibly with
diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h
new file mode 100644
index 000000000000..5d80b2eef525
--- /dev/null
+++ b/include/sound/soc-component.h
@@ -0,0 +1,387 @@
1/* SPDX-License-Identifier: GPL-2.0
2 *
3 * soc-component.h
4 *
5 * Copyright (c) 2019 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef __SOC_COMPONENT_H
12#define __SOC_COMPONENT_H
13
14#include <sound/soc.h>
15
16/*
17 * Component probe and remove ordering levels for components with runtime
18 * dependencies.
19 */
20#define SND_SOC_COMP_ORDER_FIRST -2
21#define SND_SOC_COMP_ORDER_EARLY -1
22#define SND_SOC_COMP_ORDER_NORMAL 0
23#define SND_SOC_COMP_ORDER_LATE 1
24#define SND_SOC_COMP_ORDER_LAST 2
25
26#define for_each_comp_order(order) \
27 for (order = SND_SOC_COMP_ORDER_FIRST; \
28 order <= SND_SOC_COMP_ORDER_LAST; \
29 order++)
30
31/* component interface */
32struct snd_soc_component_driver {
33 const char *name;
34
35 /* Default control and setup, added after probe() is run */
36 const struct snd_kcontrol_new *controls;
37 unsigned int num_controls;
38 const struct snd_soc_dapm_widget *dapm_widgets;
39 unsigned int num_dapm_widgets;
40 const struct snd_soc_dapm_route *dapm_routes;
41 unsigned int num_dapm_routes;
42
43 int (*probe)(struct snd_soc_component *component);
44 void (*remove)(struct snd_soc_component *component);
45 int (*suspend)(struct snd_soc_component *component);
46 int (*resume)(struct snd_soc_component *component);
47
48 unsigned int (*read)(struct snd_soc_component *component,
49 unsigned int reg);
50 int (*write)(struct snd_soc_component *component,
51 unsigned int reg, unsigned int val);
52
53 /* pcm creation and destruction */
54 int (*pcm_new)(struct snd_soc_pcm_runtime *rtd);
55 void (*pcm_free)(struct snd_pcm *pcm);
56
57 /* component wide operations */
58 int (*set_sysclk)(struct snd_soc_component *component,
59 int clk_id, int source, unsigned int freq, int dir);
60 int (*set_pll)(struct snd_soc_component *component, int pll_id,
61 int source, unsigned int freq_in, unsigned int freq_out);
62 int (*set_jack)(struct snd_soc_component *component,
63 struct snd_soc_jack *jack, void *data);
64
65 /* DT */
66 int (*of_xlate_dai_name)(struct snd_soc_component *component,
67 struct of_phandle_args *args,
68 const char **dai_name);
69 int (*of_xlate_dai_id)(struct snd_soc_component *comment,
70 struct device_node *endpoint);
71 void (*seq_notifier)(struct snd_soc_component *component,
72 enum snd_soc_dapm_type type, int subseq);
73 int (*stream_event)(struct snd_soc_component *component, int event);
74 int (*set_bias_level)(struct snd_soc_component *component,
75 enum snd_soc_bias_level level);
76
77 const struct snd_pcm_ops *ops;
78 const struct snd_compr_ops *compr_ops;
79
80 /* probe ordering - for components with runtime dependencies */
81 int probe_order;
82 int remove_order;
83
84 /*
85 * signal if the module handling the component should not be removed
86 * if a pcm is open. Setting this would prevent the module
87 * refcount being incremented in probe() but allow it be incremented
88 * when a pcm is opened and decremented when it is closed.
89 */
90 unsigned int module_get_upon_open:1;
91
92 /* bits */
93 unsigned int idle_bias_on:1;
94 unsigned int suspend_bias_off:1;
95 unsigned int use_pmdown_time:1; /* care pmdown_time at stop */
96 unsigned int endianness:1;
97 unsigned int non_legacy_dai_naming:1;
98
99 /* this component uses topology and ignore machine driver FEs */
100 const char *ignore_machine;
101 const char *topology_name_prefix;
102 int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
103 struct snd_pcm_hw_params *params);
104 bool use_dai_pcm_id; /* use DAI link PCM ID as PCM device number */
105 int be_pcm_base; /* base device ID for all BE PCMs */
106};
107
108struct snd_soc_component {
109 const char *name;
110 int id;
111 const char *name_prefix;
112 struct device *dev;
113 struct snd_soc_card *card;
114
115 unsigned int active;
116
117 unsigned int suspended:1; /* is in suspend PM state */
118
119 struct list_head list;
120 struct list_head card_aux_list; /* for auxiliary bound components */
121 struct list_head card_list;
122
123 const struct snd_soc_component_driver *driver;
124
125 struct list_head dai_list;
126 int num_dai;
127
128 struct regmap *regmap;
129 int val_bytes;
130
131 struct mutex io_mutex;
132
133 /* attached dynamic objects */
134 struct list_head dobj_list;
135
136 /*
137 * DO NOT use any of the fields below in drivers, they are temporary and
138 * are going to be removed again soon. If you use them in driver code
139 * the driver will be marked as BROKEN when these fields are removed.
140 */
141
142 /* Don't use these, use snd_soc_component_get_dapm() */
143 struct snd_soc_dapm_context dapm;
144
145 /* machine specific init */
146 int (*init)(struct snd_soc_component *component);
147
148#ifdef CONFIG_DEBUG_FS
149 struct dentry *debugfs_root;
150 const char *debugfs_prefix;
151#endif
152};
153
154#define for_each_component_dais(component, dai)\
155 list_for_each_entry(dai, &(component)->dai_list, list)
156#define for_each_component_dais_safe(component, dai, _dai)\
157 list_for_each_entry_safe(dai, _dai, &(component)->dai_list, list)
158
159/**
160 * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is
161 * embedded in
162 * @dapm: The DAPM context to cast to the component
163 *
164 * This function must only be used on DAPM contexts that are known to be part of
165 * a component (e.g. in a component driver). Otherwise the behavior is
166 * undefined.
167 */
168static inline struct snd_soc_component *snd_soc_dapm_to_component(
169 struct snd_soc_dapm_context *dapm)
170{
171 return container_of(dapm, struct snd_soc_component, dapm);
172}
173
174/**
175 * snd_soc_component_get_dapm() - Returns the DAPM context associated with a
176 * component
177 * @component: The component for which to get the DAPM context
178 */
179static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
180 struct snd_soc_component *component)
181{
182 return &component->dapm;
183}
184
185/**
186 * snd_soc_component_init_bias_level() - Initialize COMPONENT DAPM bias level
187 * @component: The COMPONENT for which to initialize the DAPM bias level
188 * @level: The DAPM level to initialize to
189 *
190 * Initializes the COMPONENT DAPM bias level. See snd_soc_dapm_init_bias_level()
191 */
192static inline void
193snd_soc_component_init_bias_level(struct snd_soc_component *component,
194 enum snd_soc_bias_level level)
195{
196 snd_soc_dapm_init_bias_level(
197 snd_soc_component_get_dapm(component), level);
198}
199
200/**
201 * snd_soc_component_get_bias_level() - Get current COMPONENT DAPM bias level
202 * @component: The COMPONENT for which to get the DAPM bias level
203 *
204 * Returns: The current DAPM bias level of the COMPONENT.
205 */
206static inline enum snd_soc_bias_level
207snd_soc_component_get_bias_level(struct snd_soc_component *component)
208{
209 return snd_soc_dapm_get_bias_level(
210 snd_soc_component_get_dapm(component));
211}
212
213/**
214 * snd_soc_component_force_bias_level() - Set the COMPONENT DAPM bias level
215 * @component: The COMPONENT for which to set the level
216 * @level: The level to set to
217 *
218 * Forces the COMPONENT bias level to a specific state. See
219 * snd_soc_dapm_force_bias_level().
220 */
221static inline int
222snd_soc_component_force_bias_level(struct snd_soc_component *component,
223 enum snd_soc_bias_level level)
224{
225 return snd_soc_dapm_force_bias_level(
226 snd_soc_component_get_dapm(component),
227 level);
228}
229
230/**
231 * snd_soc_dapm_kcontrol_component() - Returns the component associated to a
232 * kcontrol
233 * @kcontrol: The kcontrol
234 *
235 * This function must only be used on DAPM contexts that are known to be part of
236 * a COMPONENT (e.g. in a COMPONENT driver). Otherwise the behavior is undefined
237 */
238static inline struct snd_soc_component *snd_soc_dapm_kcontrol_component(
239 struct snd_kcontrol *kcontrol)
240{
241 return snd_soc_dapm_to_component(snd_soc_dapm_kcontrol_dapm(kcontrol));
242}
243
244/**
245 * snd_soc_component_cache_sync() - Sync the register cache with the hardware
246 * @component: COMPONENT to sync
247 *
248 * Note: This function will call regcache_sync()
249 */
250static inline int snd_soc_component_cache_sync(
251 struct snd_soc_component *component)
252{
253 return regcache_sync(component->regmap);
254}
255
256/* component IO */
257int snd_soc_component_read(struct snd_soc_component *component,
258 unsigned int reg, unsigned int *val);
259unsigned int snd_soc_component_read32(struct snd_soc_component *component,
260 unsigned int reg);
261int snd_soc_component_write(struct snd_soc_component *component,
262 unsigned int reg, unsigned int val);
263int snd_soc_component_update_bits(struct snd_soc_component *component,
264 unsigned int reg, unsigned int mask,
265 unsigned int val);
266int snd_soc_component_update_bits_async(struct snd_soc_component *component,
267 unsigned int reg, unsigned int mask,
268 unsigned int val);
269void snd_soc_component_async_complete(struct snd_soc_component *component);
270int snd_soc_component_test_bits(struct snd_soc_component *component,
271 unsigned int reg, unsigned int mask,
272 unsigned int value);
273
274/* component wide operations */
275int snd_soc_component_set_sysclk(struct snd_soc_component *component,
276 int clk_id, int source,
277 unsigned int freq, int dir);
278int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
279 int source, unsigned int freq_in,
280 unsigned int freq_out);
281int snd_soc_component_set_jack(struct snd_soc_component *component,
282 struct snd_soc_jack *jack, void *data);
283
284void snd_soc_component_seq_notifier(struct snd_soc_component *component,
285 enum snd_soc_dapm_type type, int subseq);
286int snd_soc_component_stream_event(struct snd_soc_component *component,
287 int event);
288int snd_soc_component_set_bias_level(struct snd_soc_component *component,
289 enum snd_soc_bias_level level);
290
291#ifdef CONFIG_REGMAP
292void snd_soc_component_init_regmap(struct snd_soc_component *component,
293 struct regmap *regmap);
294void snd_soc_component_exit_regmap(struct snd_soc_component *component);
295#endif
296
297#define snd_soc_component_module_get_when_probe(component)\
298 snd_soc_component_module_get(component, 0)
299#define snd_soc_component_module_get_when_open(component) \
300 snd_soc_component_module_get(component, 1)
301int snd_soc_component_module_get(struct snd_soc_component *component,
302 int upon_open);
303#define snd_soc_component_module_put_when_remove(component) \
304 snd_soc_component_module_put(component, 0)
305#define snd_soc_component_module_put_when_close(component) \
306 snd_soc_component_module_put(component, 1)
307void snd_soc_component_module_put(struct snd_soc_component *component,
308 int upon_open);
309
310static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c,
311 void *data)
312{
313 dev_set_drvdata(c->dev, data);
314}
315
316static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
317{
318 return dev_get_drvdata(c->dev);
319}
320
321static inline bool snd_soc_component_is_active(
322 struct snd_soc_component *component)
323{
324 return component->active != 0;
325}
326
327/* component pin */
328int snd_soc_component_enable_pin(struct snd_soc_component *component,
329 const char *pin);
330int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
331 const char *pin);
332int snd_soc_component_disable_pin(struct snd_soc_component *component,
333 const char *pin);
334int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
335 const char *pin);
336int snd_soc_component_nc_pin(struct snd_soc_component *component,
337 const char *pin);
338int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
339 const char *pin);
340int snd_soc_component_get_pin_status(struct snd_soc_component *component,
341 const char *pin);
342int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
343 const char *pin);
344int snd_soc_component_force_enable_pin_unlocked(
345 struct snd_soc_component *component,
346 const char *pin);
347
348/* component driver ops */
349int snd_soc_component_open(struct snd_soc_component *component,
350 struct snd_pcm_substream *substream);
351int snd_soc_component_close(struct snd_soc_component *component,
352 struct snd_pcm_substream *substream);
353int snd_soc_component_prepare(struct snd_soc_component *component,
354 struct snd_pcm_substream *substream);
355int snd_soc_component_hw_params(struct snd_soc_component *component,
356 struct snd_pcm_substream *substream,
357 struct snd_pcm_hw_params *params);
358int snd_soc_component_hw_free(struct snd_soc_component *component,
359 struct snd_pcm_substream *substream);
360int snd_soc_component_trigger(struct snd_soc_component *component,
361 struct snd_pcm_substream *substream,
362 int cmd);
363void snd_soc_component_suspend(struct snd_soc_component *component);
364void snd_soc_component_resume(struct snd_soc_component *component);
365int snd_soc_component_is_suspended(struct snd_soc_component *component);
366int snd_soc_component_probe(struct snd_soc_component *component);
367void snd_soc_component_remove(struct snd_soc_component *component);
368int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
369 struct device_node *ep);
370int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
371 struct of_phandle_args *args,
372 const char **dai_name);
373
374int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream);
375int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
376 unsigned int cmd, void *arg);
377int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
378 int channel, unsigned long pos,
379 void __user *buf, unsigned long bytes);
380struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
381 unsigned long offset);
382int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
383 struct vm_area_struct *vma);
384int snd_soc_pcm_component_new(struct snd_pcm *pcm);
385void snd_soc_pcm_component_free(struct snd_pcm *pcm);
386
387#endif /* __SOC_COMPONENT_H */
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index f5d70041108f..939c73db6a03 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -145,6 +145,31 @@ int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
145 145
146int snd_soc_dai_is_dummy(struct snd_soc_dai *dai); 146int snd_soc_dai_is_dummy(struct snd_soc_dai *dai);
147 147
148int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
149 struct snd_pcm_substream *substream,
150 struct snd_pcm_hw_params *params);
151void snd_soc_dai_hw_free(struct snd_soc_dai *dai,
152 struct snd_pcm_substream *substream);
153int snd_soc_dai_startup(struct snd_soc_dai *dai,
154 struct snd_pcm_substream *substream);
155void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
156 struct snd_pcm_substream *substream);
157int snd_soc_dai_prepare(struct snd_soc_dai *dai,
158 struct snd_pcm_substream *substream);
159int snd_soc_dai_trigger(struct snd_soc_dai *dai,
160 struct snd_pcm_substream *substream, int cmd);
161int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
162 struct snd_pcm_substream *substream, int cmd);
163snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
164 struct snd_pcm_substream *substream);
165void snd_soc_dai_suspend(struct snd_soc_dai *dai);
166void snd_soc_dai_resume(struct snd_soc_dai *dai);
167int snd_soc_dai_probe(struct snd_soc_dai *dai);
168int snd_soc_dai_remove(struct snd_soc_dai *dai);
169int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
170 struct snd_soc_pcm_runtime *rtd, int num);
171bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream);
172
148struct snd_soc_dai_ops { 173struct snd_soc_dai_ops {
149 /* 174 /*
150 * DAI clocking configuration, all optional. 175 * DAI clocking configuration, all optional.
@@ -268,8 +293,6 @@ struct snd_soc_dai_driver {
268 /* Optional Callback used at pcm creation*/ 293 /* Optional Callback used at pcm creation*/
269 int (*pcm_new)(struct snd_soc_pcm_runtime *rtd, 294 int (*pcm_new)(struct snd_soc_pcm_runtime *rtd,
270 struct snd_soc_dai *dai); 295 struct snd_soc_dai *dai);
271 /* DAI is also used for the control bus */
272 bool bus_control;
273 296
274 /* ops */ 297 /* ops */
275 const struct snd_soc_dai_ops *ops; 298 const struct snd_soc_dai_ops *ops;
@@ -281,6 +304,7 @@ struct snd_soc_dai_driver {
281 unsigned int symmetric_rates:1; 304 unsigned int symmetric_rates:1;
282 unsigned int symmetric_channels:1; 305 unsigned int symmetric_channels:1;
283 unsigned int symmetric_samplebits:1; 306 unsigned int symmetric_samplebits:1;
307 unsigned int bus_control:1; /* DAI is also used for the control bus */
284 308
285 /* probe ordering - for components with runtime dependencies */ 309 /* probe ordering - for components with runtime dependencies */
286 int probe_order; 310 int probe_order;
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 8a90816a6eb5..6e8a31225383 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -353,6 +353,8 @@ struct device;
353#define SND_SOC_DAPM_WILL_PMD 0x80 /* called at start of sequence */ 353#define SND_SOC_DAPM_WILL_PMD 0x80 /* called at start of sequence */
354#define SND_SOC_DAPM_PRE_POST_PMD \ 354#define SND_SOC_DAPM_PRE_POST_PMD \
355 (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD) 355 (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD)
356#define SND_SOC_DAPM_PRE_POST_PMU \
357 (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU)
356 358
357/* convenience event type detection */ 359/* convenience event type detection */
358#define SND_SOC_DAPM_EVENT_ON(e) \ 360#define SND_SOC_DAPM_EVENT_ON(e) \
@@ -417,6 +419,9 @@ int snd_soc_dapm_update_dai(struct snd_pcm_substream *substream,
417/* dapm path setup */ 419/* dapm path setup */
418int snd_soc_dapm_new_widgets(struct snd_soc_card *card); 420int snd_soc_dapm_new_widgets(struct snd_soc_card *card);
419void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm); 421void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
422void snd_soc_dapm_init(struct snd_soc_dapm_context *dapm,
423 struct snd_soc_card *card,
424 struct snd_soc_component *component);
420int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, 425int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
421 const struct snd_soc_dapm_route *route, int num); 426 const struct snd_soc_dapm_route *route, int num);
422int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm, 427int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
@@ -662,8 +667,6 @@ struct snd_soc_dapm_context {
662 unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ 667 unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
663 /* Go to BIAS_OFF in suspend if the DAPM context is idle */ 668 /* Go to BIAS_OFF in suspend if the DAPM context is idle */
664 unsigned int suspend_bias_off:1; 669 unsigned int suspend_bias_off:1;
665 void (*seq_notifier)(struct snd_soc_dapm_context *,
666 enum snd_soc_dapm_type, int);
667 670
668 struct device *dev; /* from parent - for debug */ 671 struct device *dev; /* from parent - for debug */
669 struct snd_soc_component *component; /* parent component */ 672 struct snd_soc_component *component; /* parent component */
@@ -673,10 +676,6 @@ struct snd_soc_dapm_context {
673 enum snd_soc_bias_level target_bias_level; 676 enum snd_soc_bias_level target_bias_level;
674 struct list_head list; 677 struct list_head list;
675 678
676 int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
677 int (*set_bias_level)(struct snd_soc_dapm_context *dapm,
678 enum snd_soc_bias_level level);
679
680 struct snd_soc_dapm_wcache path_sink_cache; 679 struct snd_soc_dapm_wcache path_sink_cache;
681 struct snd_soc_dapm_wcache path_source_cache; 680 struct snd_soc_dapm_wcache path_source_cache;
682 681
diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h
index 4be3a2b7c106..e55aeb00ce2d 100644
--- a/include/sound/soc-dpcm.h
+++ b/include/sound/soc-dpcm.h
@@ -142,9 +142,16 @@ void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be, int stream,
142 142
143/* internal use only */ 143/* internal use only */
144int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute); 144int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute);
145void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd);
146int soc_dpcm_runtime_update(struct snd_soc_card *); 145int soc_dpcm_runtime_update(struct snd_soc_card *);
147 146
147#ifdef CONFIG_DEBUG_FS
148void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd);
149#else
150static inline void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
151{
152}
153#endif
154
148int dpcm_path_get(struct snd_soc_pcm_runtime *fe, 155int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
149 int stream, struct snd_soc_dapm_widget_list **list_); 156 int stream, struct snd_soc_dapm_widget_list **list_);
150int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, 157int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 4e8071269639..f264c6509f00 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -363,21 +363,6 @@
363 const struct soc_enum name = SOC_ENUM_SINGLE_VIRT(ARRAY_SIZE(xtexts), xtexts) 363 const struct soc_enum name = SOC_ENUM_SINGLE_VIRT(ARRAY_SIZE(xtexts), xtexts)
364 364
365/* 365/*
366 * Component probe and remove ordering levels for components with runtime
367 * dependencies.
368 */
369#define SND_SOC_COMP_ORDER_FIRST -2
370#define SND_SOC_COMP_ORDER_EARLY -1
371#define SND_SOC_COMP_ORDER_NORMAL 0
372#define SND_SOC_COMP_ORDER_LATE 1
373#define SND_SOC_COMP_ORDER_LAST 2
374
375#define for_each_comp_order(order) \
376 for (order = SND_SOC_COMP_ORDER_FIRST; \
377 order <= SND_SOC_COMP_ORDER_LAST; \
378 order++)
379
380/*
381 * Bias levels 366 * Bias levels
382 * 367 *
383 * @ON: Bias is fully on for audio playback and capture operations. 368 * @ON: Bias is fully on for audio playback and capture operations.
@@ -505,10 +490,6 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *parms);
505int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, 490int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
506 const struct snd_pcm_hardware *hw); 491 const struct snd_pcm_hardware *hw);
507 492
508int soc_dai_hw_params(struct snd_pcm_substream *substream,
509 struct snd_pcm_hw_params *params,
510 struct snd_soc_dai *dai);
511
512/* Jack reporting */ 493/* Jack reporting */
513int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type, 494int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
514 struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins, 495 struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins,
@@ -751,132 +732,6 @@ struct snd_soc_compr_ops {
751 int (*trigger)(struct snd_compr_stream *); 732 int (*trigger)(struct snd_compr_stream *);
752}; 733};
753 734
754/* component interface */
755struct snd_soc_component_driver {
756 const char *name;
757
758 /* Default control and setup, added after probe() is run */
759 const struct snd_kcontrol_new *controls;
760 unsigned int num_controls;
761 const struct snd_soc_dapm_widget *dapm_widgets;
762 unsigned int num_dapm_widgets;
763 const struct snd_soc_dapm_route *dapm_routes;
764 unsigned int num_dapm_routes;
765
766 int (*probe)(struct snd_soc_component *);
767 void (*remove)(struct snd_soc_component *);
768 int (*suspend)(struct snd_soc_component *);
769 int (*resume)(struct snd_soc_component *);
770
771 unsigned int (*read)(struct snd_soc_component *, unsigned int);
772 int (*write)(struct snd_soc_component *, unsigned int, unsigned int);
773
774 /* pcm creation and destruction */
775 int (*pcm_new)(struct snd_soc_pcm_runtime *);
776 void (*pcm_free)(struct snd_pcm *);
777
778 /* component wide operations */
779 int (*set_sysclk)(struct snd_soc_component *component,
780 int clk_id, int source, unsigned int freq, int dir);
781 int (*set_pll)(struct snd_soc_component *component, int pll_id,
782 int source, unsigned int freq_in, unsigned int freq_out);
783 int (*set_jack)(struct snd_soc_component *component,
784 struct snd_soc_jack *jack, void *data);
785
786 /* DT */
787 int (*of_xlate_dai_name)(struct snd_soc_component *component,
788 struct of_phandle_args *args,
789 const char **dai_name);
790 int (*of_xlate_dai_id)(struct snd_soc_component *comment,
791 struct device_node *endpoint);
792 void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type,
793 int subseq);
794 int (*stream_event)(struct snd_soc_component *, int event);
795 int (*set_bias_level)(struct snd_soc_component *component,
796 enum snd_soc_bias_level level);
797
798 const struct snd_pcm_ops *ops;
799 const struct snd_compr_ops *compr_ops;
800
801 /* probe ordering - for components with runtime dependencies */
802 int probe_order;
803 int remove_order;
804
805 /*
806 * signal if the module handling the component should not be removed
807 * if a pcm is open. Setting this would prevent the module
808 * refcount being incremented in probe() but allow it be incremented
809 * when a pcm is opened and decremented when it is closed.
810 */
811 unsigned int module_get_upon_open:1;
812
813 /* bits */
814 unsigned int idle_bias_on:1;
815 unsigned int suspend_bias_off:1;
816 unsigned int use_pmdown_time:1; /* care pmdown_time at stop */
817 unsigned int endianness:1;
818 unsigned int non_legacy_dai_naming:1;
819
820 /* this component uses topology and ignore machine driver FEs */
821 const char *ignore_machine;
822 const char *topology_name_prefix;
823 int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
824 struct snd_pcm_hw_params *params);
825 bool use_dai_pcm_id; /* use the DAI link PCM ID as PCM device number */
826 int be_pcm_base; /* base device ID for all BE PCMs */
827};
828
829struct snd_soc_component {
830 const char *name;
831 int id;
832 const char *name_prefix;
833 struct device *dev;
834 struct snd_soc_card *card;
835
836 unsigned int active;
837
838 unsigned int suspended:1; /* is in suspend PM state */
839
840 struct list_head list;
841 struct list_head card_aux_list; /* for auxiliary bound components */
842 struct list_head card_list;
843
844 const struct snd_soc_component_driver *driver;
845
846 struct list_head dai_list;
847 int num_dai;
848
849 struct regmap *regmap;
850 int val_bytes;
851
852 struct mutex io_mutex;
853
854 /* attached dynamic objects */
855 struct list_head dobj_list;
856
857 /*
858 * DO NOT use any of the fields below in drivers, they are temporary and
859 * are going to be removed again soon. If you use them in driver code the
860 * driver will be marked as BROKEN when these fields are removed.
861 */
862
863 /* Don't use these, use snd_soc_component_get_dapm() */
864 struct snd_soc_dapm_context dapm;
865
866 /* machine specific init */
867 int (*init)(struct snd_soc_component *component);
868
869#ifdef CONFIG_DEBUG_FS
870 struct dentry *debugfs_root;
871 const char *debugfs_prefix;
872#endif
873};
874
875#define for_each_component_dais(component, dai)\
876 list_for_each_entry(dai, &(component)->dai_list, list)
877#define for_each_component_dais_safe(component, dai, _dai)\
878 list_for_each_entry_safe(dai, _dai, &(component)->dai_list, list)
879
880struct snd_soc_rtdcom_list { 735struct snd_soc_rtdcom_list {
881 struct snd_soc_component *component; 736 struct snd_soc_component *component;
882 struct list_head list; /* rtd::component_list */ 737 struct list_head list; /* rtd::component_list */
@@ -1086,6 +941,7 @@ struct snd_soc_dai_link {
1086#define COMP_CPU(_dai) { .dai_name = _dai, } 941#define COMP_CPU(_dai) { .dai_name = _dai, }
1087#define COMP_CODEC(_name, _dai) { .name = _name, .dai_name = _dai, } 942#define COMP_CODEC(_name, _dai) { .name = _name, .dai_name = _dai, }
1088#define COMP_PLATFORM(_name) { .name = _name } 943#define COMP_PLATFORM(_name) { .name = _name }
944#define COMP_AUX(_name) { .name = _name }
1089#define COMP_DUMMY() { .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", } 945#define COMP_DUMMY() { .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", }
1090 946
1091extern struct snd_soc_dai_link_component null_dailink_component[0]; 947extern struct snd_soc_dai_link_component null_dailink_component[0];
@@ -1107,14 +963,11 @@ struct snd_soc_codec_conf {
1107}; 963};
1108 964
1109struct snd_soc_aux_dev { 965struct snd_soc_aux_dev {
1110 const char *name; /* Codec name */
1111
1112 /* 966 /*
1113 * specify multi-codec either by device name, or by 967 * specify multi-codec either by device name, or by
1114 * DT/OF node, but not both. 968 * DT/OF node, but not both.
1115 */ 969 */
1116 const char *codec_name; 970 struct snd_soc_dai_link_component dlc;
1117 struct device_node *codec_of_node;
1118 971
1119 /* codec/machine specific init - e.g. add machine controls */ 972 /* codec/machine specific init - e.g. add machine controls */
1120 int (*init)(struct snd_soc_component *component); 973 int (*init)(struct snd_soc_component *component);
@@ -1135,6 +988,10 @@ struct snd_soc_card {
1135 struct mutex mutex; 988 struct mutex mutex;
1136 struct mutex dapm_mutex; 989 struct mutex dapm_mutex;
1137 990
991 /* Mutex for PCM operations */
992 struct mutex pcm_mutex;
993 enum snd_soc_pcm_subclass pcm_subclass;
994
1138 spinlock_t dpcm_lock; 995 spinlock_t dpcm_lock;
1139 996
1140 bool instantiated; 997 bool instantiated;
@@ -1203,8 +1060,6 @@ struct snd_soc_card {
1203 int num_of_dapm_routes; 1060 int num_of_dapm_routes;
1204 bool fully_routed; 1061 bool fully_routed;
1205 1062
1206 struct work_struct deferred_resume_work;
1207
1208 /* lists of probed devices belonging to this card */ 1063 /* lists of probed devices belonging to this card */
1209 struct list_head component_dev_list; 1064 struct list_head component_dev_list;
1210 struct list_head list; 1065 struct list_head list;
@@ -1224,7 +1079,9 @@ struct snd_soc_card {
1224 1079
1225#ifdef CONFIG_DEBUG_FS 1080#ifdef CONFIG_DEBUG_FS
1226 struct dentry *debugfs_card_root; 1081 struct dentry *debugfs_card_root;
1227 struct dentry *debugfs_pop_time; 1082#endif
1083#ifdef CONFIG_PM_SLEEP
1084 struct work_struct deferred_resume_work;
1228#endif 1085#endif
1229 u32 pop_time; 1086 u32 pop_time;
1230 1087
@@ -1234,6 +1091,10 @@ struct snd_soc_card {
1234 for ((i) = 0; \ 1091 for ((i) = 0; \
1235 ((i) < (card)->num_links) && ((link) = &(card)->dai_link[i]); \ 1092 ((i) < (card)->num_links) && ((link) = &(card)->dai_link[i]); \
1236 (i)++) 1093 (i)++)
1094#define for_each_card_pre_auxs(card, i, aux) \
1095 for ((i) = 0; \
1096 ((i) < (card)->num_aux_devs) && ((aux) = &(card)->aux_dev[i]); \
1097 (i)++)
1237 1098
1238#define for_each_card_links(card, link) \ 1099#define for_each_card_links(card, link) \
1239 list_for_each_entry(link, &(card)->dai_link_list, list) 1100 list_for_each_entry(link, &(card)->dai_link_list, list)
@@ -1245,6 +1106,12 @@ struct snd_soc_card {
1245#define for_each_card_rtds_safe(card, rtd, _rtd) \ 1106#define for_each_card_rtds_safe(card, rtd, _rtd) \
1246 list_for_each_entry_safe(rtd, _rtd, &(card)->rtd_list, list) 1107 list_for_each_entry_safe(rtd, _rtd, &(card)->rtd_list, list)
1247 1108
1109#define for_each_card_auxs(card, component) \
1110 list_for_each_entry(component, &card->aux_comp_list, card_aux_list)
1111#define for_each_card_auxs_safe(card, component, _comp) \
1112 list_for_each_entry_safe(component, _comp, \
1113 &card->aux_comp_list, card_aux_list)
1114
1248#define for_each_card_components(card, component) \ 1115#define for_each_card_components(card, component) \
1249 list_for_each_entry(component, &(card)->component_dev_list, card_list) 1116 list_for_each_entry(component, &(card)->component_dev_list, card_list)
1250 1117
@@ -1253,8 +1120,6 @@ struct snd_soc_pcm_runtime {
1253 struct device *dev; 1120 struct device *dev;
1254 struct snd_soc_card *card; 1121 struct snd_soc_card *card;
1255 struct snd_soc_dai_link *dai_link; 1122 struct snd_soc_dai_link *dai_link;
1256 struct mutex pcm_mutex;
1257 enum snd_soc_pcm_subclass pcm_subclass;
1258 struct snd_pcm_ops ops; 1123 struct snd_pcm_ops ops;
1259 1124
1260 unsigned int params_select; /* currently selected param for dai link */ 1125 unsigned int params_select; /* currently selected param for dai link */
@@ -1342,134 +1207,6 @@ struct soc_enum {
1342 struct snd_soc_dobj dobj; 1207 struct snd_soc_dobj dobj;
1343}; 1208};
1344 1209
1345/**
1346 * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is
1347 * embedded in
1348 * @dapm: The DAPM context to cast to the component
1349 *
1350 * This function must only be used on DAPM contexts that are known to be part of
1351 * a component (e.g. in a component driver). Otherwise the behavior is
1352 * undefined.
1353 */
1354static inline struct snd_soc_component *snd_soc_dapm_to_component(
1355 struct snd_soc_dapm_context *dapm)
1356{
1357 return container_of(dapm, struct snd_soc_component, dapm);
1358}
1359
1360/**
1361 * snd_soc_component_get_dapm() - Returns the DAPM context associated with a
1362 * component
1363 * @component: The component for which to get the DAPM context
1364 */
1365static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
1366 struct snd_soc_component *component)
1367{
1368 return &component->dapm;
1369}
1370
1371/**
1372 * snd_soc_component_init_bias_level() - Initialize COMPONENT DAPM bias level
1373 * @component: The COMPONENT for which to initialize the DAPM bias level
1374 * @level: The DAPM level to initialize to
1375 *
1376 * Initializes the COMPONENT DAPM bias level. See snd_soc_dapm_init_bias_level().
1377 */
1378static inline void
1379snd_soc_component_init_bias_level(struct snd_soc_component *component,
1380 enum snd_soc_bias_level level)
1381{
1382 snd_soc_dapm_init_bias_level(
1383 snd_soc_component_get_dapm(component), level);
1384}
1385
1386/**
1387 * snd_soc_component_get_bias_level() - Get current COMPONENT DAPM bias level
1388 * @component: The COMPONENT for which to get the DAPM bias level
1389 *
1390 * Returns: The current DAPM bias level of the COMPONENT.
1391 */
1392static inline enum snd_soc_bias_level
1393snd_soc_component_get_bias_level(struct snd_soc_component *component)
1394{
1395 return snd_soc_dapm_get_bias_level(
1396 snd_soc_component_get_dapm(component));
1397}
1398
1399/**
1400 * snd_soc_component_force_bias_level() - Set the COMPONENT DAPM bias level
1401 * @component: The COMPONENT for which to set the level
1402 * @level: The level to set to
1403 *
1404 * Forces the COMPONENT bias level to a specific state. See
1405 * snd_soc_dapm_force_bias_level().
1406 */
1407static inline int
1408snd_soc_component_force_bias_level(struct snd_soc_component *component,
1409 enum snd_soc_bias_level level)
1410{
1411 return snd_soc_dapm_force_bias_level(
1412 snd_soc_component_get_dapm(component),
1413 level);
1414}
1415
1416/**
1417 * snd_soc_dapm_kcontrol_component() - Returns the component associated to a kcontrol
1418 * @kcontrol: The kcontrol
1419 *
1420 * This function must only be used on DAPM contexts that are known to be part of
1421 * a COMPONENT (e.g. in a COMPONENT driver). Otherwise the behavior is undefined.
1422 */
1423static inline struct snd_soc_component *snd_soc_dapm_kcontrol_component(
1424 struct snd_kcontrol *kcontrol)
1425{
1426 return snd_soc_dapm_to_component(snd_soc_dapm_kcontrol_dapm(kcontrol));
1427}
1428
1429/**
1430 * snd_soc_component_cache_sync() - Sync the register cache with the hardware
1431 * @component: COMPONENT to sync
1432 *
1433 * Note: This function will call regcache_sync()
1434 */
1435static inline int snd_soc_component_cache_sync(
1436 struct snd_soc_component *component)
1437{
1438 return regcache_sync(component->regmap);
1439}
1440
1441/* component IO */
1442int snd_soc_component_read(struct snd_soc_component *component,
1443 unsigned int reg, unsigned int *val);
1444unsigned int snd_soc_component_read32(struct snd_soc_component *component,
1445 unsigned int reg);
1446int snd_soc_component_write(struct snd_soc_component *component,
1447 unsigned int reg, unsigned int val);
1448int snd_soc_component_update_bits(struct snd_soc_component *component,
1449 unsigned int reg, unsigned int mask, unsigned int val);
1450int snd_soc_component_update_bits_async(struct snd_soc_component *component,
1451 unsigned int reg, unsigned int mask, unsigned int val);
1452void snd_soc_component_async_complete(struct snd_soc_component *component);
1453int snd_soc_component_test_bits(struct snd_soc_component *component,
1454 unsigned int reg, unsigned int mask, unsigned int value);
1455
1456/* component wide operations */
1457int snd_soc_component_set_sysclk(struct snd_soc_component *component,
1458 int clk_id, int source, unsigned int freq, int dir);
1459int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
1460 int source, unsigned int freq_in,
1461 unsigned int freq_out);
1462int snd_soc_component_set_jack(struct snd_soc_component *component,
1463 struct snd_soc_jack *jack, void *data);
1464
1465#ifdef CONFIG_REGMAP
1466
1467void snd_soc_component_init_regmap(struct snd_soc_component *component,
1468 struct regmap *regmap);
1469void snd_soc_component_exit_regmap(struct snd_soc_component *component);
1470
1471#endif
1472
1473/* device driver data */ 1210/* device driver data */
1474 1211
1475static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, 1212static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
@@ -1483,27 +1220,6 @@ static inline void *snd_soc_card_get_drvdata(struct snd_soc_card *card)
1483 return card->drvdata; 1220 return card->drvdata;
1484} 1221}
1485 1222
1486static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c,
1487 void *data)
1488{
1489 dev_set_drvdata(c->dev, data);
1490}
1491
1492static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
1493{
1494 return dev_get_drvdata(c->dev);
1495}
1496
1497static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
1498{
1499 INIT_LIST_HEAD(&card->widgets);
1500 INIT_LIST_HEAD(&card->paths);
1501 INIT_LIST_HEAD(&card->dapm_list);
1502 INIT_LIST_HEAD(&card->aux_comp_list);
1503 INIT_LIST_HEAD(&card->component_dev_list);
1504 INIT_LIST_HEAD(&card->list);
1505}
1506
1507static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc) 1223static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
1508{ 1224{
1509 if (mc->reg == mc->rreg && mc->shift == mc->rshift) 1225 if (mc->reg == mc->rreg && mc->shift == mc->rshift)
@@ -1540,12 +1256,6 @@ static inline unsigned int snd_soc_enum_item_to_val(struct soc_enum *e,
1540 return e->values[item]; 1256 return e->values[item];
1541} 1257}
1542 1258
1543static inline bool snd_soc_component_is_active(
1544 struct snd_soc_component *component)
1545{
1546 return component->active != 0;
1547}
1548
1549/** 1259/**
1550 * snd_soc_kcontrol_component() - Returns the component that registered the 1260 * snd_soc_kcontrol_component() - Returns the component that registered the
1551 * control 1261 * control
@@ -1681,24 +1391,6 @@ static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm)
1681 mutex_unlock(&dapm->card->dapm_mutex); 1391 mutex_unlock(&dapm->card->dapm_mutex);
1682} 1392}
1683 1393
1684int snd_soc_component_enable_pin(struct snd_soc_component *component, 1394#include <sound/soc-component.h>
1685 const char *pin);
1686int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
1687 const char *pin);
1688int snd_soc_component_disable_pin(struct snd_soc_component *component,
1689 const char *pin);
1690int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
1691 const char *pin);
1692int snd_soc_component_nc_pin(struct snd_soc_component *component,
1693 const char *pin);
1694int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
1695 const char *pin);
1696int snd_soc_component_get_pin_status(struct snd_soc_component *component,
1697 const char *pin);
1698int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
1699 const char *pin);
1700int snd_soc_component_force_enable_pin_unlocked(
1701 struct snd_soc_component *component,
1702 const char *pin);
1703 1395
1704#endif 1396#endif
diff --git a/include/sound/sof/dai-intel.h b/include/sound/sof/dai-intel.h
index 65e4c20e567c..5f1ef5565be6 100644
--- a/include/sound/sof/dai-intel.h
+++ b/include/sound/sof/dai-intel.h
@@ -76,6 +76,9 @@ struct sof_ipc_dai_ssp_params {
76 uint16_t tdm_per_slot_padding_flag; 76 uint16_t tdm_per_slot_padding_flag;
77 uint32_t clks_control; 77 uint32_t clks_control;
78 uint32_t quirks; 78 uint32_t quirks;
79 uint32_t bclk_delay; /* guaranteed time (ms) for which BCLK
80 * will be driven, before sending data
81 */
79} __packed; 82} __packed;
80 83
81/* HDA Configuration Request - SOF_IPC_DAI_HDA_CONFIG */ 84/* HDA Configuration Request - SOF_IPC_DAI_HDA_CONFIG */
@@ -176,4 +179,13 @@ struct sof_ipc_dai_dmic_params {
176 struct sof_ipc_dai_dmic_pdm_ctrl pdm[0]; 179 struct sof_ipc_dai_dmic_pdm_ctrl pdm[0];
177} __packed; 180} __packed;
178 181
182/* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */
183struct sof_ipc_dai_alh_params {
184 struct sof_ipc_hdr hdr;
185 uint32_t stream_id;
186
187 /* reserved for future use */
188 uint32_t reserved[15];
189} __packed;
190
179#endif 191#endif
diff --git a/include/sound/sof/dai.h b/include/sound/sof/dai.h
index 5b8de1b1983c..0f1235022146 100644
--- a/include/sound/sof/dai.h
+++ b/include/sound/sof/dai.h
@@ -49,7 +49,9 @@ enum sof_ipc_dai_type {
49 SOF_DAI_INTEL_SSP, /**< Intel SSP */ 49 SOF_DAI_INTEL_SSP, /**< Intel SSP */
50 SOF_DAI_INTEL_DMIC, /**< Intel DMIC */ 50 SOF_DAI_INTEL_DMIC, /**< Intel DMIC */
51 SOF_DAI_INTEL_HDA, /**< Intel HD/A */ 51 SOF_DAI_INTEL_HDA, /**< Intel HD/A */
52 SOF_DAI_INTEL_SOUNDWIRE, /**< Intel SoundWire */ 52 SOF_DAI_INTEL_ALH, /**< Intel ALH */
53 SOF_DAI_IMX_SAI, /**< i.MX SAI */
54 SOF_DAI_IMX_ESAI, /**< i.MX ESAI */
53}; 55};
54 56
55/* general purpose DAI configuration */ 57/* general purpose DAI configuration */
@@ -70,6 +72,7 @@ struct sof_ipc_dai_config {
70 struct sof_ipc_dai_ssp_params ssp; 72 struct sof_ipc_dai_ssp_params ssp;
71 struct sof_ipc_dai_dmic_params dmic; 73 struct sof_ipc_dai_dmic_params dmic;
72 struct sof_ipc_dai_hda_params hda; 74 struct sof_ipc_dai_hda_params hda;
75 struct sof_ipc_dai_alh_params alh;
73 }; 76 };
74} __packed; 77} __packed;
75 78
diff --git a/include/uapi/sound/sof/abi.h b/include/uapi/sound/sof/abi.h
index 4a9c24434f42..a0fe0d4c4b66 100644
--- a/include/uapi/sound/sof/abi.h
+++ b/include/uapi/sound/sof/abi.h
@@ -26,7 +26,7 @@
26 26
27/* SOF ABI version major, minor and patch numbers */ 27/* SOF ABI version major, minor and patch numbers */
28#define SOF_ABI_MAJOR 3 28#define SOF_ABI_MAJOR 3
29#define SOF_ABI_MINOR 8 29#define SOF_ABI_MINOR 10
30#define SOF_ABI_PATCH 0 30#define SOF_ABI_PATCH 0
31 31
32/* SOF ABI version number. Format within 32bit word is MMmmmppp */ 32/* SOF ABI version number. Format within 32bit word is MMmmmppp */
diff --git a/include/uapi/sound/sof/tokens.h b/include/uapi/sound/sof/tokens.h
index dc1b27daaac6..8f996857fb24 100644
--- a/include/uapi/sound/sof/tokens.h
+++ b/include/uapi/sound/sof/tokens.h
@@ -75,6 +75,7 @@
75#define SOF_TKN_INTEL_SSP_FRAME_PULSE_WIDTH 503 75#define SOF_TKN_INTEL_SSP_FRAME_PULSE_WIDTH 503
76#define SOF_TKN_INTEL_SSP_QUIRKS 504 76#define SOF_TKN_INTEL_SSP_QUIRKS 504
77#define SOF_TKN_INTEL_SSP_TDM_PADDING_PER_SLOT 505 77#define SOF_TKN_INTEL_SSP_TDM_PADDING_PER_SLOT 505
78#define SOF_TKN_INTEL_SSP_BCLK_DELAY 506
78 79
79/* DMIC */ 80/* DMIC */
80#define SOF_TKN_INTEL_DMIC_DRIVER_VERSION 600 81#define SOF_TKN_INTEL_DMIC_DRIVER_VERSION 600
@@ -105,4 +106,12 @@
105/* for backward compatibility */ 106/* for backward compatibility */
106#define SOF_TKN_EFFECT_TYPE SOF_TKN_PROCESS_TYPE 107#define SOF_TKN_EFFECT_TYPE SOF_TKN_PROCESS_TYPE
107 108
109/* SAI */
110#define SOF_TKN_IMX_SAI_FIRST_TOKEN 1000
111/* TODO: Add SAI tokens */
112
113/* ESAI */
114#define SOF_TKN_IMX_ESAI_FIRST_TOKEN 1100
115/* TODO: Add ESAI tokens */
116
108#endif 117#endif
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 703857aab00f..11e653c8aa0e 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2170,7 +2170,7 @@ static int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params,
2170 2170
2171static const unsigned int rates[] = { 2171static const unsigned int rates[] = {
2172 5512, 8000, 11025, 16000, 22050, 32000, 44100, 2172 5512, 8000, 11025, 16000, 22050, 32000, 44100,
2173 48000, 64000, 88200, 96000, 176400, 192000 2173 48000, 64000, 88200, 96000, 176400, 192000, 352800, 384000
2174}; 2174};
2175 2175
2176const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = { 2176const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = {
diff --git a/sound/hda/Kconfig b/sound/hda/Kconfig
index f6feced15f17..3d33fc1757ba 100644
--- a/sound/hda/Kconfig
+++ b/sound/hda/Kconfig
@@ -6,6 +6,9 @@ config SND_HDA_CORE
6config SND_HDA_DSP_LOADER 6config SND_HDA_DSP_LOADER
7 bool 7 bool
8 8
9config SND_HDA_ALIGNED_MMIO
10 bool
11
9config SND_HDA_COMPONENT 12config SND_HDA_COMPONENT
10 bool 13 bool
11 14
@@ -29,3 +32,8 @@ config SND_HDA_PREALLOC_SIZE
29 32
30 Note that the pre-allocation size can be changed dynamically 33 Note that the pre-allocation size can be changed dynamically
31 via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too. 34 via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too.
35
36config SND_INTEL_NHLT
37 tristate
38 # this config should be selected only for Intel ACPI platforms.
39 # A fallback is provided so that the code compiles in all cases. \ No newline at end of file
diff --git a/sound/hda/Makefile b/sound/hda/Makefile
index 2160202e2dc1..8560f6ef1b19 100644
--- a/sound/hda/Makefile
+++ b/sound/hda/Makefile
@@ -13,3 +13,6 @@ obj-$(CONFIG_SND_HDA_CORE) += snd-hda-core.o
13 13
14#extended hda 14#extended hda
15obj-$(CONFIG_SND_HDA_EXT_CORE) += ext/ 15obj-$(CONFIG_SND_HDA_EXT_CORE) += ext/
16
17snd-intel-nhlt-objs := intel-nhlt.o
18obj-$(CONFIG_SND_INTEL_NHLT) += snd-intel-nhlt.o
diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c
index 4f9f1d2a2ec5..242306d820ec 100644
--- a/sound/hda/ext/hdac_ext_bus.c
+++ b/sound/hda/ext/hdac_ext_bus.c
@@ -17,80 +17,22 @@
17MODULE_DESCRIPTION("HDA extended core"); 17MODULE_DESCRIPTION("HDA extended core");
18MODULE_LICENSE("GPL v2"); 18MODULE_LICENSE("GPL v2");
19 19
20static void hdac_ext_writel(u32 value, u32 __iomem *addr)
21{
22 writel(value, addr);
23}
24
25static u32 hdac_ext_readl(u32 __iomem *addr)
26{
27 return readl(addr);
28}
29
30static void hdac_ext_writew(u16 value, u16 __iomem *addr)
31{
32 writew(value, addr);
33}
34
35static u16 hdac_ext_readw(u16 __iomem *addr)
36{
37 return readw(addr);
38}
39
40static void hdac_ext_writeb(u8 value, u8 __iomem *addr)
41{
42 writeb(value, addr);
43}
44
45static u8 hdac_ext_readb(u8 __iomem *addr)
46{
47 return readb(addr);
48}
49
50static int hdac_ext_dma_alloc_pages(struct hdac_bus *bus, int type,
51 size_t size, struct snd_dma_buffer *buf)
52{
53 return snd_dma_alloc_pages(type, bus->dev, size, buf);
54}
55
56static void hdac_ext_dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf)
57{
58 snd_dma_free_pages(buf);
59}
60
61static const struct hdac_io_ops hdac_ext_default_io = {
62 .reg_writel = hdac_ext_writel,
63 .reg_readl = hdac_ext_readl,
64 .reg_writew = hdac_ext_writew,
65 .reg_readw = hdac_ext_readw,
66 .reg_writeb = hdac_ext_writeb,
67 .reg_readb = hdac_ext_readb,
68 .dma_alloc_pages = hdac_ext_dma_alloc_pages,
69 .dma_free_pages = hdac_ext_dma_free_pages,
70};
71
72/** 20/**
73 * snd_hdac_ext_bus_init - initialize a HD-audio extended bus 21 * snd_hdac_ext_bus_init - initialize a HD-audio extended bus
74 * @ebus: the pointer to extended bus object 22 * @ebus: the pointer to extended bus object
75 * @dev: device pointer 23 * @dev: device pointer
76 * @ops: bus verb operators 24 * @ops: bus verb operators
77 * @io_ops: lowlevel I/O operators, can be NULL. If NULL core will use
78 * default ops 25 * default ops
79 * 26 *
80 * Returns 0 if successful, or a negative error code. 27 * Returns 0 if successful, or a negative error code.
81 */ 28 */
82int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, 29int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
83 const struct hdac_bus_ops *ops, 30 const struct hdac_bus_ops *ops,
84 const struct hdac_io_ops *io_ops,
85 const struct hdac_ext_bus_ops *ext_ops) 31 const struct hdac_ext_bus_ops *ext_ops)
86{ 32{
87 int ret; 33 int ret;
88 34
89 /* check if io ops are provided, if not load the defaults */ 35 ret = snd_hdac_bus_init(bus, dev, ops);
90 if (io_ops == NULL)
91 io_ops = &hdac_ext_default_io;
92
93 ret = snd_hdac_bus_init(bus, dev, ops, io_ops);
94 if (ret < 0) 36 if (ret < 0)
95 return ret; 37 return ret;
96 38
diff --git a/sound/hda/hdac_bus.c b/sound/hda/hdac_bus.c
index 14e57ffd5bc1..cd25e2b3f7f2 100644
--- a/sound/hda/hdac_bus.c
+++ b/sound/hda/hdac_bus.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include <linux/init.h> 6#include <linux/init.h>
7#include <linux/io.h>
7#include <linux/device.h> 8#include <linux/device.h>
8#include <linux/module.h> 9#include <linux/module.h>
9#include <linux/export.h> 10#include <linux/export.h>
@@ -19,13 +20,11 @@ static const struct hdac_bus_ops default_ops = {
19 * snd_hdac_bus_init - initialize a HD-audio bas bus 20 * snd_hdac_bus_init - initialize a HD-audio bas bus
20 * @bus: the pointer to bus object 21 * @bus: the pointer to bus object
21 * @ops: bus verb operators 22 * @ops: bus verb operators
22 * @io_ops: lowlevel I/O operators
23 * 23 *
24 * Returns 0 if successful, or a negative error code. 24 * Returns 0 if successful, or a negative error code.
25 */ 25 */
26int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, 26int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
27 const struct hdac_bus_ops *ops, 27 const struct hdac_bus_ops *ops)
28 const struct hdac_io_ops *io_ops)
29{ 28{
30 memset(bus, 0, sizeof(*bus)); 29 memset(bus, 0, sizeof(*bus));
31 bus->dev = dev; 30 bus->dev = dev;
@@ -33,7 +32,7 @@ int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
33 bus->ops = ops; 32 bus->ops = ops;
34 else 33 else
35 bus->ops = &default_ops; 34 bus->ops = &default_ops;
36 bus->io_ops = io_ops; 35 bus->dma_type = SNDRV_DMA_TYPE_DEV;
37 INIT_LIST_HEAD(&bus->stream_list); 36 INIT_LIST_HEAD(&bus->stream_list);
38 INIT_LIST_HEAD(&bus->codec_list); 37 INIT_LIST_HEAD(&bus->codec_list);
39 INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events); 38 INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events);
@@ -217,3 +216,33 @@ void snd_hdac_bus_remove_device(struct hdac_bus *bus,
217 flush_work(&bus->unsol_work); 216 flush_work(&bus->unsol_work);
218} 217}
219EXPORT_SYMBOL_GPL(snd_hdac_bus_remove_device); 218EXPORT_SYMBOL_GPL(snd_hdac_bus_remove_device);
219
220#ifdef CONFIG_SND_HDA_ALIGNED_MMIO
221/* Helpers for aligned read/write of mmio space, for Tegra */
222unsigned int snd_hdac_aligned_read(void __iomem *addr, unsigned int mask)
223{
224 void __iomem *aligned_addr =
225 (void __iomem *)((unsigned long)(addr) & ~0x3);
226 unsigned int shift = ((unsigned long)(addr) & 0x3) << 3;
227 unsigned int v;
228
229 v = readl(aligned_addr);
230 return (v >> shift) & mask;
231}
232EXPORT_SYMBOL_GPL(snd_hdac_aligned_read);
233
234void snd_hdac_aligned_write(unsigned int val, void __iomem *addr,
235 unsigned int mask)
236{
237 void __iomem *aligned_addr =
238 (void __iomem *)((unsigned long)(addr) & ~0x3);
239 unsigned int shift = ((unsigned long)(addr) & 0x3) << 3;
240 unsigned int v;
241
242 v = readl(aligned_addr);
243 v &= ~(mask << shift);
244 v |= val << shift;
245 writel(v, aligned_addr);
246}
247EXPORT_SYMBOL_GPL(snd_hdac_aligned_write);
248#endif /* CONFIG_SND_HDA_ALIGNED_MMIO */
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index 3b0110545070..7e7be8e4dcf9 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -575,12 +575,13 @@ int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus)
575{ 575{
576 struct hdac_stream *s; 576 struct hdac_stream *s;
577 int num_streams = 0; 577 int num_streams = 0;
578 int dma_type = bus->dma_type ? bus->dma_type : SNDRV_DMA_TYPE_DEV;
578 int err; 579 int err;
579 580
580 list_for_each_entry(s, &bus->stream_list, list) { 581 list_for_each_entry(s, &bus->stream_list, list) {
581 /* allocate memory for the BDL for each stream */ 582 /* allocate memory for the BDL for each stream */
582 err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, 583 err = snd_dma_alloc_pages(dma_type, bus->dev,
583 BDL_SIZE, &s->bdl); 584 BDL_SIZE, &s->bdl);
584 num_streams++; 585 num_streams++;
585 if (err < 0) 586 if (err < 0)
586 return -ENOMEM; 587 return -ENOMEM;
@@ -589,16 +590,15 @@ int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus)
589 if (WARN_ON(!num_streams)) 590 if (WARN_ON(!num_streams))
590 return -EINVAL; 591 return -EINVAL;
591 /* allocate memory for the position buffer */ 592 /* allocate memory for the position buffer */
592 err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, 593 err = snd_dma_alloc_pages(dma_type, bus->dev,
593 num_streams * 8, &bus->posbuf); 594 num_streams * 8, &bus->posbuf);
594 if (err < 0) 595 if (err < 0)
595 return -ENOMEM; 596 return -ENOMEM;
596 list_for_each_entry(s, &bus->stream_list, list) 597 list_for_each_entry(s, &bus->stream_list, list)
597 s->posbuf = (__le32 *)(bus->posbuf.area + s->index * 8); 598 s->posbuf = (__le32 *)(bus->posbuf.area + s->index * 8);
598 599
599 /* single page (at least 4096 bytes) must suffice for both ringbuffes */ 600 /* single page (at least 4096 bytes) must suffice for both ringbuffes */
600 return bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, 601 return snd_dma_alloc_pages(dma_type, bus->dev, PAGE_SIZE, &bus->rb);
601 PAGE_SIZE, &bus->rb);
602} 602}
603EXPORT_SYMBOL_GPL(snd_hdac_bus_alloc_stream_pages); 603EXPORT_SYMBOL_GPL(snd_hdac_bus_alloc_stream_pages);
604 604
@@ -612,12 +612,12 @@ void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus)
612 612
613 list_for_each_entry(s, &bus->stream_list, list) { 613 list_for_each_entry(s, &bus->stream_list, list) {
614 if (s->bdl.area) 614 if (s->bdl.area)
615 bus->io_ops->dma_free_pages(bus, &s->bdl); 615 snd_dma_free_pages(&s->bdl);
616 } 616 }
617 617
618 if (bus->rb.area) 618 if (bus->rb.area)
619 bus->io_ops->dma_free_pages(bus, &bus->rb); 619 snd_dma_free_pages(&bus->rb);
620 if (bus->posbuf.area) 620 if (bus->posbuf.area)
621 bus->io_ops->dma_free_pages(bus, &bus->posbuf); 621 snd_dma_free_pages(&bus->posbuf);
622} 622}
623EXPORT_SYMBOL_GPL(snd_hdac_bus_free_stream_pages); 623EXPORT_SYMBOL_GPL(snd_hdac_bus_free_stream_pages);
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index 55d53b89ac21..fc68d4ce0a37 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -680,8 +680,8 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
680 azx_dev->locked = true; 680 azx_dev->locked = true;
681 spin_unlock_irq(&bus->reg_lock); 681 spin_unlock_irq(&bus->reg_lock);
682 682
683 err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV_SG, 683 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, bus->dev,
684 byte_size, bufp); 684 byte_size, bufp);
685 if (err < 0) 685 if (err < 0)
686 goto err_alloc; 686 goto err_alloc;
687 687
@@ -707,7 +707,7 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
707 return azx_dev->stream_tag; 707 return azx_dev->stream_tag;
708 708
709 error: 709 error:
710 bus->io_ops->dma_free_pages(bus, bufp); 710 snd_dma_free_pages(bufp);
711 err_alloc: 711 err_alloc:
712 spin_lock_irq(&bus->reg_lock); 712 spin_lock_irq(&bus->reg_lock);
713 azx_dev->locked = false; 713 azx_dev->locked = false;
@@ -754,7 +754,7 @@ void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev,
754 azx_dev->period_bytes = 0; 754 azx_dev->period_bytes = 0;
755 azx_dev->format_val = 0; 755 azx_dev->format_val = 0;
756 756
757 bus->io_ops->dma_free_pages(bus, dmab); 757 snd_dma_free_pages(dmab);
758 dmab->area = NULL; 758 dmab->area = NULL;
759 759
760 spin_lock_irq(&bus->reg_lock); 760 spin_lock_irq(&bus->reg_lock);
diff --git a/sound/hda/intel-nhlt.c b/sound/hda/intel-nhlt.c
new file mode 100644
index 000000000000..daede96f28ee
--- /dev/null
+++ b/sound/hda/intel-nhlt.c
@@ -0,0 +1,107 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2015-2019 Intel Corporation
3
4#include <linux/acpi.h>
5#include <sound/intel-nhlt.h>
6
7#define NHLT_ACPI_HEADER_SIG "NHLT"
8
9/* Unique identification for getting NHLT blobs */
10static guid_t osc_guid =
11 GUID_INIT(0xA69F886E, 0x6CEB, 0x4594,
12 0xA4, 0x1F, 0x7B, 0x5D, 0xCE, 0x24, 0xC5, 0x53);
13
14struct nhlt_acpi_table *intel_nhlt_init(struct device *dev)
15{
16 acpi_handle handle;
17 union acpi_object *obj;
18 struct nhlt_resource_desc *nhlt_ptr;
19 struct nhlt_acpi_table *nhlt_table = NULL;
20
21 handle = ACPI_HANDLE(dev);
22 if (!handle) {
23 dev_err(dev, "Didn't find ACPI_HANDLE\n");
24 return NULL;
25 }
26
27 obj = acpi_evaluate_dsm(handle, &osc_guid, 1, 1, NULL);
28
29 if (!obj)
30 return NULL;
31
32 if (obj->type != ACPI_TYPE_BUFFER) {
33 dev_dbg(dev, "No NHLT table found\n");
34 ACPI_FREE(obj);
35 return NULL;
36 }
37
38 nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer;
39 if (nhlt_ptr->length)
40 nhlt_table = (struct nhlt_acpi_table *)
41 memremap(nhlt_ptr->min_addr, nhlt_ptr->length,
42 MEMREMAP_WB);
43 ACPI_FREE(obj);
44 if (nhlt_table &&
45 (strncmp(nhlt_table->header.signature,
46 NHLT_ACPI_HEADER_SIG,
47 strlen(NHLT_ACPI_HEADER_SIG)) != 0)) {
48 memunmap(nhlt_table);
49 dev_err(dev, "NHLT ACPI header signature incorrect\n");
50 return NULL;
51 }
52 return nhlt_table;
53}
54EXPORT_SYMBOL_GPL(intel_nhlt_init);
55
56void intel_nhlt_free(struct nhlt_acpi_table *nhlt)
57{
58 memunmap((void *)nhlt);
59}
60EXPORT_SYMBOL_GPL(intel_nhlt_free);
61
62int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt)
63{
64 struct nhlt_endpoint *epnt;
65 struct nhlt_dmic_array_config *cfg;
66 struct nhlt_vendor_dmic_array_config *cfg_vendor;
67 unsigned int dmic_geo = 0;
68 u8 j;
69
70 if (!nhlt)
71 return 0;
72
73 epnt = (struct nhlt_endpoint *)nhlt->desc;
74
75 for (j = 0; j < nhlt->endpoint_count; j++) {
76 if (epnt->linktype == NHLT_LINK_DMIC) {
77 cfg = (struct nhlt_dmic_array_config *)
78 (epnt->config.caps);
79 switch (cfg->array_type) {
80 case NHLT_MIC_ARRAY_2CH_SMALL:
81 case NHLT_MIC_ARRAY_2CH_BIG:
82 dmic_geo = MIC_ARRAY_2CH;
83 break;
84
85 case NHLT_MIC_ARRAY_4CH_1ST_GEOM:
86 case NHLT_MIC_ARRAY_4CH_L_SHAPED:
87 case NHLT_MIC_ARRAY_4CH_2ND_GEOM:
88 dmic_geo = MIC_ARRAY_4CH;
89 break;
90 case NHLT_MIC_ARRAY_VENDOR_DEFINED:
91 cfg_vendor = (struct nhlt_vendor_dmic_array_config *)cfg;
92 dmic_geo = cfg_vendor->nb_mics;
93 break;
94 default:
95 dev_warn(dev, "undefined DMIC array_type 0x%0x\n",
96 cfg->array_type);
97 }
98 }
99 epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
100 }
101
102 return dmic_geo;
103}
104EXPORT_SYMBOL_GPL(intel_nhlt_get_dmic_geo);
105
106MODULE_LICENSE("GPL v2");
107MODULE_DESCRIPTION("Intel NHLT driver");
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 35d934309cb2..dae47a45b2b8 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -12,6 +12,7 @@ config SND_HDA_INTEL
12 tristate "HD Audio PCI" 12 tristate "HD Audio PCI"
13 depends on SND_PCI 13 depends on SND_PCI
14 select SND_HDA 14 select SND_HDA
15 select SND_INTEL_NHLT if ACPI
15 help 16 help
16 Say Y here to include support for Intel "High Definition 17 Say Y here to include support for Intel "High Definition
17 Audio" (Azalia) and its compatible devices. 18 Audio" (Azalia) and its compatible devices.
@@ -22,10 +23,20 @@ config SND_HDA_INTEL
22 To compile this driver as a module, choose M here: the module 23 To compile this driver as a module, choose M here: the module
23 will be called snd-hda-intel. 24 will be called snd-hda-intel.
24 25
26config SND_HDA_INTEL_DETECT_DMIC
27 bool "DMIC detection and probe abort"
28 depends on SND_HDA_INTEL
29 help
30 Say Y to detect digital microphones on SKL+ devices. DMICs
31 cannot be handled by the HDaudio legacy driver and are
32 currently only supported by the SOF driver.
33 If unsure say N.
34
25config SND_HDA_TEGRA 35config SND_HDA_TEGRA
26 tristate "NVIDIA Tegra HD Audio" 36 tristate "NVIDIA Tegra HD Audio"
27 depends on ARCH_TEGRA 37 depends on ARCH_TEGRA
28 select SND_HDA 38 select SND_HDA
39 select SND_HDA_ALIGNED_MMIO
29 help 40 help
30 Say Y here to support the HDA controller present in NVIDIA 41 Say Y here to support the HDA controller present in NVIDIA
31 Tegra SoCs 42 Tegra SoCs
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 51f10ed9bc43..a2fb19129219 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -846,7 +846,13 @@ static void snd_hda_codec_dev_release(struct device *dev)
846 snd_hda_sysfs_clear(codec); 846 snd_hda_sysfs_clear(codec);
847 kfree(codec->modelname); 847 kfree(codec->modelname);
848 kfree(codec->wcaps); 848 kfree(codec->wcaps);
849 kfree(codec); 849
850 /*
851 * In the case of ASoC HD-audio, hda_codec is device managed.
852 * It will be freed when the ASoC device is removed.
853 */
854 if (codec->core.type == HDA_DEV_LEGACY)
855 kfree(codec);
850} 856}
851 857
852#define DEV_NAME_LEN 31 858#define DEV_NAME_LEN 31
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 48d863736b3c..97a43a28b9e4 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -1207,14 +1207,12 @@ void snd_hda_bus_reset(struct hda_bus *bus)
1207} 1207}
1208 1208
1209/* HD-audio bus initialization */ 1209/* HD-audio bus initialization */
1210int azx_bus_init(struct azx *chip, const char *model, 1210int azx_bus_init(struct azx *chip, const char *model)
1211 const struct hdac_io_ops *io_ops)
1212{ 1211{
1213 struct hda_bus *bus = &chip->bus; 1212 struct hda_bus *bus = &chip->bus;
1214 int err; 1213 int err;
1215 1214
1216 err = snd_hdac_bus_init(&bus->core, chip->card->dev, &bus_core_ops, 1215 err = snd_hdac_bus_init(&bus->core, chip->card->dev, &bus_core_ops);
1217 io_ops);
1218 if (err < 0) 1216 if (err < 0)
1219 return err; 1217 return err;
1220 1218
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
index f2a6df5e6bcb..82e26442724b 100644
--- a/sound/pci/hda/hda_controller.h
+++ b/sound/pci/hda/hda_controller.h
@@ -206,8 +206,7 @@ void azx_stop_chip(struct azx *chip);
206irqreturn_t azx_interrupt(int irq, void *dev_id); 206irqreturn_t azx_interrupt(int irq, void *dev_id);
207 207
208/* Codec interface */ 208/* Codec interface */
209int azx_bus_init(struct azx *chip, const char *model, 209int azx_bus_init(struct azx *chip, const char *model);
210 const struct hdac_io_ops *io_ops);
211int azx_probe_codecs(struct azx *chip, unsigned int max_slots); 210int azx_probe_codecs(struct azx *chip, unsigned int max_slots);
212int azx_codec_configure(struct azx *chip); 211int azx_codec_configure(struct azx *chip);
213int azx_init_streams(struct azx *chip); 212int azx_init_streams(struct azx *chip);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 99fc0917339b..2d0db3c9f335 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -46,6 +46,7 @@
46#include <sound/initval.h> 46#include <sound/initval.h>
47#include <sound/hdaudio.h> 47#include <sound/hdaudio.h>
48#include <sound/hda_i915.h> 48#include <sound/hda_i915.h>
49#include <sound/intel-nhlt.h>
49#include <linux/vgaarb.h> 50#include <linux/vgaarb.h>
50#include <linux/vga_switcheroo.h> 51#include <linux/vga_switcheroo.h>
51#include <linux/firmware.h> 52#include <linux/firmware.h>
@@ -125,6 +126,7 @@ static char *patch[SNDRV_CARDS];
125static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 126static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
126 CONFIG_SND_HDA_INPUT_BEEP_MODE}; 127 CONFIG_SND_HDA_INPUT_BEEP_MODE};
127#endif 128#endif
129static bool dmic_detect = IS_ENABLED(CONFIG_SND_HDA_INTEL_DETECT_DMIC);
128 130
129module_param_array(index, int, NULL, 0444); 131module_param_array(index, int, NULL, 0444);
130MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); 132MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -159,6 +161,8 @@ module_param_array(beep_mode, bool, NULL, 0444);
159MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " 161MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
160 "(0=off, 1=on) (default=1)."); 162 "(0=off, 1=on) (default=1).");
161#endif 163#endif
164module_param(dmic_detect, bool, 0444);
165MODULE_PARM_DESC(dmic_detect, "DMIC detect on SKL+ platforms");
162 166
163#ifdef CONFIG_PM 167#ifdef CONFIG_PM
164static int param_set_xint(const char *val, const struct kernel_param *kp); 168static int param_set_xint(const char *val, const struct kernel_param *kp);
@@ -1684,7 +1688,6 @@ static int default_bdl_pos_adj(struct azx *chip)
1684/* 1688/*
1685 * constructor 1689 * constructor
1686 */ 1690 */
1687static const struct hdac_io_ops pci_hda_io_ops;
1688static const struct hda_controller_ops pci_hda_ops; 1691static const struct hda_controller_ops pci_hda_ops;
1689 1692
1690static int azx_create(struct snd_card *card, struct pci_dev *pci, 1693static int azx_create(struct snd_card *card, struct pci_dev *pci,
@@ -1744,13 +1747,17 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
1744 else 1747 else
1745 chip->bdl_pos_adj = bdl_pos_adj[dev]; 1748 chip->bdl_pos_adj = bdl_pos_adj[dev];
1746 1749
1747 err = azx_bus_init(chip, model[dev], &pci_hda_io_ops); 1750 err = azx_bus_init(chip, model[dev]);
1748 if (err < 0) { 1751 if (err < 0) {
1749 kfree(hda); 1752 kfree(hda);
1750 pci_disable_device(pci); 1753 pci_disable_device(pci);
1751 return err; 1754 return err;
1752 } 1755 }
1753 1756
1757 /* use the non-cached pages in non-snoop mode */
1758 if (!azx_snoop(chip))
1759 azx_bus(chip)->dma_type = SNDRV_DMA_TYPE_DEV_UC;
1760
1754 /* Workaround for a communication error on CFL (bko#199007) and CNL */ 1761 /* Workaround for a communication error on CFL (bko#199007) and CNL */
1755 if (IS_CFL(pci) || IS_CNL(pci)) 1762 if (IS_CFL(pci) || IS_CNL(pci))
1756 azx_bus(chip)->polling_mode = 1; 1763 azx_bus(chip)->polling_mode = 1;
@@ -1985,41 +1992,6 @@ static void azx_firmware_cb(const struct firmware *fw, void *context)
1985} 1992}
1986#endif 1993#endif
1987 1994
1988/*
1989 * HDA controller ops.
1990 */
1991
1992/* PCI register access. */
1993static void pci_azx_writel(u32 value, u32 __iomem *addr)
1994{
1995 writel(value, addr);
1996}
1997
1998static u32 pci_azx_readl(u32 __iomem *addr)
1999{
2000 return readl(addr);
2001}
2002
2003static void pci_azx_writew(u16 value, u16 __iomem *addr)
2004{
2005 writew(value, addr);
2006}
2007
2008static u16 pci_azx_readw(u16 __iomem *addr)
2009{
2010 return readw(addr);
2011}
2012
2013static void pci_azx_writeb(u8 value, u8 __iomem *addr)
2014{
2015 writeb(value, addr);
2016}
2017
2018static u8 pci_azx_readb(u8 __iomem *addr)
2019{
2020 return readb(addr);
2021}
2022
2023static int disable_msi_reset_irq(struct azx *chip) 1995static int disable_msi_reset_irq(struct azx *chip)
2024{ 1996{
2025 struct hdac_bus *bus = azx_bus(chip); 1997 struct hdac_bus *bus = azx_bus(chip);
@@ -2036,24 +2008,6 @@ static int disable_msi_reset_irq(struct azx *chip)
2036 return 0; 2008 return 0;
2037} 2009}
2038 2010
2039/* DMA page allocation helpers. */
2040static int dma_alloc_pages(struct hdac_bus *bus,
2041 int type,
2042 size_t size,
2043 struct snd_dma_buffer *buf)
2044{
2045 struct azx *chip = bus_to_azx(bus);
2046
2047 if (!azx_snoop(chip) && type == SNDRV_DMA_TYPE_DEV)
2048 type = SNDRV_DMA_TYPE_DEV_UC;
2049 return snd_dma_alloc_pages(type, bus->dev, size, buf);
2050}
2051
2052static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf)
2053{
2054 snd_dma_free_pages(buf);
2055}
2056
2057static void pcm_mmap_prepare(struct snd_pcm_substream *substream, 2011static void pcm_mmap_prepare(struct snd_pcm_substream *substream,
2058 struct vm_area_struct *area) 2012 struct vm_area_struct *area)
2059{ 2013{
@@ -2065,23 +2019,31 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream,
2065#endif 2019#endif
2066} 2020}
2067 2021
2068static const struct hdac_io_ops pci_hda_io_ops = {
2069 .reg_writel = pci_azx_writel,
2070 .reg_readl = pci_azx_readl,
2071 .reg_writew = pci_azx_writew,
2072 .reg_readw = pci_azx_readw,
2073 .reg_writeb = pci_azx_writeb,
2074 .reg_readb = pci_azx_readb,
2075 .dma_alloc_pages = dma_alloc_pages,
2076 .dma_free_pages = dma_free_pages,
2077};
2078
2079static const struct hda_controller_ops pci_hda_ops = { 2022static const struct hda_controller_ops pci_hda_ops = {
2080 .disable_msi_reset_irq = disable_msi_reset_irq, 2023 .disable_msi_reset_irq = disable_msi_reset_irq,
2081 .pcm_mmap_prepare = pcm_mmap_prepare, 2024 .pcm_mmap_prepare = pcm_mmap_prepare,
2082 .position_check = azx_position_check, 2025 .position_check = azx_position_check,
2083}; 2026};
2084 2027
2028static int azx_check_dmic(struct pci_dev *pci, struct azx *chip)
2029{
2030 struct nhlt_acpi_table *nhlt;
2031 int ret = 0;
2032
2033 if (chip->driver_type == AZX_DRIVER_SKL &&
2034 pci->class != 0x040300) {
2035 nhlt = intel_nhlt_init(&pci->dev);
2036 if (nhlt) {
2037 if (intel_nhlt_get_dmic_geo(&pci->dev, nhlt)) {
2038 ret = -ENODEV;
2039 dev_info(&pci->dev, "Digital mics found on Skylake+ platform, aborting probe\n");
2040 }
2041 intel_nhlt_free(nhlt);
2042 }
2043 }
2044 return ret;
2045}
2046
2085static int azx_probe(struct pci_dev *pci, 2047static int azx_probe(struct pci_dev *pci,
2086 const struct pci_device_id *pci_id) 2048 const struct pci_device_id *pci_id)
2087{ 2049{
@@ -2112,6 +2074,17 @@ static int azx_probe(struct pci_dev *pci,
2112 card->private_data = chip; 2074 card->private_data = chip;
2113 hda = container_of(chip, struct hda_intel, chip); 2075 hda = container_of(chip, struct hda_intel, chip);
2114 2076
2077 /*
2078 * stop probe if digital microphones detected on Skylake+ platform
2079 * with the DSP enabled. This is an opt-in behavior defined at build
2080 * time or at run-time with a module parameter
2081 */
2082 if (dmic_detect) {
2083 err = azx_check_dmic(pci, chip);
2084 if (err < 0)
2085 goto out_free;
2086 }
2087
2115 pci_set_drvdata(pci, card); 2088 pci_set_drvdata(pci, card);
2116 2089
2117 err = register_vga_switcheroo(chip); 2090 err = register_vga_switcheroo(chip);
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index 7dbe9f39fc79..8350954b7986 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -75,88 +75,6 @@ MODULE_PARM_DESC(power_save,
75#define power_save 0 75#define power_save 0
76#endif 76#endif
77 77
78/*
79 * DMA page allocation ops.
80 */
81static int dma_alloc_pages(struct hdac_bus *bus, int type, size_t size,
82 struct snd_dma_buffer *buf)
83{
84 return snd_dma_alloc_pages(type, bus->dev, size, buf);
85}
86
87static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf)
88{
89 snd_dma_free_pages(buf);
90}
91
92/*
93 * Register access ops. Tegra HDA register access is DWORD only.
94 */
95static void hda_tegra_writel(u32 value, u32 __iomem *addr)
96{
97 writel(value, addr);
98}
99
100static u32 hda_tegra_readl(u32 __iomem *addr)
101{
102 return readl(addr);
103}
104
105static void hda_tegra_writew(u16 value, u16 __iomem *addr)
106{
107 unsigned int shift = ((unsigned long)(addr) & 0x3) << 3;
108 void __iomem *dword_addr = (void __iomem *)((unsigned long)(addr) & ~0x3);
109 u32 v;
110
111 v = readl(dword_addr);
112 v &= ~(0xffff << shift);
113 v |= value << shift;
114 writel(v, dword_addr);
115}
116
117static u16 hda_tegra_readw(u16 __iomem *addr)
118{
119 unsigned int shift = ((unsigned long)(addr) & 0x3) << 3;
120 void __iomem *dword_addr = (void __iomem *)((unsigned long)(addr) & ~0x3);
121 u32 v;
122
123 v = readl(dword_addr);
124 return (v >> shift) & 0xffff;
125}
126
127static void hda_tegra_writeb(u8 value, u8 __iomem *addr)
128{
129 unsigned int shift = ((unsigned long)(addr) & 0x3) << 3;
130 void __iomem *dword_addr = (void __iomem *)((unsigned long)(addr) & ~0x3);
131 u32 v;
132
133 v = readl(dword_addr);
134 v &= ~(0xff << shift);
135 v |= value << shift;
136 writel(v, dword_addr);
137}
138
139static u8 hda_tegra_readb(u8 __iomem *addr)
140{
141 unsigned int shift = ((unsigned long)(addr) & 0x3) << 3;
142 void __iomem *dword_addr = (void __iomem *)((unsigned long)(addr) & ~0x3);
143 u32 v;
144
145 v = readl(dword_addr);
146 return (v >> shift) & 0xff;
147}
148
149static const struct hdac_io_ops hda_tegra_io_ops = {
150 .reg_writel = hda_tegra_writel,
151 .reg_readl = hda_tegra_readl,
152 .reg_writew = hda_tegra_writew,
153 .reg_readw = hda_tegra_readw,
154 .reg_writeb = hda_tegra_writeb,
155 .reg_readb = hda_tegra_readb,
156 .dma_alloc_pages = dma_alloc_pages,
157 .dma_free_pages = dma_free_pages,
158};
159
160static const struct hda_controller_ops hda_tegra_ops; /* nothing special */ 78static const struct hda_controller_ops hda_tegra_ops; /* nothing special */
161 79
162static void hda_tegra_init(struct hda_tegra *hda) 80static void hda_tegra_init(struct hda_tegra *hda)
@@ -475,7 +393,7 @@ static int hda_tegra_create(struct snd_card *card,
475 393
476 INIT_WORK(&hda->probe_work, hda_tegra_probe_work); 394 INIT_WORK(&hda->probe_work, hda_tegra_probe_work);
477 395
478 err = azx_bus_init(chip, NULL, &hda_tegra_io_ops); 396 err = azx_bus_init(chip, NULL);
479 if (err < 0) 397 if (err < 0)
480 return err; 398 return err;
481 399
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index dc86e4073001..bdc305cece6e 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -51,7 +51,6 @@ source "sound/soc/dwc/Kconfig"
51source "sound/soc/fsl/Kconfig" 51source "sound/soc/fsl/Kconfig"
52source "sound/soc/hisilicon/Kconfig" 52source "sound/soc/hisilicon/Kconfig"
53source "sound/soc/jz4740/Kconfig" 53source "sound/soc/jz4740/Kconfig"
54source "sound/soc/nuc900/Kconfig"
55source "sound/soc/kirkwood/Kconfig" 54source "sound/soc/kirkwood/Kconfig"
56source "sound/soc/img/Kconfig" 55source "sound/soc/img/Kconfig"
57source "sound/soc/intel/Kconfig" 56source "sound/soc/intel/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index d90ce8a32887..861a21b79484 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,5 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-utils.o 2snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-utils.o soc-dai.o soc-component.o
3snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o 3snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o
4snd-soc-core-$(CONFIG_SND_SOC_COMPRESS) += soc-compress.o 4snd-soc-core-$(CONFIG_SND_SOC_COMPRESS) += soc-compress.o
5 5
@@ -39,7 +39,6 @@ obj-$(CONFIG_SND_SOC) += intel/
39obj-$(CONFIG_SND_SOC) += mediatek/ 39obj-$(CONFIG_SND_SOC) += mediatek/
40obj-$(CONFIG_SND_SOC) += meson/ 40obj-$(CONFIG_SND_SOC) += meson/
41obj-$(CONFIG_SND_SOC) += mxs/ 41obj-$(CONFIG_SND_SOC) += mxs/
42obj-$(CONFIG_SND_SOC) += nuc900/
43obj-$(CONFIG_SND_SOC) += kirkwood/ 42obj-$(CONFIG_SND_SOC) += kirkwood/
44obj-$(CONFIG_SND_SOC) += pxa/ 43obj-$(CONFIG_SND_SOC) += pxa/
45obj-$(CONFIG_SND_SOC) += qcom/ 44obj-$(CONFIG_SND_SOC) += qcom/
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
index d26653f81416..52225b4b6382 100644
--- a/sound/soc/amd/acp-pcm-dma.c
+++ b/sound/soc/amd/acp-pcm-dma.c
@@ -1251,8 +1251,7 @@ static int acp_audio_probe(struct platform_device *pdev)
1251 if (!audio_drv_data) 1251 if (!audio_drv_data)
1252 return -ENOMEM; 1252 return -ENOMEM;
1253 1253
1254 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1254 audio_drv_data->acp_mmio = devm_platform_ioremap_resource(pdev, 0);
1255 audio_drv_data->acp_mmio = devm_ioremap_resource(&pdev->dev, res);
1256 if (IS_ERR(audio_drv_data->acp_mmio)) 1255 if (IS_ERR(audio_drv_data->acp_mmio))
1257 return PTR_ERR(audio_drv_data->acp_mmio); 1256 return PTR_ERR(audio_drv_data->acp_mmio);
1258 1257
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 06c1d5ce642c..f118c229ed82 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -12,25 +12,31 @@ if SND_ATMEL_SOC
12config SND_ATMEL_SOC_PDC 12config SND_ATMEL_SOC_PDC
13 tristate 13 tristate
14 depends on HAS_DMA 14 depends on HAS_DMA
15 default m if SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=m
16 default y if SND_ATMEL_SOC_SSC_PDC=y || (SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=y)
17
18config SND_ATMEL_SOC_SSC_PDC
19 tristate
20 15
21config SND_ATMEL_SOC_DMA 16config SND_ATMEL_SOC_DMA
22 tristate 17 tristate
23 select SND_SOC_GENERIC_DMAENGINE_PCM 18 select SND_SOC_GENERIC_DMAENGINE_PCM
24 default m if SND_ATMEL_SOC_SSC_DMA=m && SND_ATMEL_SOC_SSC=m
25 default y if SND_ATMEL_SOC_SSC_DMA=y || (SND_ATMEL_SOC_SSC_DMA=m && SND_ATMEL_SOC_SSC=y)
26
27config SND_ATMEL_SOC_SSC_DMA
28 tristate
29 19
30config SND_ATMEL_SOC_SSC 20config SND_ATMEL_SOC_SSC
31 tristate 21 tristate
32 default y if SND_ATMEL_SOC_SSC_DMA=y || SND_ATMEL_SOC_SSC_PDC=y 22
33 default m if SND_ATMEL_SOC_SSC_DMA=m || SND_ATMEL_SOC_SSC_PDC=m 23config SND_ATMEL_SOC_SSC_PDC
24 tristate "SoC PCM DAI support for AT91 SSC controller using PDC"
25 depends on ATMEL_SSC
26 select SND_ATMEL_SOC_PDC
27 select SND_ATMEL_SOC_SSC
28 help
29 Say Y or M if you want to add support for Atmel SSC interface
30 in PDC mode configured using audio-graph-card in device-tree.
31
32config SND_ATMEL_SOC_SSC_DMA
33 tristate "SoC PCM DAI support for AT91 SSC controller using DMA"
34 depends on ATMEL_SSC
35 select SND_ATMEL_SOC_DMA
36 select SND_ATMEL_SOC_SSC
37 help
38 Say Y or M if you want to add support for Atmel SSC interface
39 in DMA mode configured using audio-graph-card in device-tree.
34 40
35config SND_AT91_SOC_SAM9G20_WM8731 41config SND_AT91_SOC_SAM9G20_WM8731
36 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" 42 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c
index 0f2c574f27f1..e98601eccfa3 100644
--- a/sound/soc/atmel/atmel-classd.c
+++ b/sound/soc/atmel/atmel-classd.c
@@ -571,11 +571,8 @@ static int atmel_classd_probe(struct platform_device *pdev)
571 dd->pdata = pdata; 571 dd->pdata = pdata;
572 572
573 dd->irq = platform_get_irq(pdev, 0); 573 dd->irq = platform_get_irq(pdev, 0);
574 if (dd->irq < 0) { 574 if (dd->irq < 0)
575 ret = dd->irq; 575 return dd->irq;
576 dev_err(dev, "failed to could not get irq: %d\n", ret);
577 return ret;
578 }
579 576
580 dd->pclk = devm_clk_get(dev, "pclk"); 577 dd->pclk = devm_clk_get(dev, "pclk");
581 if (IS_ERR(dd->pclk)) { 578 if (IS_ERR(dd->pclk)) {
diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c
index e09c28349e0d..04ec6f0af179 100644
--- a/sound/soc/atmel/atmel-pdmic.c
+++ b/sound/soc/atmel/atmel-pdmic.c
@@ -612,11 +612,8 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
612 dd->dev = dev; 612 dd->dev = dev;
613 613
614 dd->irq = platform_get_irq(pdev, 0); 614 dd->irq = platform_get_irq(pdev, 0);
615 if (dd->irq < 0) { 615 if (dd->irq < 0)
616 ret = dd->irq; 616 return dd->irq;
617 dev_err(dev, "failed to get irq: %d\n", ret);
618 return ret;
619 }
620 617
621 dd->pclk = devm_clk_get(dev, "pclk"); 618 dd->pclk = devm_clk_get(dev, "pclk");
622 if (IS_ERR(dd->pclk)) { 619 if (IS_ERR(dd->pclk)) {
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 6f89483ac88c..48e9eef34c0f 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -471,7 +471,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
471 int dir, channels, bits; 471 int dir, channels, bits;
472 u32 tfmr, rfmr, tcmr, rcmr; 472 u32 tfmr, rfmr, tcmr, rcmr;
473 int ret; 473 int ret;
474 int fslen, fslen_ext; 474 int fslen, fslen_ext, fs_osync, fs_edge;
475 u32 cmr_div; 475 u32 cmr_div;
476 u32 tcmr_period; 476 u32 tcmr_period;
477 u32 rcmr_period; 477 u32 rcmr_period;
@@ -558,226 +558,45 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
558 /* 558 /*
559 * Compute SSC register settings. 559 * Compute SSC register settings.
560 */ 560 */
561 switch (ssc_p->daifmt
562 & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
563 561
564 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS: 562 fslen_ext = (bits - 1) / 16;
565 /* 563 fslen = (bits - 1) % 16;
566 * I2S format, SSC provides BCLK and LRC clocks.
567 *
568 * The SSC transmit and receive clocks are generated
569 * from the MCK divider, and the BCLK signal
570 * is output on the SSC TK line.
571 */
572 564
573 if (bits > 16 && !ssc->pdata->has_fslen_ext) { 565 switch (ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {
574 dev_err(dai->dev,
575 "sample size %d is too large for SSC device\n",
576 bits);
577 return -EINVAL;
578 }
579 566
580 fslen_ext = (bits - 1) / 16; 567 case SND_SOC_DAIFMT_LEFT_J:
581 fslen = (bits - 1) % 16; 568 fs_osync = SSC_FSOS_POSITIVE;
582 569 fs_edge = SSC_START_RISING_RF;
583 rcmr = SSC_BF(RCMR_PERIOD, rcmr_period) 570
584 | SSC_BF(RCMR_STTDLY, START_DELAY) 571 rcmr = SSC_BF(RCMR_STTDLY, 0);
585 | SSC_BF(RCMR_START, SSC_START_FALLING_RF) 572 tcmr = SSC_BF(TCMR_STTDLY, 0);
586 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
587 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
588 | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
589
590 rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext)
591 | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
592 | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
593 | SSC_BF(RFMR_FSLEN, fslen)
594 | SSC_BF(RFMR_DATNB, (channels - 1))
595 | SSC_BIT(RFMR_MSBF)
596 | SSC_BF(RFMR_LOOP, 0)
597 | SSC_BF(RFMR_DATLEN, (bits - 1));
598
599 tcmr = SSC_BF(TCMR_PERIOD, tcmr_period)
600 | SSC_BF(TCMR_STTDLY, START_DELAY)
601 | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
602 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
603 | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
604 | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
605
606 tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext)
607 | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
608 | SSC_BF(TFMR_FSDEN, 0)
609 | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
610 | SSC_BF(TFMR_FSLEN, fslen)
611 | SSC_BF(TFMR_DATNB, (channels - 1))
612 | SSC_BIT(TFMR_MSBF)
613 | SSC_BF(TFMR_DATDEF, 0)
614 | SSC_BF(TFMR_DATLEN, (bits - 1));
615 break;
616 573
617 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
618 /* I2S format, CODEC supplies BCLK and LRC clocks. */
619 rcmr = SSC_BF(RCMR_PERIOD, 0)
620 | SSC_BF(RCMR_STTDLY, START_DELAY)
621 | SSC_BF(RCMR_START, SSC_START_FALLING_RF)
622 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
623 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
624 | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
625 SSC_CKS_PIN : SSC_CKS_CLOCK);
626
627 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
628 | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
629 | SSC_BF(RFMR_FSLEN, 0)
630 | SSC_BF(RFMR_DATNB, (channels - 1))
631 | SSC_BIT(RFMR_MSBF)
632 | SSC_BF(RFMR_LOOP, 0)
633 | SSC_BF(RFMR_DATLEN, (bits - 1));
634
635 tcmr = SSC_BF(TCMR_PERIOD, 0)
636 | SSC_BF(TCMR_STTDLY, START_DELAY)
637 | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
638 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
639 | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
640 | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?
641 SSC_CKS_CLOCK : SSC_CKS_PIN);
642
643 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
644 | SSC_BF(TFMR_FSDEN, 0)
645 | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
646 | SSC_BF(TFMR_FSLEN, 0)
647 | SSC_BF(TFMR_DATNB, (channels - 1))
648 | SSC_BIT(TFMR_MSBF)
649 | SSC_BF(TFMR_DATDEF, 0)
650 | SSC_BF(TFMR_DATLEN, (bits - 1));
651 break; 574 break;
652 575
653 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFS: 576 case SND_SOC_DAIFMT_I2S:
654 /* I2S format, CODEC supplies BCLK, SSC supplies LRCLK. */ 577 fs_osync = SSC_FSOS_NEGATIVE;
655 if (bits > 16 && !ssc->pdata->has_fslen_ext) { 578 fs_edge = SSC_START_FALLING_RF;
656 dev_err(dai->dev,
657 "sample size %d is too large for SSC device\n",
658 bits);
659 return -EINVAL;
660 }
661 579
662 fslen_ext = (bits - 1) / 16; 580 rcmr = SSC_BF(RCMR_STTDLY, 1);
663 fslen = (bits - 1) % 16; 581 tcmr = SSC_BF(TCMR_STTDLY, 1);
664
665 rcmr = SSC_BF(RCMR_PERIOD, rcmr_period)
666 | SSC_BF(RCMR_STTDLY, START_DELAY)
667 | SSC_BF(RCMR_START, SSC_START_FALLING_RF)
668 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
669 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
670 | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
671 SSC_CKS_PIN : SSC_CKS_CLOCK);
672
673 rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext)
674 | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
675 | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
676 | SSC_BF(RFMR_FSLEN, fslen)
677 | SSC_BF(RFMR_DATNB, (channels - 1))
678 | SSC_BIT(RFMR_MSBF)
679 | SSC_BF(RFMR_LOOP, 0)
680 | SSC_BF(RFMR_DATLEN, (bits - 1));
681
682 tcmr = SSC_BF(TCMR_PERIOD, tcmr_period)
683 | SSC_BF(TCMR_STTDLY, START_DELAY)
684 | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
685 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
686 | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
687 | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?
688 SSC_CKS_CLOCK : SSC_CKS_PIN);
689
690 tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext)
691 | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_NEGATIVE)
692 | SSC_BF(TFMR_FSDEN, 0)
693 | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
694 | SSC_BF(TFMR_FSLEN, fslen)
695 | SSC_BF(TFMR_DATNB, (channels - 1))
696 | SSC_BIT(TFMR_MSBF)
697 | SSC_BF(TFMR_DATDEF, 0)
698 | SSC_BF(TFMR_DATLEN, (bits - 1));
699 break;
700 582
701 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
702 /*
703 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
704 *
705 * The SSC transmit and receive clocks are generated from the
706 * MCK divider, and the BCLK signal is output
707 * on the SSC TK line.
708 */
709 rcmr = SSC_BF(RCMR_PERIOD, rcmr_period)
710 | SSC_BF(RCMR_STTDLY, 1)
711 | SSC_BF(RCMR_START, SSC_START_RISING_RF)
712 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
713 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
714 | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
715
716 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
717 | SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE)
718 | SSC_BF(RFMR_FSLEN, 0)
719 | SSC_BF(RFMR_DATNB, (channels - 1))
720 | SSC_BIT(RFMR_MSBF)
721 | SSC_BF(RFMR_LOOP, 0)
722 | SSC_BF(RFMR_DATLEN, (bits - 1));
723
724 tcmr = SSC_BF(TCMR_PERIOD, tcmr_period)
725 | SSC_BF(TCMR_STTDLY, 1)
726 | SSC_BF(TCMR_START, SSC_START_RISING_RF)
727 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
728 | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
729 | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
730
731 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
732 | SSC_BF(TFMR_FSDEN, 0)
733 | SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE)
734 | SSC_BF(TFMR_FSLEN, 0)
735 | SSC_BF(TFMR_DATNB, (channels - 1))
736 | SSC_BIT(TFMR_MSBF)
737 | SSC_BF(TFMR_DATDEF, 0)
738 | SSC_BF(TFMR_DATLEN, (bits - 1));
739 break; 583 break;
740 584
741 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM: 585 case SND_SOC_DAIFMT_DSP_A:
742 /* 586 /*
743 * DSP/PCM Mode A format, CODEC supplies BCLK and LRC clocks. 587 * DSP/PCM Mode A format
744 * 588 *
745 * Data is transferred on first BCLK after LRC pulse rising 589 * Data is transferred on first BCLK after LRC pulse rising
746 * edge.If stereo, the right channel data is contiguous with 590 * edge.If stereo, the right channel data is contiguous with
747 * the left channel data. 591 * the left channel data.
748 */ 592 */
749 rcmr = SSC_BF(RCMR_PERIOD, 0) 593 fs_osync = SSC_FSOS_POSITIVE;
750 | SSC_BF(RCMR_STTDLY, START_DELAY) 594 fs_edge = SSC_START_RISING_RF;
751 | SSC_BF(RCMR_START, SSC_START_RISING_RF) 595 fslen = fslen_ext = 0;
752 | SSC_BF(RCMR_CKI, SSC_CKI_RISING) 596
753 | SSC_BF(RCMR_CKO, SSC_CKO_NONE) 597 rcmr = SSC_BF(RCMR_STTDLY, 1);
754 | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? 598 tcmr = SSC_BF(TCMR_STTDLY, 1);
755 SSC_CKS_PIN : SSC_CKS_CLOCK); 599
756
757 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
758 | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
759 | SSC_BF(RFMR_FSLEN, 0)
760 | SSC_BF(RFMR_DATNB, (channels - 1))
761 | SSC_BIT(RFMR_MSBF)
762 | SSC_BF(RFMR_LOOP, 0)
763 | SSC_BF(RFMR_DATLEN, (bits - 1));
764
765 tcmr = SSC_BF(TCMR_PERIOD, 0)
766 | SSC_BF(TCMR_STTDLY, START_DELAY)
767 | SSC_BF(TCMR_START, SSC_START_RISING_RF)
768 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
769 | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
770 | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
771 SSC_CKS_CLOCK : SSC_CKS_PIN);
772
773 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
774 | SSC_BF(TFMR_FSDEN, 0)
775 | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
776 | SSC_BF(TFMR_FSLEN, 0)
777 | SSC_BF(TFMR_DATNB, (channels - 1))
778 | SSC_BIT(TFMR_MSBF)
779 | SSC_BF(TFMR_DATDEF, 0)
780 | SSC_BF(TFMR_DATLEN, (bits - 1));
781 break; 600 break;
782 601
783 default: 602 default:
@@ -785,6 +604,70 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
785 ssc_p->daifmt); 604 ssc_p->daifmt);
786 return -EINVAL; 605 return -EINVAL;
787 } 606 }
607
608 if (!atmel_ssc_cfs(ssc_p)) {
609 fslen = fslen_ext = 0;
610 rcmr_period = tcmr_period = 0;
611 fs_osync = SSC_FSOS_NONE;
612 }
613
614 rcmr |= SSC_BF(RCMR_START, fs_edge);
615 tcmr |= SSC_BF(TCMR_START, fs_edge);
616
617 if (atmel_ssc_cbs(ssc_p)) {
618 /*
619 * SSC provides BCLK
620 *
621 * The SSC transmit and receive clocks are generated from the
622 * MCK divider, and the BCLK signal is output
623 * on the SSC TK line.
624 */
625 rcmr |= SSC_BF(RCMR_CKS, SSC_CKS_DIV)
626 | SSC_BF(RCMR_CKO, SSC_CKO_NONE);
627
628 tcmr |= SSC_BF(TCMR_CKS, SSC_CKS_DIV)
629 | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS);
630 } else {
631 rcmr |= SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
632 SSC_CKS_PIN : SSC_CKS_CLOCK)
633 | SSC_BF(RCMR_CKO, SSC_CKO_NONE);
634
635 tcmr |= SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?
636 SSC_CKS_CLOCK : SSC_CKS_PIN)
637 | SSC_BF(TCMR_CKO, SSC_CKO_NONE);
638 }
639
640 rcmr |= SSC_BF(RCMR_PERIOD, rcmr_period)
641 | SSC_BF(RCMR_CKI, SSC_CKI_RISING);
642
643 tcmr |= SSC_BF(TCMR_PERIOD, tcmr_period)
644 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING);
645
646 rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext)
647 | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
648 | SSC_BF(RFMR_FSOS, fs_osync)
649 | SSC_BF(RFMR_FSLEN, fslen)
650 | SSC_BF(RFMR_DATNB, (channels - 1))
651 | SSC_BIT(RFMR_MSBF)
652 | SSC_BF(RFMR_LOOP, 0)
653 | SSC_BF(RFMR_DATLEN, (bits - 1));
654
655 tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext)
656 | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
657 | SSC_BF(TFMR_FSDEN, 0)
658 | SSC_BF(TFMR_FSOS, fs_osync)
659 | SSC_BF(TFMR_FSLEN, fslen)
660 | SSC_BF(TFMR_DATNB, (channels - 1))
661 | SSC_BIT(TFMR_MSBF)
662 | SSC_BF(TFMR_DATDEF, 0)
663 | SSC_BF(TFMR_DATLEN, (bits - 1));
664
665 if (fslen_ext && !ssc->pdata->has_fslen_ext) {
666 dev_err(dai->dev, "sample size %d is too large for SSC device\n",
667 bits);
668 return -EINVAL;
669 }
670
788 pr_debug("atmel_ssc_hw_params: " 671 pr_debug("atmel_ssc_hw_params: "
789 "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", 672 "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
790 rcmr, rfmr, tcmr, tfmr); 673 rcmr, rfmr, tcmr, tfmr);
diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c
index ab7d5f98e759..befc2a3a05b0 100644
--- a/sound/soc/atmel/mchp-i2s-mcc.c
+++ b/sound/soc/atmel/mchp-i2s-mcc.c
@@ -392,11 +392,11 @@ static int mchp_i2s_mcc_clk_get_rate_diff(struct clk *clk,
392} 392}
393 393
394static int mchp_i2s_mcc_config_divs(struct mchp_i2s_mcc_dev *dev, 394static int mchp_i2s_mcc_config_divs(struct mchp_i2s_mcc_dev *dev,
395 unsigned int bclk, unsigned int *mra) 395 unsigned int bclk, unsigned int *mra,
396 unsigned long *best_rate)
396{ 397{
397 unsigned long clk_rate; 398 unsigned long clk_rate;
398 unsigned long lcm_rate; 399 unsigned long lcm_rate;
399 unsigned long best_rate = 0;
400 unsigned long best_diff_rate = ~0; 400 unsigned long best_diff_rate = ~0;
401 unsigned int sysclk; 401 unsigned int sysclk;
402 struct clk *best_clk = NULL; 402 struct clk *best_clk = NULL;
@@ -423,7 +423,7 @@ static int mchp_i2s_mcc_config_divs(struct mchp_i2s_mcc_dev *dev,
423 (clk_rate == bclk || clk_rate / (bclk * 2) <= GENMASK(5, 0)); 423 (clk_rate == bclk || clk_rate / (bclk * 2) <= GENMASK(5, 0));
424 clk_rate += lcm_rate) { 424 clk_rate += lcm_rate) {
425 ret = mchp_i2s_mcc_clk_get_rate_diff(dev->gclk, clk_rate, 425 ret = mchp_i2s_mcc_clk_get_rate_diff(dev->gclk, clk_rate,
426 &best_clk, &best_rate, 426 &best_clk, best_rate,
427 &best_diff_rate); 427 &best_diff_rate);
428 if (ret) { 428 if (ret) {
429 dev_err(dev->dev, "gclk error for rate %lu: %d", 429 dev_err(dev->dev, "gclk error for rate %lu: %d",
@@ -437,7 +437,7 @@ static int mchp_i2s_mcc_config_divs(struct mchp_i2s_mcc_dev *dev,
437 } 437 }
438 438
439 ret = mchp_i2s_mcc_clk_get_rate_diff(dev->pclk, clk_rate, 439 ret = mchp_i2s_mcc_clk_get_rate_diff(dev->pclk, clk_rate,
440 &best_clk, &best_rate, 440 &best_clk, best_rate,
441 &best_diff_rate); 441 &best_diff_rate);
442 if (ret) { 442 if (ret) {
443 dev_err(dev->dev, "pclk error for rate %lu: %d", 443 dev_err(dev->dev, "pclk error for rate %lu: %d",
@@ -459,33 +459,17 @@ static int mchp_i2s_mcc_config_divs(struct mchp_i2s_mcc_dev *dev,
459 459
460 dev_dbg(dev->dev, "source CLK is %s with rate %lu, diff %lu\n", 460 dev_dbg(dev->dev, "source CLK is %s with rate %lu, diff %lu\n",
461 best_clk == dev->pclk ? "pclk" : "gclk", 461 best_clk == dev->pclk ? "pclk" : "gclk",
462 best_rate, best_diff_rate); 462 *best_rate, best_diff_rate);
463
464 /* set the rate */
465 ret = clk_set_rate(best_clk, best_rate);
466 if (ret) {
467 dev_err(dev->dev, "unable to set rate %lu to %s: %d\n",
468 best_rate, best_clk == dev->pclk ? "PCLK" : "GCLK",
469 ret);
470 return ret;
471 }
472 463
473 /* Configure divisors */ 464 /* Configure divisors */
474 if (dev->sysclk) 465 if (dev->sysclk)
475 *mra |= MCHP_I2SMCC_MRA_IMCKDIV(best_rate / (2 * sysclk)); 466 *mra |= MCHP_I2SMCC_MRA_IMCKDIV(*best_rate / (2 * sysclk));
476 *mra |= MCHP_I2SMCC_MRA_ISCKDIV(best_rate / (2 * bclk)); 467 *mra |= MCHP_I2SMCC_MRA_ISCKDIV(*best_rate / (2 * bclk));
477 468
478 if (best_clk == dev->gclk) { 469 if (best_clk == dev->gclk)
479 *mra |= MCHP_I2SMCC_MRA_SRCCLK_GCLK; 470 *mra |= MCHP_I2SMCC_MRA_SRCCLK_GCLK;
480 ret = clk_prepare(dev->gclk); 471 else
481 if (ret < 0)
482 dev_err(dev->dev, "unable to prepare GCLK: %d\n", ret);
483 else
484 dev->gclk_use = 1;
485 } else {
486 *mra |= MCHP_I2SMCC_MRA_SRCCLK_PCLK; 472 *mra |= MCHP_I2SMCC_MRA_SRCCLK_PCLK;
487 dev->gclk_use = 0;
488 }
489 473
490 return 0; 474 return 0;
491} 475}
@@ -502,6 +486,7 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
502 struct snd_pcm_hw_params *params, 486 struct snd_pcm_hw_params *params,
503 struct snd_soc_dai *dai) 487 struct snd_soc_dai *dai)
504{ 488{
489 unsigned long rate = 0;
505 struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai); 490 struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai);
506 u32 mra = 0; 491 u32 mra = 0;
507 u32 mrb = 0; 492 u32 mrb = 0;
@@ -640,6 +625,17 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
640 return -EINVAL; 625 return -EINVAL;
641 } 626 }
642 627
628 if (set_divs) {
629 bclk_rate = frame_length * params_rate(params);
630 ret = mchp_i2s_mcc_config_divs(dev, bclk_rate, &mra,
631 &rate);
632 if (ret) {
633 dev_err(dev->dev,
634 "unable to configure the divisors: %d\n", ret);
635 return ret;
636 }
637 }
638
643 /* 639 /*
644 * If we are already running, the wanted setup must be 640 * If we are already running, the wanted setup must be
645 * the same with the one that's currently ongoing 641 * the same with the one that's currently ongoing
@@ -656,19 +652,27 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
656 return 0; 652 return 0;
657 } 653 }
658 654
659 /* Save the number of channels to know what interrupts to enable */ 655 if (mra & MCHP_I2SMCC_MRA_SRCCLK_GCLK && !dev->gclk_use) {
660 dev->channels = channels; 656 /* set the rate */
661 657 ret = clk_set_rate(dev->gclk, rate);
662 if (set_divs) {
663 bclk_rate = frame_length * params_rate(params);
664 ret = mchp_i2s_mcc_config_divs(dev, bclk_rate, &mra);
665 if (ret) { 658 if (ret) {
666 dev_err(dev->dev, "unable to configure the divisors: %d\n", 659 dev_err(dev->dev,
667 ret); 660 "unable to set rate %lu to GCLK: %d\n",
661 rate, ret);
662 return ret;
663 }
664
665 ret = clk_prepare(dev->gclk);
666 if (ret < 0) {
667 dev_err(dev->dev, "unable to prepare GCLK: %d\n", ret);
668 return ret; 668 return ret;
669 } 669 }
670 dev->gclk_use = 1;
670 } 671 }
671 672
673 /* Save the number of channels to know what interrupts to enable */
674 dev->channels = channels;
675
672 ret = regmap_write(dev->regmap, MCHP_I2SMCC_MRA, mra); 676 ret = regmap_write(dev->regmap, MCHP_I2SMCC_MRA, mra);
673 if (ret < 0) { 677 if (ret < 0) {
674 if (dev->gclk_use) { 678 if (dev->gclk_use) {
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 21e5f6aed7f3..08bc04e2da2a 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -363,7 +363,7 @@ static const struct snd_soc_component_driver au1xpsc_ac97_component = {
363static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) 363static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
364{ 364{
365 int ret; 365 int ret;
366 struct resource *iores, *dmares; 366 struct resource *dmares;
367 unsigned long sel; 367 unsigned long sel;
368 struct au1xpsc_audio_data *wd; 368 struct au1xpsc_audio_data *wd;
369 369
@@ -374,8 +374,7 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
374 374
375 mutex_init(&wd->lock); 375 mutex_init(&wd->lock);
376 376
377 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 377 wd->mmio = devm_platform_ioremap_resource(pdev, 0);
378 wd->mmio = devm_ioremap_resource(&pdev->dev, iores);
379 if (IS_ERR(wd->mmio)) 378 if (IS_ERR(wd->mmio))
380 return PTR_ERR(wd->mmio); 379 return PTR_ERR(wd->mmio);
381 380
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 076303f96b8c..767ce950d0da 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -291,7 +291,7 @@ static const struct snd_soc_component_driver au1xpsc_i2s_component = {
291 291
292static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) 292static int au1xpsc_i2s_drvprobe(struct platform_device *pdev)
293{ 293{
294 struct resource *iores, *dmares; 294 struct resource *dmares;
295 unsigned long sel; 295 unsigned long sel;
296 struct au1xpsc_audio_data *wd; 296 struct au1xpsc_audio_data *wd;
297 297
@@ -300,8 +300,7 @@ static int au1xpsc_i2s_drvprobe(struct platform_device *pdev)
300 if (!wd) 300 if (!wd)
301 return -ENOMEM; 301 return -ENOMEM;
302 302
303 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 303 wd->mmio = devm_platform_ioremap_resource(pdev, 0);
304 wd->mmio = devm_ioremap_resource(&pdev->dev, iores);
305 if (IS_ERR(wd->mmio)) 304 if (IS_ERR(wd->mmio))
306 return PTR_ERR(wd->mmio); 305 return PTR_ERR(wd->mmio);
307 306
diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c
index 5ef80f3d446a..e6a12e271b07 100644
--- a/sound/soc/bcm/bcm2835-i2s.c
+++ b/sound/soc/bcm/bcm2835-i2s.c
@@ -828,7 +828,6 @@ static int bcm2835_i2s_probe(struct platform_device *pdev)
828{ 828{
829 struct bcm2835_i2s_dev *dev; 829 struct bcm2835_i2s_dev *dev;
830 int ret; 830 int ret;
831 struct resource *mem;
832 void __iomem *base; 831 void __iomem *base;
833 const __be32 *addr; 832 const __be32 *addr;
834 dma_addr_t dma_base; 833 dma_addr_t dma_base;
@@ -848,8 +847,7 @@ static int bcm2835_i2s_probe(struct platform_device *pdev)
848 } 847 }
849 848
850 /* Request ioarea */ 849 /* Request ioarea */
851 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 850 base = devm_platform_ioremap_resource(pdev, 0);
852 base = devm_ioremap_resource(&pdev->dev, mem);
853 if (IS_ERR(base)) 851 if (IS_ERR(base))
854 return PTR_ERR(base); 852 return PTR_ERR(base);
855 853
diff --git a/sound/soc/bcm/cygnus-pcm.c b/sound/soc/bcm/cygnus-pcm.c
index 123ecf5479d7..8966b02844dc 100644
--- a/sound/soc/bcm/cygnus-pcm.c
+++ b/sound/soc/bcm/cygnus-pcm.c
@@ -639,7 +639,6 @@ static int cygnus_pcm_hw_params(struct snd_pcm_substream *substream,
639 struct snd_soc_pcm_runtime *rtd = substream->private_data; 639 struct snd_soc_pcm_runtime *rtd = substream->private_data;
640 struct snd_pcm_runtime *runtime = substream->runtime; 640 struct snd_pcm_runtime *runtime = substream->runtime;
641 struct cygnus_aio_port *aio; 641 struct cygnus_aio_port *aio;
642 int ret = 0;
643 642
644 aio = cygnus_dai_get_dma_data(substream); 643 aio = cygnus_dai_get_dma_data(substream);
645 dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum); 644 dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum);
@@ -647,7 +646,7 @@ static int cygnus_pcm_hw_params(struct snd_pcm_substream *substream,
647 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 646 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
648 runtime->dma_bytes = params_buffer_bytes(params); 647 runtime->dma_bytes = params_buffer_bytes(params);
649 648
650 return ret; 649 return 0;
651} 650}
652 651
653static int cygnus_pcm_hw_free(struct snd_pcm_substream *substream) 652static int cygnus_pcm_hw_free(struct snd_pcm_substream *substream)
@@ -668,7 +667,6 @@ static int cygnus_pcm_prepare(struct snd_pcm_substream *substream)
668 struct snd_pcm_runtime *runtime = substream->runtime; 667 struct snd_pcm_runtime *runtime = substream->runtime;
669 struct cygnus_aio_port *aio; 668 struct cygnus_aio_port *aio;
670 unsigned long bufsize, periodsize; 669 unsigned long bufsize, periodsize;
671 int ret = 0;
672 bool is_play; 670 bool is_play;
673 u32 start; 671 u32 start;
674 struct ringbuf_regs *p_rbuf = NULL; 672 struct ringbuf_regs *p_rbuf = NULL;
@@ -693,7 +691,7 @@ static int cygnus_pcm_prepare(struct snd_pcm_substream *substream)
693 ringbuf_set_initial(aio->cygaud->audio, p_rbuf, is_play, start, 691 ringbuf_set_initial(aio->cygaud->audio, p_rbuf, is_play, start,
694 periodsize, bufsize); 692 periodsize, bufsize);
695 693
696 return ret; 694 return 0;
697} 695}
698 696
699static snd_pcm_uframes_t cygnus_pcm_pointer(struct snd_pcm_substream *substream) 697static snd_pcm_uframes_t cygnus_pcm_pointer(struct snd_pcm_substream *substream)
diff --git a/sound/soc/bcm/cygnus-ssp.c b/sound/soc/bcm/cygnus-ssp.c
index b7c358b48d8d..2f9357d7da96 100644
--- a/sound/soc/bcm/cygnus-ssp.c
+++ b/sound/soc/bcm/cygnus-ssp.c
@@ -1342,11 +1342,8 @@ static int cygnus_ssp_probe(struct platform_device *pdev)
1342 } 1342 }
1343 1343
1344 cygaud->irq_num = platform_get_irq(pdev, 0); 1344 cygaud->irq_num = platform_get_irq(pdev, 0);
1345 if (cygaud->irq_num <= 0) { 1345 if (cygaud->irq_num <= 0)
1346 dev_err(dev, "platform_get_irq failed\n"); 1346 return cygaud->irq_num;
1347 err = cygaud->irq_num;
1348 return err;
1349 }
1350 1347
1351 err = audio_clk_init(pdev, cygaud); 1348 err = audio_clk_init(pdev, cygaud);
1352 if (err) { 1349 if (err) {
diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c
index 84c967fcab6b..e21eaa1893d1 100644
--- a/sound/soc/cirrus/ep93xx-ac97.c
+++ b/sound/soc/cirrus/ep93xx-ac97.c
@@ -362,7 +362,6 @@ static const struct snd_soc_component_driver ep93xx_ac97_component = {
362static int ep93xx_ac97_probe(struct platform_device *pdev) 362static int ep93xx_ac97_probe(struct platform_device *pdev)
363{ 363{
364 struct ep93xx_ac97_info *info; 364 struct ep93xx_ac97_info *info;
365 struct resource *res;
366 int irq; 365 int irq;
367 int ret; 366 int ret;
368 367
@@ -370,8 +369,7 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
370 if (!info) 369 if (!info)
371 return -ENOMEM; 370 return -ENOMEM;
372 371
373 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 372 info->regs = devm_platform_ioremap_resource(pdev, 0);
374 info->regs = devm_ioremap_resource(&pdev->dev, res);
375 if (IS_ERR(info->regs)) 373 if (IS_ERR(info->regs))
376 return PTR_ERR(info->regs); 374 return PTR_ERR(info->regs);
377 375
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index 0b4355e95f84..7d9cf67129d4 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -430,15 +430,13 @@ static const struct snd_soc_component_driver ep93xx_i2s_component = {
430static int ep93xx_i2s_probe(struct platform_device *pdev) 430static int ep93xx_i2s_probe(struct platform_device *pdev)
431{ 431{
432 struct ep93xx_i2s_info *info; 432 struct ep93xx_i2s_info *info;
433 struct resource *res;
434 int err; 433 int err;
435 434
436 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 435 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
437 if (!info) 436 if (!info)
438 return -ENOMEM; 437 return -ENOMEM;
439 438
440 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 439 info->regs = devm_platform_ioremap_resource(pdev, 0);
441 info->regs = devm_ioremap_resource(&pdev->dev, res);
442 if (IS_ERR(info->regs)) 440 if (IS_ERR(info->regs))
443 return PTR_ERR(info->regs); 441 return PTR_ERR(info->regs);
444 442
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index e982722b448e..00b2c43d28a1 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -529,10 +529,6 @@ static const struct snd_kcontrol_new pm860x_snd_controls[] = {
529 * DAPM Controls 529 * DAPM Controls
530 */ 530 */
531 531
532/* PCM Switch / PCM Interface */
533static const struct snd_kcontrol_new pcm_switch_controls =
534 SOC_DAPM_SINGLE("Switch", PM860X_ADC_EN_2, 0, 1, 0);
535
536/* AUX1 Switch */ 532/* AUX1 Switch */
537static const struct snd_kcontrol_new aux1_switch_controls = 533static const struct snd_kcontrol_new aux1_switch_controls =
538 SOC_DAPM_SINGLE("Switch", PM860X_ANA_TO_ANA, 4, 1, 0); 534 SOC_DAPM_SINGLE("Switch", PM860X_ANA_TO_ANA, 4, 1, 0);
@@ -549,17 +545,6 @@ static const struct snd_kcontrol_new lepa_switch_controls =
549static const struct snd_kcontrol_new repa_switch_controls = 545static const struct snd_kcontrol_new repa_switch_controls =
550 SOC_DAPM_SINGLE("Switch", PM860X_DAC_EN_2, 1, 1, 0); 546 SOC_DAPM_SINGLE("Switch", PM860X_DAC_EN_2, 1, 1, 0);
551 547
552/* PCM Mux / Mux7 */
553static const char *aif1_text[] = {
554 "PCM L", "PCM R",
555};
556
557static SOC_ENUM_SINGLE_DECL(aif1_enum,
558 PM860X_PCM_IFACE_3, 6, aif1_text);
559
560static const struct snd_kcontrol_new aif1_mux =
561 SOC_DAPM_ENUM("PCM Mux", aif1_enum);
562
563/* I2S Mux / Mux9 */ 548/* I2S Mux / Mux9 */
564static const char *i2s_din_text[] = { 549static const char *i2s_din_text[] = {
565 "DIN", "DIN1", 550 "DIN", "DIN1",
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 9f89a5346299..89238343e34d 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -70,10 +70,12 @@ config SND_SOC_ALL_CODECS
70 select SND_SOC_CS43130 if I2C 70 select SND_SOC_CS43130 if I2C
71 select SND_SOC_CS4341 if SND_SOC_I2C_AND_SPI 71 select SND_SOC_CS4341 if SND_SOC_I2C_AND_SPI
72 select SND_SOC_CS4349 if I2C 72 select SND_SOC_CS4349 if I2C
73 select SND_SOC_CS47L15 if MFD_CS47L15
73 select SND_SOC_CS47L24 if MFD_CS47L24 74 select SND_SOC_CS47L24 if MFD_CS47L24
74 select SND_SOC_CS47L35 if MFD_CS47L35 75 select SND_SOC_CS47L35 if MFD_CS47L35
75 select SND_SOC_CS47L85 if MFD_CS47L85 76 select SND_SOC_CS47L85 if MFD_CS47L85
76 select SND_SOC_CS47L90 if MFD_CS47L90 77 select SND_SOC_CS47L90 if MFD_CS47L90
78 select SND_SOC_CS47L92 if MFD_CS47L92
77 select SND_SOC_CS53L30 if I2C 79 select SND_SOC_CS53L30 if I2C
78 select SND_SOC_CX20442 if TTY 80 select SND_SOC_CX20442 if TTY
79 select SND_SOC_CX2072X if I2C 81 select SND_SOC_CX2072X if I2C
@@ -197,6 +199,7 @@ config SND_SOC_ALL_CODECS
197 select SND_SOC_TS3A227E if I2C 199 select SND_SOC_TS3A227E if I2C
198 select SND_SOC_TWL4030 if TWL4030_CORE 200 select SND_SOC_TWL4030 if TWL4030_CORE
199 select SND_SOC_TWL6040 if TWL6040_CORE 201 select SND_SOC_TWL6040 if TWL6040_CORE
202 select SND_SOC_UDA1334 if GPIOLIB
200 select SND_SOC_UDA134X 203 select SND_SOC_UDA134X
201 select SND_SOC_UDA1380 if I2C 204 select SND_SOC_UDA1380 if I2C
202 select SND_SOC_WCD9335 if SLIMBUS 205 select SND_SOC_WCD9335 if SLIMBUS
@@ -581,6 +584,9 @@ config SND_SOC_CS4349
581 tristate "Cirrus Logic CS4349 CODEC" 584 tristate "Cirrus Logic CS4349 CODEC"
582 depends on I2C 585 depends on I2C
583 586
587config SND_SOC_CS47L15
588 tristate
589
584config SND_SOC_CS47L24 590config SND_SOC_CS47L24
585 tristate 591 tristate
586 592
@@ -593,6 +599,9 @@ config SND_SOC_CS47L85
593config SND_SOC_CS47L90 599config SND_SOC_CS47L90
594 tristate 600 tristate
595 601
602config SND_SOC_CS47L92
603 tristate
604
596# Cirrus Logic Quad-Channel ADC 605# Cirrus Logic Quad-Channel ADC
597config SND_SOC_CS53L30 606config SND_SOC_CS53L30
598 tristate "Cirrus Logic CS53L30 CODEC" 607 tristate "Cirrus Logic CS53L30 CODEC"
@@ -722,12 +731,16 @@ config SND_SOC_LOCHNAGAR_SC
722 731
723config SND_SOC_MADERA 732config SND_SOC_MADERA
724 tristate 733 tristate
734 default y if SND_SOC_CS47L15=y
725 default y if SND_SOC_CS47L35=y 735 default y if SND_SOC_CS47L35=y
726 default y if SND_SOC_CS47L85=y 736 default y if SND_SOC_CS47L85=y
727 default y if SND_SOC_CS47L90=y 737 default y if SND_SOC_CS47L90=y
738 default y if SND_SOC_CS47L92=y
739 default m if SND_SOC_CS47L15=m
728 default m if SND_SOC_CS47L35=m 740 default m if SND_SOC_CS47L35=m
729 default m if SND_SOC_CS47L85=m 741 default m if SND_SOC_CS47L85=m
730 default m if SND_SOC_CS47L90=m 742 default m if SND_SOC_CS47L90=m
743 default m if SND_SOC_CS47L92=m
731 744
732config SND_SOC_MAX98088 745config SND_SOC_MAX98088
733 tristate "Maxim MAX98088/9 Low-Power, Stereo Audio Codec" 746 tristate "Maxim MAX98088/9 Low-Power, Stereo Audio Codec"
@@ -1195,6 +1208,14 @@ config SND_SOC_TWL4030
1195config SND_SOC_TWL6040 1208config SND_SOC_TWL6040
1196 tristate 1209 tristate
1197 1210
1211config SND_SOC_UDA1334
1212 tristate "NXP UDA1334 DAC"
1213 depends on GPIOLIB
1214 help
1215 The UDA1334 is an NXP audio codec, supports the I2S-bus data format
1216 and has basic features such as de-emphasis (at 44.1 kHz sampling
1217 rate) and mute.
1218
1198config SND_SOC_UDA134X 1219config SND_SOC_UDA134X
1199 tristate 1220 tristate
1200 1221
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 5b4bb8cf4325..c498373dcc5f 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -64,10 +64,12 @@ snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
64snd-soc-cs43130-objs := cs43130.o 64snd-soc-cs43130-objs := cs43130.o
65snd-soc-cs4341-objs := cs4341.o 65snd-soc-cs4341-objs := cs4341.o
66snd-soc-cs4349-objs := cs4349.o 66snd-soc-cs4349-objs := cs4349.o
67snd-soc-cs47l15-objs := cs47l15.o
67snd-soc-cs47l24-objs := cs47l24.o 68snd-soc-cs47l24-objs := cs47l24.o
68snd-soc-cs47l35-objs := cs47l35.o 69snd-soc-cs47l35-objs := cs47l35.o
69snd-soc-cs47l85-objs := cs47l85.o 70snd-soc-cs47l85-objs := cs47l85.o
70snd-soc-cs47l90-objs := cs47l90.o 71snd-soc-cs47l90-objs := cs47l90.o
72snd-soc-cs47l92-objs := cs47l92.o
71snd-soc-cs53l30-objs := cs53l30.o 73snd-soc-cs53l30-objs := cs53l30.o
72snd-soc-cx20442-objs := cx20442.o 74snd-soc-cx20442-objs := cx20442.o
73snd-soc-cx2072x-objs := cx2072x.o 75snd-soc-cx2072x-objs := cx2072x.o
@@ -210,6 +212,7 @@ snd-soc-tscs454-objs := tscs454.o
210snd-soc-ts3a227e-objs := ts3a227e.o 212snd-soc-ts3a227e-objs := ts3a227e.o
211snd-soc-twl4030-objs := twl4030.o 213snd-soc-twl4030-objs := twl4030.o
212snd-soc-twl6040-objs := twl6040.o 214snd-soc-twl6040-objs := twl6040.o
215snd-soc-uda1334-objs := uda1334.o
213snd-soc-uda134x-objs := uda134x.o 216snd-soc-uda134x-objs := uda134x.o
214snd-soc-uda1380-objs := uda1380.o 217snd-soc-uda1380-objs := uda1380.o
215snd-soc-wcd9335-objs := wcd-clsh-v2.o wcd9335.o 218snd-soc-wcd9335-objs := wcd-clsh-v2.o wcd9335.o
@@ -346,9 +349,11 @@ obj-$(CONFIG_SND_SOC_CS43130) += snd-soc-cs43130.o
346obj-$(CONFIG_SND_SOC_CS4341) += snd-soc-cs4341.o 349obj-$(CONFIG_SND_SOC_CS4341) += snd-soc-cs4341.o
347obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o 350obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o
348obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o 351obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o
352obj-$(CONFIG_SND_SOC_CS47L15) += snd-soc-cs47l15.o
349obj-$(CONFIG_SND_SOC_CS47L35) += snd-soc-cs47l35.o 353obj-$(CONFIG_SND_SOC_CS47L35) += snd-soc-cs47l35.o
350obj-$(CONFIG_SND_SOC_CS47L85) += snd-soc-cs47l85.o 354obj-$(CONFIG_SND_SOC_CS47L85) += snd-soc-cs47l85.o
351obj-$(CONFIG_SND_SOC_CS47L90) += snd-soc-cs47l90.o 355obj-$(CONFIG_SND_SOC_CS47L90) += snd-soc-cs47l90.o
356obj-$(CONFIG_SND_SOC_CS47L92) += snd-soc-cs47l92.o
352obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o 357obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o
353obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 358obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
354obj-$(CONFIG_SND_SOC_CX2072X) += snd-soc-cx2072x.o 359obj-$(CONFIG_SND_SOC_CX2072X) += snd-soc-cx2072x.o
@@ -490,6 +495,7 @@ obj-$(CONFIG_SND_SOC_TSCS454) += snd-soc-tscs454.o
490obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o 495obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o
491obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 496obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
492obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o 497obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
498obj-$(CONFIG_SND_SOC_UDA1334) += snd-soc-uda1334.o
493obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 499obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
494obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 500obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
495obj-$(CONFIG_SND_SOC_WCD9335) += snd-soc-wcd9335.o 501obj-$(CONFIG_SND_SOC_WCD9335) += snd-soc-wcd9335.o
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 80dab5df9633..980e024a5720 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -413,15 +413,10 @@ static struct snd_soc_dai_driver ad193x_no_adc_dai = {
413 .ops = &ad193x_dai_ops, 413 .ops = &ad193x_dai_ops,
414}; 414};
415 415
416struct ad193x_reg_default {
417 unsigned int reg;
418 unsigned int val;
419};
420
421/* codec register values to set after reset */ 416/* codec register values to set after reset */
422static void ad193x_reg_default_init(struct ad193x_priv *ad193x) 417static void ad193x_reg_default_init(struct ad193x_priv *ad193x)
423{ 418{
424 const struct ad193x_reg_default reg_init[] = { 419 static const struct reg_sequence reg_init[] = {
425 { 0, 0x99 }, /* PLL_CLK_CTRL0: pll input: mclki/xi 12.288Mhz */ 420 { 0, 0x99 }, /* PLL_CLK_CTRL0: pll input: mclki/xi 12.288Mhz */
426 { 1, 0x04 }, /* PLL_CLK_CTRL1: no on-chip Vref */ 421 { 1, 0x04 }, /* PLL_CLK_CTRL1: no on-chip Vref */
427 { 2, 0x40 }, /* DAC_CTRL0: TDM mode */ 422 { 2, 0x40 }, /* DAC_CTRL0: TDM mode */
@@ -437,21 +432,17 @@ static void ad193x_reg_default_init(struct ad193x_priv *ad193x)
437 { 12, 0x00 }, /* DAC_L4_VOL: no attenuation */ 432 { 12, 0x00 }, /* DAC_L4_VOL: no attenuation */
438 { 13, 0x00 }, /* DAC_R4_VOL: no attenuation */ 433 { 13, 0x00 }, /* DAC_R4_VOL: no attenuation */
439 }; 434 };
440 const struct ad193x_reg_default reg_adc_init[] = { 435 static const struct reg_sequence reg_adc_init[] = {
441 { 14, 0x03 }, /* ADC_CTRL0: high-pass filter enable */ 436 { 14, 0x03 }, /* ADC_CTRL0: high-pass filter enable */
442 { 15, 0x43 }, /* ADC_CTRL1: sata delay=1, adc aux mode */ 437 { 15, 0x43 }, /* ADC_CTRL1: sata delay=1, adc aux mode */
443 { 16, 0x00 }, /* ADC_CTRL2: reset */ 438 { 16, 0x00 }, /* ADC_CTRL2: reset */
444 }; 439 };
445 int i;
446 440
447 for (i = 0; i < ARRAY_SIZE(reg_init); i++) 441 regmap_multi_reg_write(ad193x->regmap, reg_init, ARRAY_SIZE(reg_init));
448 regmap_write(ad193x->regmap, reg_init[i].reg, reg_init[i].val);
449 442
450 if (ad193x_has_adc(ad193x)) { 443 if (ad193x_has_adc(ad193x)) {
451 for (i = 0; i < ARRAY_SIZE(reg_adc_init); i++) { 444 regmap_multi_reg_write(ad193x->regmap, reg_adc_init,
452 regmap_write(ad193x->regmap, reg_adc_init[i].reg, 445 ARRAY_SIZE(reg_adc_init));
453 reg_adc_init[i].val);
454 }
455 } 446 }
456} 447}
457 448
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 1d03a1348162..04b86a51e055 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -334,7 +334,7 @@ static struct cs4271_clk_cfg cs4271_clk_tab[] = {
334 {0, CS4271_MODE1_MODE_4X, 256, CS4271_MODE1_DIV_2}, 334 {0, CS4271_MODE1_MODE_4X, 256, CS4271_MODE1_DIV_2},
335}; 335};
336 336
337#define CS4171_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab) 337#define CS4271_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab)
338 338
339static int cs4271_hw_params(struct snd_pcm_substream *substream, 339static int cs4271_hw_params(struct snd_pcm_substream *substream,
340 struct snd_pcm_hw_params *params, 340 struct snd_pcm_hw_params *params,
@@ -383,13 +383,13 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
383 val = CS4271_MODE1_MODE_4X; 383 val = CS4271_MODE1_MODE_4X;
384 384
385 ratio = cs4271->mclk / cs4271->rate; 385 ratio = cs4271->mclk / cs4271->rate;
386 for (i = 0; i < CS4171_NR_RATIOS; i++) 386 for (i = 0; i < CS4271_NR_RATIOS; i++)
387 if ((cs4271_clk_tab[i].master == cs4271->master) && 387 if ((cs4271_clk_tab[i].master == cs4271->master) &&
388 (cs4271_clk_tab[i].speed_mode == val) && 388 (cs4271_clk_tab[i].speed_mode == val) &&
389 (cs4271_clk_tab[i].ratio == ratio)) 389 (cs4271_clk_tab[i].ratio == ratio))
390 break; 390 break;
391 391
392 if (i == CS4171_NR_RATIOS) { 392 if (i == CS4271_NR_RATIOS) {
393 dev_err(component->dev, "Invalid sample rate\n"); 393 dev_err(component->dev, "Invalid sample rate\n");
394 return -EINVAL; 394 return -EINVAL;
395 } 395 }
diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c
index b4d7627525f9..ac569ab3d30f 100644
--- a/sound/soc/codecs/cs42l56.c
+++ b/sound/soc/codecs/cs42l56.c
@@ -199,14 +199,6 @@ static const struct soc_enum beep_bass_enum =
199 SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 1, 199 SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 1,
200 ARRAY_SIZE(beep_bass_text), beep_bass_text); 200 ARRAY_SIZE(beep_bass_text), beep_bass_text);
201 201
202static const char * const adc_swap_text[] = {
203 "None", "A+B/2", "A-B/2", "Swap"
204};
205
206static const struct soc_enum adc_swap_enum =
207 SOC_ENUM_SINGLE(CS42L56_MISC_ADC_CTL, 3,
208 ARRAY_SIZE(adc_swap_text), adc_swap_text);
209
210static const char * const pgaa_mux_text[] = { 202static const char * const pgaa_mux_text[] = {
211 "AIN1A", "AIN2A", "AIN3A"}; 203 "AIN1A", "AIN2A", "AIN3A"};
212 204
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index a81739367109..36089f8bcf0a 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -273,12 +273,6 @@ static SOC_ENUM_SINGLE_DECL(xsp_output_mux_enum,
273 CS42L73_MIXERCTL, 4, 273 CS42L73_MIXERCTL, 4,
274 cs42l73_spo_mixer_text); 274 cs42l73_spo_mixer_text);
275 275
276static const struct snd_kcontrol_new vsp_output_mux =
277 SOC_DAPM_ENUM("Route", vsp_output_mux_enum);
278
279static const struct snd_kcontrol_new xsp_output_mux =
280 SOC_DAPM_ENUM("Route", xsp_output_mux_enum);
281
282static const struct snd_kcontrol_new hp_amp_ctl = 276static const struct snd_kcontrol_new hp_amp_ctl =
283 SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 0, 1, 1); 277 SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 0, 1, 1);
284 278
diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c
index 5b049fcdba20..94b1adb088fd 100644
--- a/sound/soc/codecs/cs42xx8.c
+++ b/sound/soc/codecs/cs42xx8.c
@@ -684,6 +684,8 @@ static int cs42xx8_runtime_suspend(struct device *dev)
684#endif 684#endif
685 685
686const struct dev_pm_ops cs42xx8_pm = { 686const struct dev_pm_ops cs42xx8_pm = {
687 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
688 pm_runtime_force_resume)
687 SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL) 689 SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL)
688}; 690};
689EXPORT_SYMBOL_GPL(cs42xx8_pm); 691EXPORT_SYMBOL_GPL(cs42xx8_pm);
diff --git a/sound/soc/codecs/cs47l15.c b/sound/soc/codecs/cs47l15.c
new file mode 100644
index 000000000000..ece1276f38eb
--- /dev/null
+++ b/sound/soc/codecs/cs47l15.c
@@ -0,0 +1,1490 @@
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// ALSA SoC Audio driver for CS47L15 codec
4//
5// Copyright (C) 2016-2019 Cirrus Logic, Inc. and
6// Cirrus Logic International Semiconductor Ltd.
7//
8
9#include <linux/module.h>
10#include <linux/moduleparam.h>
11#include <linux/device.h>
12#include <linux/delay.h>
13#include <linux/init.h>
14#include <linux/pm.h>
15#include <linux/pm_runtime.h>
16#include <linux/regmap.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/tlv.h>
22
23#include <linux/irqchip/irq-madera.h>
24#include <linux/mfd/madera/core.h>
25#include <linux/mfd/madera/registers.h>
26
27#include "madera.h"
28#include "wm_adsp.h"
29
30#define CS47L15_NUM_ADSP 1
31#define CS47L15_MONO_OUTPUTS 1
32
33/* Mid-mode registers */
34#define CS47L15_ADC_INT_BIAS_MASK 0x3800
35#define CS47L15_ADC_INT_BIAS_SHIFT 11
36#define CS47L15_PGA_BIAS_SEL_MASK 0x03
37#define CS47L15_PGA_BIAS_SEL_SHIFT 0
38
39#define DRV_NAME "cs47l15-codec"
40
41struct cs47l15 {
42 struct madera_priv core;
43 struct madera_fll fll[2];
44
45 bool in1_lp_mode;
46};
47
48static const struct wm_adsp_region cs47l15_dsp1_regions[] = {
49 { .type = WMFW_ADSP2_PM, .base = 0x080000 },
50 { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 },
51 { .type = WMFW_ADSP2_XM, .base = 0x0a0000 },
52 { .type = WMFW_ADSP2_YM, .base = 0x0c0000 },
53};
54
55static const char * const cs47l15_outdemux_texts[] = {
56 "HPOUT",
57 "EPOUT",
58};
59
60static SOC_ENUM_SINGLE_DECL(cs47l15_outdemux_enum, SND_SOC_NOPM, 0,
61 cs47l15_outdemux_texts);
62
63static const struct snd_kcontrol_new cs47l15_outdemux =
64 SOC_DAPM_ENUM_EXT("HPOUT1 Demux", cs47l15_outdemux_enum,
65 madera_out1_demux_get, madera_out1_demux_put);
66
67static int cs47l15_adsp_power_ev(struct snd_soc_dapm_widget *w,
68 struct snd_kcontrol *kcontrol,
69 int event)
70{
71 struct snd_soc_component *component =
72 snd_soc_dapm_to_component(w->dapm);
73 struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
74 struct madera_priv *priv = &cs47l15->core;
75 struct madera *madera = priv->madera;
76 unsigned int freq;
77 int ret;
78
79 ret = regmap_read(madera->regmap, MADERA_DSP_CLOCK_2, &freq);
80 if (ret != 0) {
81 dev_err(madera->dev,
82 "Failed to read MADERA_DSP_CLOCK_2: %d\n", ret);
83 return ret;
84 }
85
86 switch (event) {
87 case SND_SOC_DAPM_PRE_PMU:
88 ret = madera_set_adsp_clk(&cs47l15->core, w->shift, freq);
89 if (ret)
90 return ret;
91 break;
92 default:
93 break;
94 }
95
96 return wm_adsp_early_event(w, kcontrol, event);
97}
98
99#define CS47L15_NG_SRC(name, base) \
100 SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \
101 SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \
102 SOC_SINGLE(name " NG SPKOUTL Switch", base, 6, 1, 0), \
103 SOC_SINGLE(name " NG SPKDAT1L Switch", base, 8, 1, 0), \
104 SOC_SINGLE(name " NG SPKDAT1R Switch", base, 9, 1, 0)
105
106static int cs47l15_in1_adc_get(struct snd_kcontrol *kcontrol,
107 struct snd_ctl_elem_value *ucontrol)
108{
109 struct snd_soc_component *component =
110 snd_soc_kcontrol_component(kcontrol);
111 struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
112
113 ucontrol->value.integer.value[0] = !!cs47l15->in1_lp_mode;
114
115 return 0;
116}
117
118static int cs47l15_in1_adc_put(struct snd_kcontrol *kcontrol,
119 struct snd_ctl_elem_value *ucontrol)
120{
121 struct snd_soc_component *component =
122 snd_soc_kcontrol_component(kcontrol);
123 struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
124
125 switch (ucontrol->value.integer.value[0]) {
126 case 0:
127 /* Set IN1 to normal mode */
128 snd_soc_component_update_bits(component, MADERA_DMIC1L_CONTROL,
129 MADERA_IN1_OSR_MASK,
130 5 << MADERA_IN1_OSR_SHIFT);
131 snd_soc_component_update_bits(component, CS47L15_ADC_INT_BIAS,
132 CS47L15_ADC_INT_BIAS_MASK,
133 4 << CS47L15_ADC_INT_BIAS_SHIFT);
134 snd_soc_component_update_bits(component, CS47L15_PGA_BIAS_SEL,
135 CS47L15_PGA_BIAS_SEL_MASK, 0);
136 cs47l15->in1_lp_mode = false;
137 break;
138 default:
139 /* Set IN1 to LP mode */
140 snd_soc_component_update_bits(component, MADERA_DMIC1L_CONTROL,
141 MADERA_IN1_OSR_MASK,
142 4 << MADERA_IN1_OSR_SHIFT);
143 snd_soc_component_update_bits(component, CS47L15_ADC_INT_BIAS,
144 CS47L15_ADC_INT_BIAS_MASK,
145 1 << CS47L15_ADC_INT_BIAS_SHIFT);
146 snd_soc_component_update_bits(component, CS47L15_PGA_BIAS_SEL,
147 CS47L15_PGA_BIAS_SEL_MASK,
148 3 << CS47L15_PGA_BIAS_SEL_SHIFT);
149 cs47l15->in1_lp_mode = true;
150 break;
151 }
152
153 return 0;
154}
155
156static const struct snd_kcontrol_new cs47l15_snd_controls[] = {
157SOC_ENUM("IN1 OSR", madera_in_dmic_osr[0]),
158SOC_ENUM("IN2 OSR", madera_in_dmic_osr[1]),
159
160SOC_SINGLE_RANGE_TLV("IN1L Volume", MADERA_IN1L_CONTROL,
161 MADERA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
162SOC_SINGLE_RANGE_TLV("IN1R Volume", MADERA_IN1R_CONTROL,
163 MADERA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
164
165SOC_ENUM("IN HPF Cutoff Frequency", madera_in_hpf_cut_enum),
166
167SOC_SINGLE("IN1L HPF Switch", MADERA_IN1L_CONTROL, MADERA_IN1L_HPF_SHIFT, 1, 0),
168SOC_SINGLE("IN1R HPF Switch", MADERA_IN1R_CONTROL, MADERA_IN1R_HPF_SHIFT, 1, 0),
169SOC_SINGLE("IN2L HPF Switch", MADERA_IN2L_CONTROL, MADERA_IN2L_HPF_SHIFT, 1, 0),
170SOC_SINGLE("IN2R HPF Switch", MADERA_IN2R_CONTROL, MADERA_IN2R_HPF_SHIFT, 1, 0),
171
172SOC_SINGLE_TLV("IN1L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1L,
173 MADERA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
174SOC_SINGLE_TLV("IN1R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1R,
175 MADERA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
176SOC_SINGLE_TLV("IN2L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2L,
177 MADERA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
178SOC_SINGLE_TLV("IN2R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2R,
179 MADERA_IN2R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
180
181SOC_ENUM("Input Ramp Up", madera_in_vi_ramp),
182SOC_ENUM("Input Ramp Down", madera_in_vd_ramp),
183
184MADERA_MIXER_CONTROLS("EQ1", MADERA_EQ1MIX_INPUT_1_SOURCE),
185MADERA_MIXER_CONTROLS("EQ2", MADERA_EQ2MIX_INPUT_1_SOURCE),
186MADERA_MIXER_CONTROLS("EQ3", MADERA_EQ3MIX_INPUT_1_SOURCE),
187MADERA_MIXER_CONTROLS("EQ4", MADERA_EQ4MIX_INPUT_1_SOURCE),
188
189MADERA_EQ_CONTROL("EQ1 Coefficients", MADERA_EQ1_2),
190SOC_SINGLE_TLV("EQ1 B1 Volume", MADERA_EQ1_1, MADERA_EQ1_B1_GAIN_SHIFT,
191 24, 0, madera_eq_tlv),
192SOC_SINGLE_TLV("EQ1 B2 Volume", MADERA_EQ1_1, MADERA_EQ1_B2_GAIN_SHIFT,
193 24, 0, madera_eq_tlv),
194SOC_SINGLE_TLV("EQ1 B3 Volume", MADERA_EQ1_1, MADERA_EQ1_B3_GAIN_SHIFT,
195 24, 0, madera_eq_tlv),
196SOC_SINGLE_TLV("EQ1 B4 Volume", MADERA_EQ1_2, MADERA_EQ1_B4_GAIN_SHIFT,
197 24, 0, madera_eq_tlv),
198SOC_SINGLE_TLV("EQ1 B5 Volume", MADERA_EQ1_2, MADERA_EQ1_B5_GAIN_SHIFT,
199 24, 0, madera_eq_tlv),
200
201MADERA_EQ_CONTROL("EQ2 Coefficients", MADERA_EQ2_2),
202SOC_SINGLE_TLV("EQ2 B1 Volume", MADERA_EQ2_1, MADERA_EQ2_B1_GAIN_SHIFT,
203 24, 0, madera_eq_tlv),
204SOC_SINGLE_TLV("EQ2 B2 Volume", MADERA_EQ2_1, MADERA_EQ2_B2_GAIN_SHIFT,
205 24, 0, madera_eq_tlv),
206SOC_SINGLE_TLV("EQ2 B3 Volume", MADERA_EQ2_1, MADERA_EQ2_B3_GAIN_SHIFT,
207 24, 0, madera_eq_tlv),
208SOC_SINGLE_TLV("EQ2 B4 Volume", MADERA_EQ2_2, MADERA_EQ2_B4_GAIN_SHIFT,
209 24, 0, madera_eq_tlv),
210SOC_SINGLE_TLV("EQ2 B5 Volume", MADERA_EQ2_2, MADERA_EQ2_B5_GAIN_SHIFT,
211 24, 0, madera_eq_tlv),
212
213MADERA_EQ_CONTROL("EQ3 Coefficients", MADERA_EQ3_2),
214SOC_SINGLE_TLV("EQ3 B1 Volume", MADERA_EQ3_1, MADERA_EQ3_B1_GAIN_SHIFT,
215 24, 0, madera_eq_tlv),
216SOC_SINGLE_TLV("EQ3 B2 Volume", MADERA_EQ3_1, MADERA_EQ3_B2_GAIN_SHIFT,
217 24, 0, madera_eq_tlv),
218SOC_SINGLE_TLV("EQ3 B3 Volume", MADERA_EQ3_1, MADERA_EQ3_B3_GAIN_SHIFT,
219 24, 0, madera_eq_tlv),
220SOC_SINGLE_TLV("EQ3 B4 Volume", MADERA_EQ3_2, MADERA_EQ3_B4_GAIN_SHIFT,
221 24, 0, madera_eq_tlv),
222SOC_SINGLE_TLV("EQ3 B5 Volume", MADERA_EQ3_2, MADERA_EQ3_B5_GAIN_SHIFT,
223 24, 0, madera_eq_tlv),
224
225MADERA_EQ_CONTROL("EQ4 Coefficients", MADERA_EQ4_2),
226SOC_SINGLE_TLV("EQ4 B1 Volume", MADERA_EQ4_1, MADERA_EQ4_B1_GAIN_SHIFT,
227 24, 0, madera_eq_tlv),
228SOC_SINGLE_TLV("EQ4 B2 Volume", MADERA_EQ4_1, MADERA_EQ4_B2_GAIN_SHIFT,
229 24, 0, madera_eq_tlv),
230SOC_SINGLE_TLV("EQ4 B3 Volume", MADERA_EQ4_1, MADERA_EQ4_B3_GAIN_SHIFT,
231 24, 0, madera_eq_tlv),
232SOC_SINGLE_TLV("EQ4 B4 Volume", MADERA_EQ4_2, MADERA_EQ4_B4_GAIN_SHIFT,
233 24, 0, madera_eq_tlv),
234SOC_SINGLE_TLV("EQ4 B5 Volume", MADERA_EQ4_2, MADERA_EQ4_B5_GAIN_SHIFT,
235 24, 0, madera_eq_tlv),
236
237MADERA_MIXER_CONTROLS("DRC1L", MADERA_DRC1LMIX_INPUT_1_SOURCE),
238MADERA_MIXER_CONTROLS("DRC1R", MADERA_DRC1RMIX_INPUT_1_SOURCE),
239MADERA_MIXER_CONTROLS("DRC2L", MADERA_DRC2LMIX_INPUT_1_SOURCE),
240MADERA_MIXER_CONTROLS("DRC2R", MADERA_DRC2RMIX_INPUT_1_SOURCE),
241
242SND_SOC_BYTES_MASK("DRC1", MADERA_DRC1_CTRL1, 5,
243 MADERA_DRC1R_ENA | MADERA_DRC1L_ENA),
244SND_SOC_BYTES_MASK("DRC2", MADERA_DRC2_CTRL1, 5,
245 MADERA_DRC2R_ENA | MADERA_DRC2L_ENA),
246
247MADERA_MIXER_CONTROLS("LHPF1", MADERA_HPLP1MIX_INPUT_1_SOURCE),
248MADERA_MIXER_CONTROLS("LHPF2", MADERA_HPLP2MIX_INPUT_1_SOURCE),
249MADERA_MIXER_CONTROLS("LHPF3", MADERA_HPLP3MIX_INPUT_1_SOURCE),
250MADERA_MIXER_CONTROLS("LHPF4", MADERA_HPLP4MIX_INPUT_1_SOURCE),
251
252MADERA_LHPF_CONTROL("LHPF1 Coefficients", MADERA_HPLPF1_2),
253MADERA_LHPF_CONTROL("LHPF2 Coefficients", MADERA_HPLPF2_2),
254MADERA_LHPF_CONTROL("LHPF3 Coefficients", MADERA_HPLPF3_2),
255MADERA_LHPF_CONTROL("LHPF4 Coefficients", MADERA_HPLPF4_2),
256
257SOC_ENUM("LHPF1 Mode", madera_lhpf1_mode),
258SOC_ENUM("LHPF2 Mode", madera_lhpf2_mode),
259SOC_ENUM("LHPF3 Mode", madera_lhpf3_mode),
260SOC_ENUM("LHPF4 Mode", madera_lhpf4_mode),
261
262MADERA_RATE_ENUM("ISRC1 FSL", madera_isrc_fsl[0]),
263MADERA_RATE_ENUM("ISRC2 FSL", madera_isrc_fsl[1]),
264MADERA_RATE_ENUM("ISRC1 FSH", madera_isrc_fsh[0]),
265MADERA_RATE_ENUM("ISRC2 FSH", madera_isrc_fsh[1]),
266
267WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
268
269MADERA_MIXER_CONTROLS("DSP1L", MADERA_DSP1LMIX_INPUT_1_SOURCE),
270MADERA_MIXER_CONTROLS("DSP1R", MADERA_DSP1RMIX_INPUT_1_SOURCE),
271
272SOC_SINGLE_TLV("Noise Generator Volume", MADERA_COMFORT_NOISE_GENERATOR,
273 MADERA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, madera_noise_tlv),
274
275MADERA_MIXER_CONTROLS("HPOUT1L", MADERA_OUT1LMIX_INPUT_1_SOURCE),
276MADERA_MIXER_CONTROLS("HPOUT1R", MADERA_OUT1RMIX_INPUT_1_SOURCE),
277MADERA_MIXER_CONTROLS("SPKOUTL", MADERA_OUT4LMIX_INPUT_1_SOURCE),
278MADERA_MIXER_CONTROLS("SPKDAT1L", MADERA_OUT5LMIX_INPUT_1_SOURCE),
279MADERA_MIXER_CONTROLS("SPKDAT1R", MADERA_OUT5RMIX_INPUT_1_SOURCE),
280
281SOC_SINGLE("HPOUT1 SC Protect Switch", MADERA_HP1_SHORT_CIRCUIT_CTRL,
282 MADERA_HP1_SC_ENA_SHIFT, 1, 0),
283
284SOC_SINGLE("SPKDAT1 High Performance Switch", MADERA_OUTPUT_PATH_CONFIG_5L,
285 MADERA_OUT5_OSR_SHIFT, 1, 0),
286
287SOC_DOUBLE_R("HPOUT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_1L,
288 MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_MUTE_SHIFT, 1, 1),
289SOC_SINGLE("Speaker Digital Switch", MADERA_DAC_DIGITAL_VOLUME_4L,
290 MADERA_OUT4L_MUTE_SHIFT, 1, 1),
291SOC_DOUBLE_R("SPKDAT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_5L,
292 MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_MUTE_SHIFT, 1, 1),
293
294SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_1L,
295 MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_VOL_SHIFT,
296 0xbf, 0, madera_digital_tlv),
297SOC_SINGLE_TLV("Speaker Digital Volume", MADERA_DAC_DIGITAL_VOLUME_4L,
298 MADERA_OUT4L_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
299SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_5L,
300 MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_VOL_SHIFT,
301 0xbf, 0, madera_digital_tlv),
302
303SOC_DOUBLE("SPKDAT1 Switch", MADERA_PDM_SPK1_CTRL_1, MADERA_SPK1L_MUTE_SHIFT,
304 MADERA_SPK1R_MUTE_SHIFT, 1, 1),
305
306SOC_ENUM("Output Ramp Up", madera_out_vi_ramp),
307SOC_ENUM("Output Ramp Down", madera_out_vd_ramp),
308
309SOC_SINGLE("Noise Gate Switch", MADERA_NOISE_GATE_CONTROL,
310 MADERA_NGATE_ENA_SHIFT, 1, 0),
311SOC_SINGLE_TLV("Noise Gate Threshold Volume", MADERA_NOISE_GATE_CONTROL,
312 MADERA_NGATE_THR_SHIFT, 7, 1, madera_ng_tlv),
313SOC_ENUM("Noise Gate Hold", madera_ng_hold),
314
315SOC_SINGLE_BOOL_EXT("IN1 LP Mode Switch", 0,
316 cs47l15_in1_adc_get, cs47l15_in1_adc_put),
317
318CS47L15_NG_SRC("HPOUT1L", MADERA_NOISE_GATE_SELECT_1L),
319CS47L15_NG_SRC("HPOUT1R", MADERA_NOISE_GATE_SELECT_1R),
320CS47L15_NG_SRC("SPKOUTL", MADERA_NOISE_GATE_SELECT_4L),
321CS47L15_NG_SRC("SPKDAT1L", MADERA_NOISE_GATE_SELECT_5L),
322CS47L15_NG_SRC("SPKDAT1R", MADERA_NOISE_GATE_SELECT_5R),
323
324MADERA_MIXER_CONTROLS("AIF1TX1", MADERA_AIF1TX1MIX_INPUT_1_SOURCE),
325MADERA_MIXER_CONTROLS("AIF1TX2", MADERA_AIF1TX2MIX_INPUT_1_SOURCE),
326MADERA_MIXER_CONTROLS("AIF1TX3", MADERA_AIF1TX3MIX_INPUT_1_SOURCE),
327MADERA_MIXER_CONTROLS("AIF1TX4", MADERA_AIF1TX4MIX_INPUT_1_SOURCE),
328MADERA_MIXER_CONTROLS("AIF1TX5", MADERA_AIF1TX5MIX_INPUT_1_SOURCE),
329MADERA_MIXER_CONTROLS("AIF1TX6", MADERA_AIF1TX6MIX_INPUT_1_SOURCE),
330
331MADERA_MIXER_CONTROLS("AIF2TX1", MADERA_AIF2TX1MIX_INPUT_1_SOURCE),
332MADERA_MIXER_CONTROLS("AIF2TX2", MADERA_AIF2TX2MIX_INPUT_1_SOURCE),
333MADERA_MIXER_CONTROLS("AIF2TX3", MADERA_AIF2TX3MIX_INPUT_1_SOURCE),
334MADERA_MIXER_CONTROLS("AIF2TX4", MADERA_AIF2TX4MIX_INPUT_1_SOURCE),
335
336MADERA_MIXER_CONTROLS("AIF3TX1", MADERA_AIF3TX1MIX_INPUT_1_SOURCE),
337MADERA_MIXER_CONTROLS("AIF3TX2", MADERA_AIF3TX2MIX_INPUT_1_SOURCE),
338
339MADERA_GAINMUX_CONTROLS("SPDIF1TX1", MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE),
340MADERA_GAINMUX_CONTROLS("SPDIF1TX2", MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE),
341
342WM_ADSP_FW_CONTROL("DSP1", 0),
343};
344
345MADERA_MIXER_ENUMS(EQ1, MADERA_EQ1MIX_INPUT_1_SOURCE);
346MADERA_MIXER_ENUMS(EQ2, MADERA_EQ2MIX_INPUT_1_SOURCE);
347MADERA_MIXER_ENUMS(EQ3, MADERA_EQ3MIX_INPUT_1_SOURCE);
348MADERA_MIXER_ENUMS(EQ4, MADERA_EQ4MIX_INPUT_1_SOURCE);
349
350MADERA_MIXER_ENUMS(DRC1L, MADERA_DRC1LMIX_INPUT_1_SOURCE);
351MADERA_MIXER_ENUMS(DRC1R, MADERA_DRC1RMIX_INPUT_1_SOURCE);
352MADERA_MIXER_ENUMS(DRC2L, MADERA_DRC2LMIX_INPUT_1_SOURCE);
353MADERA_MIXER_ENUMS(DRC2R, MADERA_DRC2RMIX_INPUT_1_SOURCE);
354
355MADERA_MIXER_ENUMS(LHPF1, MADERA_HPLP1MIX_INPUT_1_SOURCE);
356MADERA_MIXER_ENUMS(LHPF2, MADERA_HPLP2MIX_INPUT_1_SOURCE);
357MADERA_MIXER_ENUMS(LHPF3, MADERA_HPLP3MIX_INPUT_1_SOURCE);
358MADERA_MIXER_ENUMS(LHPF4, MADERA_HPLP4MIX_INPUT_1_SOURCE);
359
360MADERA_MIXER_ENUMS(DSP1L, MADERA_DSP1LMIX_INPUT_1_SOURCE);
361MADERA_MIXER_ENUMS(DSP1R, MADERA_DSP1RMIX_INPUT_1_SOURCE);
362MADERA_DSP_AUX_ENUMS(DSP1, MADERA_DSP1AUX1MIX_INPUT_1_SOURCE);
363
364MADERA_MIXER_ENUMS(PWM1, MADERA_PWM1MIX_INPUT_1_SOURCE);
365MADERA_MIXER_ENUMS(PWM2, MADERA_PWM2MIX_INPUT_1_SOURCE);
366
367MADERA_MIXER_ENUMS(OUT1L, MADERA_OUT1LMIX_INPUT_1_SOURCE);
368MADERA_MIXER_ENUMS(OUT1R, MADERA_OUT1RMIX_INPUT_1_SOURCE);
369MADERA_MIXER_ENUMS(SPKOUTL, MADERA_OUT4LMIX_INPUT_1_SOURCE);
370MADERA_MIXER_ENUMS(SPKDAT1L, MADERA_OUT5LMIX_INPUT_1_SOURCE);
371MADERA_MIXER_ENUMS(SPKDAT1R, MADERA_OUT5RMIX_INPUT_1_SOURCE);
372
373MADERA_MIXER_ENUMS(AIF1TX1, MADERA_AIF1TX1MIX_INPUT_1_SOURCE);
374MADERA_MIXER_ENUMS(AIF1TX2, MADERA_AIF1TX2MIX_INPUT_1_SOURCE);
375MADERA_MIXER_ENUMS(AIF1TX3, MADERA_AIF1TX3MIX_INPUT_1_SOURCE);
376MADERA_MIXER_ENUMS(AIF1TX4, MADERA_AIF1TX4MIX_INPUT_1_SOURCE);
377MADERA_MIXER_ENUMS(AIF1TX5, MADERA_AIF1TX5MIX_INPUT_1_SOURCE);
378MADERA_MIXER_ENUMS(AIF1TX6, MADERA_AIF1TX6MIX_INPUT_1_SOURCE);
379
380MADERA_MIXER_ENUMS(AIF2TX1, MADERA_AIF2TX1MIX_INPUT_1_SOURCE);
381MADERA_MIXER_ENUMS(AIF2TX2, MADERA_AIF2TX2MIX_INPUT_1_SOURCE);
382MADERA_MIXER_ENUMS(AIF2TX3, MADERA_AIF2TX3MIX_INPUT_1_SOURCE);
383MADERA_MIXER_ENUMS(AIF2TX4, MADERA_AIF2TX4MIX_INPUT_1_SOURCE);
384
385MADERA_MIXER_ENUMS(AIF3TX1, MADERA_AIF3TX1MIX_INPUT_1_SOURCE);
386MADERA_MIXER_ENUMS(AIF3TX2, MADERA_AIF3TX2MIX_INPUT_1_SOURCE);
387
388MADERA_MUX_ENUMS(SPD1TX1, MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE);
389MADERA_MUX_ENUMS(SPD1TX2, MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE);
390
391MADERA_MUX_ENUMS(ISRC1INT1, MADERA_ISRC1INT1MIX_INPUT_1_SOURCE);
392MADERA_MUX_ENUMS(ISRC1INT2, MADERA_ISRC1INT2MIX_INPUT_1_SOURCE);
393MADERA_MUX_ENUMS(ISRC1INT3, MADERA_ISRC1INT3MIX_INPUT_1_SOURCE);
394MADERA_MUX_ENUMS(ISRC1INT4, MADERA_ISRC1INT4MIX_INPUT_1_SOURCE);
395
396MADERA_MUX_ENUMS(ISRC1DEC1, MADERA_ISRC1DEC1MIX_INPUT_1_SOURCE);
397MADERA_MUX_ENUMS(ISRC1DEC2, MADERA_ISRC1DEC2MIX_INPUT_1_SOURCE);
398MADERA_MUX_ENUMS(ISRC1DEC3, MADERA_ISRC1DEC3MIX_INPUT_1_SOURCE);
399MADERA_MUX_ENUMS(ISRC1DEC4, MADERA_ISRC1DEC4MIX_INPUT_1_SOURCE);
400
401MADERA_MUX_ENUMS(ISRC2INT1, MADERA_ISRC2INT1MIX_INPUT_1_SOURCE);
402MADERA_MUX_ENUMS(ISRC2INT2, MADERA_ISRC2INT2MIX_INPUT_1_SOURCE);
403MADERA_MUX_ENUMS(ISRC2INT3, MADERA_ISRC2INT3MIX_INPUT_1_SOURCE);
404MADERA_MUX_ENUMS(ISRC2INT4, MADERA_ISRC2INT4MIX_INPUT_1_SOURCE);
405
406MADERA_MUX_ENUMS(ISRC2DEC1, MADERA_ISRC2DEC1MIX_INPUT_1_SOURCE);
407MADERA_MUX_ENUMS(ISRC2DEC2, MADERA_ISRC2DEC2MIX_INPUT_1_SOURCE);
408MADERA_MUX_ENUMS(ISRC2DEC3, MADERA_ISRC2DEC3MIX_INPUT_1_SOURCE);
409MADERA_MUX_ENUMS(ISRC2DEC4, MADERA_ISRC2DEC4MIX_INPUT_1_SOURCE);
410
411static const char * const cs47l15_aec_loopback_texts[] = {
412 "HPOUT1L", "HPOUT1R", "SPKOUTL", "SPKDAT1L", "SPKDAT1R",
413};
414
415static const unsigned int cs47l15_aec_loopback_values[] = {
416 0, 1, 6, 8, 9,
417};
418
419static const struct soc_enum cs47l15_aec1_loopback =
420 SOC_VALUE_ENUM_SINGLE(MADERA_DAC_AEC_CONTROL_1,
421 MADERA_AEC1_LOOPBACK_SRC_SHIFT, 0xf,
422 ARRAY_SIZE(cs47l15_aec_loopback_texts),
423 cs47l15_aec_loopback_texts,
424 cs47l15_aec_loopback_values);
425
426static const struct soc_enum cs47l15_aec2_loopback =
427 SOC_VALUE_ENUM_SINGLE(MADERA_DAC_AEC_CONTROL_2,
428 MADERA_AEC2_LOOPBACK_SRC_SHIFT, 0xf,
429 ARRAY_SIZE(cs47l15_aec_loopback_texts),
430 cs47l15_aec_loopback_texts,
431 cs47l15_aec_loopback_values);
432
433static const struct snd_kcontrol_new cs47l15_aec_loopback_mux[] = {
434 SOC_DAPM_ENUM("AEC1 Loopback", cs47l15_aec1_loopback),
435 SOC_DAPM_ENUM("AEC2 Loopback", cs47l15_aec2_loopback),
436};
437
438static const struct snd_soc_dapm_widget cs47l15_dapm_widgets[] = {
439SND_SOC_DAPM_SUPPLY("SYSCLK", MADERA_SYSTEM_CLOCK_1, MADERA_SYSCLK_ENA_SHIFT,
440 0, madera_sysclk_ev,
441 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
442SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK,
443 MADERA_OPCLK_ENA_SHIFT, 0, NULL, 0),
444SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1,
445 MADERA_DSP_CLK_ENA_SHIFT, 0, NULL, 0),
446
447SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD1", 20, 0),
448SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
449SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDD", 0, 0),
450
451SND_SOC_DAPM_SUPPLY("MICBIAS1", MADERA_MIC_BIAS_CTRL_1,
452 MADERA_MICB1_ENA_SHIFT, 0, NULL, 0),
453
454SND_SOC_DAPM_SUPPLY("MICBIAS1A", MADERA_MIC_BIAS_CTRL_5,
455 MADERA_MICB1A_ENA_SHIFT, 0, NULL, 0),
456SND_SOC_DAPM_SUPPLY("MICBIAS1B", MADERA_MIC_BIAS_CTRL_5,
457 MADERA_MICB1B_ENA_SHIFT, 0, NULL, 0),
458SND_SOC_DAPM_SUPPLY("MICBIAS1C", MADERA_MIC_BIAS_CTRL_5,
459 MADERA_MICB1C_ENA_SHIFT, 0, NULL, 0),
460
461SND_SOC_DAPM_SUPPLY("FXCLK", SND_SOC_NOPM,
462 MADERA_DOM_GRP_FX, 0,
463 madera_domain_clk_ev,
464 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
465SND_SOC_DAPM_SUPPLY("ISRC1CLK", SND_SOC_NOPM,
466 MADERA_DOM_GRP_ISRC1, 0,
467 madera_domain_clk_ev,
468 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
469SND_SOC_DAPM_SUPPLY("ISRC2CLK", SND_SOC_NOPM,
470 MADERA_DOM_GRP_ISRC2, 0,
471 madera_domain_clk_ev,
472 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
473SND_SOC_DAPM_SUPPLY("OUTCLK", SND_SOC_NOPM,
474 MADERA_DOM_GRP_OUT, 0,
475 madera_domain_clk_ev,
476 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
477SND_SOC_DAPM_SUPPLY("SPDCLK", SND_SOC_NOPM,
478 MADERA_DOM_GRP_SPD, 0,
479 madera_domain_clk_ev,
480 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
481SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM,
482 MADERA_DOM_GRP_DSP1, 0,
483 madera_domain_clk_ev,
484 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
485SND_SOC_DAPM_SUPPLY("AIF1TXCLK", SND_SOC_NOPM,
486 MADERA_DOM_GRP_AIF1, 0,
487 madera_domain_clk_ev,
488 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
489SND_SOC_DAPM_SUPPLY("AIF2TXCLK", SND_SOC_NOPM,
490 MADERA_DOM_GRP_AIF2, 0,
491 madera_domain_clk_ev,
492 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
493SND_SOC_DAPM_SUPPLY("AIF3TXCLK", SND_SOC_NOPM,
494 MADERA_DOM_GRP_AIF3, 0,
495 madera_domain_clk_ev,
496 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
497SND_SOC_DAPM_SUPPLY("PWMCLK", SND_SOC_NOPM,
498 MADERA_DOM_GRP_PWM, 0,
499 madera_domain_clk_ev,
500 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
501
502SND_SOC_DAPM_SIGGEN("TONE"),
503SND_SOC_DAPM_SIGGEN("NOISE"),
504
505SND_SOC_DAPM_INPUT("IN1ALN"),
506SND_SOC_DAPM_INPUT("IN1ALP"),
507SND_SOC_DAPM_INPUT("IN1BLN"),
508SND_SOC_DAPM_INPUT("IN1BLP"),
509SND_SOC_DAPM_INPUT("IN1ARN"),
510SND_SOC_DAPM_INPUT("IN1ARP"),
511SND_SOC_DAPM_INPUT("IN1BRN"),
512SND_SOC_DAPM_INPUT("IN1BRP"),
513SND_SOC_DAPM_INPUT("IN2N"),
514SND_SOC_DAPM_INPUT("IN2P"),
515SND_SOC_DAPM_INPUT("SPKRXDAT"),
516
517SND_SOC_DAPM_MUX("IN1L Analog Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[0]),
518SND_SOC_DAPM_MUX("IN1R Analog Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[1]),
519
520SND_SOC_DAPM_MUX("IN1L Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[0]),
521SND_SOC_DAPM_MUX("IN1R Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[0]),
522
523SND_SOC_DAPM_MUX("IN2L Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[1]),
524SND_SOC_DAPM_MUX("IN2R Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[1]),
525
526SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
527SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
528
529SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),
530
531SND_SOC_DAPM_DEMUX("HPOUT1 Demux", SND_SOC_NOPM, 0, 0, &cs47l15_outdemux),
532
533SND_SOC_DAPM_PGA("PWM1 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM1_ENA_SHIFT,
534 0, NULL, 0),
535SND_SOC_DAPM_PGA("PWM2 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM2_ENA_SHIFT,
536 0, NULL, 0),
537
538SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
539 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX1_ENA_SHIFT, 0),
540SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
541 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX2_ENA_SHIFT, 0),
542SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
543 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX3_ENA_SHIFT, 0),
544SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
545 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX4_ENA_SHIFT, 0),
546SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
547 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX5_ENA_SHIFT, 0),
548SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
549 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX6_ENA_SHIFT, 0),
550
551SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
552 MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX1_ENA_SHIFT, 0),
553SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
554 MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX2_ENA_SHIFT, 0),
555SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0,
556 MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX3_ENA_SHIFT, 0),
557SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0,
558 MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX4_ENA_SHIFT, 0),
559
560SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
561 MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX1_ENA_SHIFT, 0),
562SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
563 MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX2_ENA_SHIFT, 0),
564
565SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
566 MADERA_OUT1L_ENA_SHIFT, 0, NULL, 0, madera_hp_ev,
567 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
568 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
569SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
570 MADERA_OUT1R_ENA_SHIFT, 0, NULL, 0, madera_hp_ev,
571 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
572 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
573SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
574 MADERA_OUT4L_ENA_SHIFT, 0, NULL, 0, madera_spk_ev,
575 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
576SND_SOC_DAPM_PGA_E("OUT5L", MADERA_OUTPUT_ENABLES_1,
577 MADERA_OUT5L_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
578 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
579SND_SOC_DAPM_PGA_E("OUT5R", MADERA_OUTPUT_ENABLES_1,
580 MADERA_OUT5R_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
581 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
582
583SND_SOC_DAPM_PGA("SPD1TX1", MADERA_SPD1_TX_CONTROL,
584 MADERA_SPD1_VAL1_SHIFT, 0, NULL, 0),
585SND_SOC_DAPM_PGA("SPD1TX2", MADERA_SPD1_TX_CONTROL,
586 MADERA_SPD1_VAL2_SHIFT, 0, NULL, 0),
587SND_SOC_DAPM_OUT_DRV("SPD1", MADERA_SPD1_TX_CONTROL,
588 MADERA_SPD1_ENA_SHIFT, 0, NULL, 0),
589
590/*
591 * mux_in widgets : arranged in the order of sources
592 * specified in MADERA_MIXER_INPUT_ROUTES
593 */
594
595SND_SOC_DAPM_PGA("Noise Generator", MADERA_COMFORT_NOISE_GENERATOR,
596 MADERA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
597
598SND_SOC_DAPM_PGA("Tone Generator 1", MADERA_TONE_GENERATOR_1,
599 MADERA_TONE1_ENA_SHIFT, 0, NULL, 0),
600SND_SOC_DAPM_PGA("Tone Generator 2", MADERA_TONE_GENERATOR_1,
601 MADERA_TONE2_ENA_SHIFT, 0, NULL, 0),
602
603SND_SOC_DAPM_SIGGEN("HAPTICS"),
604
605SND_SOC_DAPM_MUX("AEC1 Loopback", MADERA_DAC_AEC_CONTROL_1,
606 MADERA_AEC1_LOOPBACK_ENA_SHIFT, 0,
607 &cs47l15_aec_loopback_mux[0]),
608SND_SOC_DAPM_MUX("AEC2 Loopback", MADERA_DAC_AEC_CONTROL_2,
609 MADERA_AEC2_LOOPBACK_ENA_SHIFT, 0,
610 &cs47l15_aec_loopback_mux[1]),
611
612SND_SOC_DAPM_PGA_E("IN1L", MADERA_INPUT_ENABLES, MADERA_IN1L_ENA_SHIFT,
613 0, NULL, 0, madera_in_ev,
614 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
615 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
616SND_SOC_DAPM_PGA_E("IN1R", MADERA_INPUT_ENABLES, MADERA_IN1R_ENA_SHIFT,
617 0, NULL, 0, madera_in_ev,
618 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
619 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
620SND_SOC_DAPM_PGA_E("IN2L", MADERA_INPUT_ENABLES, MADERA_IN2L_ENA_SHIFT,
621 0, NULL, 0, madera_in_ev,
622 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
623 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
624SND_SOC_DAPM_PGA_E("IN2R", MADERA_INPUT_ENABLES, MADERA_IN2R_ENA_SHIFT,
625 0, NULL, 0, madera_in_ev,
626 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
627 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
628
629SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
630 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX1_ENA_SHIFT, 0),
631SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
632 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX2_ENA_SHIFT, 0),
633SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
634 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX3_ENA_SHIFT, 0),
635SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
636 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX4_ENA_SHIFT, 0),
637SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
638 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX5_ENA_SHIFT, 0),
639SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
640 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX6_ENA_SHIFT, 0),
641
642SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
643 MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX1_ENA_SHIFT, 0),
644SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
645 MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX2_ENA_SHIFT, 0),
646SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0,
647 MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX3_ENA_SHIFT, 0),
648SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0,
649 MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX4_ENA_SHIFT, 0),
650
651SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
652 MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX1_ENA_SHIFT, 0),
653SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
654 MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX2_ENA_SHIFT, 0),
655
656SND_SOC_DAPM_PGA("EQ1", MADERA_EQ1_1, MADERA_EQ1_ENA_SHIFT, 0, NULL, 0),
657SND_SOC_DAPM_PGA("EQ2", MADERA_EQ2_1, MADERA_EQ2_ENA_SHIFT, 0, NULL, 0),
658SND_SOC_DAPM_PGA("EQ3", MADERA_EQ3_1, MADERA_EQ3_ENA_SHIFT, 0, NULL, 0),
659SND_SOC_DAPM_PGA("EQ4", MADERA_EQ4_1, MADERA_EQ4_ENA_SHIFT, 0, NULL, 0),
660
661SND_SOC_DAPM_PGA("DRC1L", MADERA_DRC1_CTRL1, MADERA_DRC1L_ENA_SHIFT, 0,
662 NULL, 0),
663SND_SOC_DAPM_PGA("DRC1R", MADERA_DRC1_CTRL1, MADERA_DRC1R_ENA_SHIFT, 0,
664 NULL, 0),
665SND_SOC_DAPM_PGA("DRC2L", MADERA_DRC2_CTRL1, MADERA_DRC2L_ENA_SHIFT, 0,
666 NULL, 0),
667SND_SOC_DAPM_PGA("DRC2R", MADERA_DRC2_CTRL1, MADERA_DRC2R_ENA_SHIFT, 0,
668 NULL, 0),
669
670SND_SOC_DAPM_PGA("LHPF1", MADERA_HPLPF1_1, MADERA_LHPF1_ENA_SHIFT, 0, NULL, 0),
671SND_SOC_DAPM_PGA("LHPF2", MADERA_HPLPF2_1, MADERA_LHPF2_ENA_SHIFT, 0, NULL, 0),
672SND_SOC_DAPM_PGA("LHPF3", MADERA_HPLPF3_1, MADERA_LHPF3_ENA_SHIFT, 0, NULL, 0),
673SND_SOC_DAPM_PGA("LHPF4", MADERA_HPLPF4_1, MADERA_LHPF4_ENA_SHIFT, 0, NULL, 0),
674
675SND_SOC_DAPM_PGA("ISRC1DEC1", MADERA_ISRC_1_CTRL_3,
676 MADERA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0),
677SND_SOC_DAPM_PGA("ISRC1DEC2", MADERA_ISRC_1_CTRL_3,
678 MADERA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0),
679SND_SOC_DAPM_PGA("ISRC1DEC3", MADERA_ISRC_1_CTRL_3,
680 MADERA_ISRC1_DEC3_ENA_SHIFT, 0, NULL, 0),
681SND_SOC_DAPM_PGA("ISRC1DEC4", MADERA_ISRC_1_CTRL_3,
682 MADERA_ISRC1_DEC4_ENA_SHIFT, 0, NULL, 0),
683
684SND_SOC_DAPM_PGA("ISRC1INT1", MADERA_ISRC_1_CTRL_3,
685 MADERA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0),
686SND_SOC_DAPM_PGA("ISRC1INT2", MADERA_ISRC_1_CTRL_3,
687 MADERA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0),
688SND_SOC_DAPM_PGA("ISRC1INT3", MADERA_ISRC_1_CTRL_3,
689 MADERA_ISRC1_INT3_ENA_SHIFT, 0, NULL, 0),
690SND_SOC_DAPM_PGA("ISRC1INT4", MADERA_ISRC_1_CTRL_3,
691 MADERA_ISRC1_INT4_ENA_SHIFT, 0, NULL, 0),
692
693SND_SOC_DAPM_PGA("ISRC2DEC1", MADERA_ISRC_2_CTRL_3,
694 MADERA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
695SND_SOC_DAPM_PGA("ISRC2DEC2", MADERA_ISRC_2_CTRL_3,
696 MADERA_ISRC2_DEC2_ENA_SHIFT, 0, NULL, 0),
697SND_SOC_DAPM_PGA("ISRC2DEC3", MADERA_ISRC_2_CTRL_3,
698 MADERA_ISRC2_DEC3_ENA_SHIFT, 0, NULL, 0),
699SND_SOC_DAPM_PGA("ISRC2DEC4", MADERA_ISRC_2_CTRL_3,
700 MADERA_ISRC2_DEC4_ENA_SHIFT, 0, NULL, 0),
701
702SND_SOC_DAPM_PGA("ISRC2INT1", MADERA_ISRC_2_CTRL_3,
703 MADERA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0),
704SND_SOC_DAPM_PGA("ISRC2INT2", MADERA_ISRC_2_CTRL_3,
705 MADERA_ISRC2_INT2_ENA_SHIFT, 0, NULL, 0),
706SND_SOC_DAPM_PGA("ISRC2INT3", MADERA_ISRC_2_CTRL_3,
707 MADERA_ISRC2_INT3_ENA_SHIFT, 0, NULL, 0),
708SND_SOC_DAPM_PGA("ISRC2INT4", MADERA_ISRC_2_CTRL_3,
709 MADERA_ISRC2_INT4_ENA_SHIFT, 0, NULL, 0),
710
711WM_ADSP2("DSP1", 0, cs47l15_adsp_power_ev),
712
713/* end of ordered widget list */
714
715MADERA_MIXER_WIDGETS(EQ1, "EQ1"),
716MADERA_MIXER_WIDGETS(EQ2, "EQ2"),
717MADERA_MIXER_WIDGETS(EQ3, "EQ3"),
718MADERA_MIXER_WIDGETS(EQ4, "EQ4"),
719
720MADERA_MIXER_WIDGETS(DRC1L, "DRC1L"),
721MADERA_MIXER_WIDGETS(DRC1R, "DRC1R"),
722MADERA_MIXER_WIDGETS(DRC2L, "DRC2L"),
723MADERA_MIXER_WIDGETS(DRC2R, "DRC2R"),
724
725SND_SOC_DAPM_SWITCH("DRC1 Activity Output", SND_SOC_NOPM, 0, 0,
726 &madera_drc_activity_output_mux[0]),
727SND_SOC_DAPM_SWITCH("DRC2 Activity Output", SND_SOC_NOPM, 0, 0,
728 &madera_drc_activity_output_mux[1]),
729
730MADERA_MIXER_WIDGETS(LHPF1, "LHPF1"),
731MADERA_MIXER_WIDGETS(LHPF2, "LHPF2"),
732MADERA_MIXER_WIDGETS(LHPF3, "LHPF3"),
733MADERA_MIXER_WIDGETS(LHPF4, "LHPF4"),
734
735MADERA_MIXER_WIDGETS(PWM1, "PWM1"),
736MADERA_MIXER_WIDGETS(PWM2, "PWM2"),
737
738MADERA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
739MADERA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
740MADERA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
741MADERA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
742MADERA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
743
744MADERA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
745MADERA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
746MADERA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
747MADERA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
748MADERA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
749MADERA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
750
751MADERA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
752MADERA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
753MADERA_MIXER_WIDGETS(AIF2TX3, "AIF2TX3"),
754MADERA_MIXER_WIDGETS(AIF2TX4, "AIF2TX4"),
755
756MADERA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
757MADERA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
758
759MADERA_MUX_WIDGETS(SPD1TX1, "SPDIF1TX1"),
760MADERA_MUX_WIDGETS(SPD1TX2, "SPDIF1TX2"),
761
762MADERA_DSP_WIDGETS(DSP1, "DSP1"),
763
764SND_SOC_DAPM_SWITCH("DSP1 Trigger Output", SND_SOC_NOPM, 0, 0,
765 &madera_dsp_trigger_output_mux[0]),
766
767MADERA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
768MADERA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
769MADERA_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"),
770MADERA_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"),
771
772MADERA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
773MADERA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
774MADERA_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"),
775MADERA_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"),
776
777MADERA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
778MADERA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
779MADERA_MUX_WIDGETS(ISRC2DEC3, "ISRC2DEC3"),
780MADERA_MUX_WIDGETS(ISRC2DEC4, "ISRC2DEC4"),
781
782MADERA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
783MADERA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
784MADERA_MUX_WIDGETS(ISRC2INT3, "ISRC2INT3"),
785MADERA_MUX_WIDGETS(ISRC2INT4, "ISRC2INT4"),
786
787SND_SOC_DAPM_OUTPUT("HPOUTL"),
788SND_SOC_DAPM_OUTPUT("HPOUTR"),
789SND_SOC_DAPM_OUTPUT("EPOUTP"),
790SND_SOC_DAPM_OUTPUT("EPOUTN"),
791SND_SOC_DAPM_OUTPUT("SPKOUTN"),
792SND_SOC_DAPM_OUTPUT("SPKOUTP"),
793SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
794SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
795SND_SOC_DAPM_OUTPUT("SPDIF1"),
796
797SND_SOC_DAPM_OUTPUT("MICSUPP"),
798};
799
800#define MADERA_MIXER_INPUT_ROUTES(name) \
801 { name, "Noise Generator", "Noise Generator" }, \
802 { name, "Tone Generator 1", "Tone Generator 1" }, \
803 { name, "Tone Generator 2", "Tone Generator 2" }, \
804 { name, "Haptics", "HAPTICS" }, \
805 { name, "AEC1", "AEC1 Loopback" }, \
806 { name, "AEC2", "AEC2 Loopback" }, \
807 { name, "IN1L", "IN1L" }, \
808 { name, "IN1R", "IN1R" }, \
809 { name, "IN2L", "IN2L" }, \
810 { name, "IN2R", "IN2R" }, \
811 { name, "AIF1RX1", "AIF1RX1" }, \
812 { name, "AIF1RX2", "AIF1RX2" }, \
813 { name, "AIF1RX3", "AIF1RX3" }, \
814 { name, "AIF1RX4", "AIF1RX4" }, \
815 { name, "AIF1RX5", "AIF1RX5" }, \
816 { name, "AIF1RX6", "AIF1RX6" }, \
817 { name, "AIF2RX1", "AIF2RX1" }, \
818 { name, "AIF2RX2", "AIF2RX2" }, \
819 { name, "AIF2RX3", "AIF2RX3" }, \
820 { name, "AIF2RX4", "AIF2RX4" }, \
821 { name, "AIF3RX1", "AIF3RX1" }, \
822 { name, "AIF3RX2", "AIF3RX2" }, \
823 { name, "EQ1", "EQ1" }, \
824 { name, "EQ2", "EQ2" }, \
825 { name, "EQ3", "EQ3" }, \
826 { name, "EQ4", "EQ4" }, \
827 { name, "DRC1L", "DRC1L" }, \
828 { name, "DRC1R", "DRC1R" }, \
829 { name, "DRC2L", "DRC2L" }, \
830 { name, "DRC2R", "DRC2R" }, \
831 { name, "LHPF1", "LHPF1" }, \
832 { name, "LHPF2", "LHPF2" }, \
833 { name, "LHPF3", "LHPF3" }, \
834 { name, "LHPF4", "LHPF4" }, \
835 { name, "ISRC1DEC1", "ISRC1DEC1" }, \
836 { name, "ISRC1DEC2", "ISRC1DEC2" }, \
837 { name, "ISRC1DEC3", "ISRC1DEC3" }, \
838 { name, "ISRC1DEC4", "ISRC1DEC4" }, \
839 { name, "ISRC1INT1", "ISRC1INT1" }, \
840 { name, "ISRC1INT2", "ISRC1INT2" }, \
841 { name, "ISRC1INT3", "ISRC1INT3" }, \
842 { name, "ISRC1INT4", "ISRC1INT4" }, \
843 { name, "ISRC2DEC1", "ISRC2DEC1" }, \
844 { name, "ISRC2DEC2", "ISRC2DEC2" }, \
845 { name, "ISRC2DEC3", "ISRC2DEC3" }, \
846 { name, "ISRC2DEC4", "ISRC2DEC4" }, \
847 { name, "ISRC2INT1", "ISRC2INT1" }, \
848 { name, "ISRC2INT2", "ISRC2INT2" }, \
849 { name, "ISRC2INT3", "ISRC2INT3" }, \
850 { name, "ISRC2INT4", "ISRC2INT4" }, \
851 { name, "DSP1.1", "DSP1" }, \
852 { name, "DSP1.2", "DSP1" }, \
853 { name, "DSP1.3", "DSP1" }, \
854 { name, "DSP1.4", "DSP1" }, \
855 { name, "DSP1.5", "DSP1" }, \
856 { name, "DSP1.6", "DSP1" }
857
858static const struct snd_soc_dapm_route cs47l15_dapm_routes[] = {
859 /* Internal clock domains */
860 { "EQ1", NULL, "FXCLK" },
861 { "EQ2", NULL, "FXCLK" },
862 { "EQ3", NULL, "FXCLK" },
863 { "EQ4", NULL, "FXCLK" },
864 { "DRC1L", NULL, "FXCLK" },
865 { "DRC1R", NULL, "FXCLK" },
866 { "DRC2L", NULL, "FXCLK" },
867 { "DRC2R", NULL, "FXCLK" },
868 { "LHPF1", NULL, "FXCLK" },
869 { "LHPF2", NULL, "FXCLK" },
870 { "LHPF3", NULL, "FXCLK" },
871 { "LHPF4", NULL, "FXCLK" },
872 { "PWM1 Mixer", NULL, "PWMCLK" },
873 { "PWM2 Mixer", NULL, "PWMCLK" },
874 { "OUT1L", NULL, "OUTCLK" },
875 { "OUT1R", NULL, "OUTCLK" },
876 { "OUT4L", NULL, "OUTCLK" },
877 { "OUT5L", NULL, "OUTCLK" },
878 { "OUT5R", NULL, "OUTCLK" },
879 { "AIF1TX1", NULL, "AIF1TXCLK" },
880 { "AIF1TX2", NULL, "AIF1TXCLK" },
881 { "AIF1TX3", NULL, "AIF1TXCLK" },
882 { "AIF1TX4", NULL, "AIF1TXCLK" },
883 { "AIF1TX5", NULL, "AIF1TXCLK" },
884 { "AIF1TX6", NULL, "AIF1TXCLK" },
885 { "AIF2TX1", NULL, "AIF2TXCLK" },
886 { "AIF2TX2", NULL, "AIF2TXCLK" },
887 { "AIF2TX3", NULL, "AIF2TXCLK" },
888 { "AIF2TX4", NULL, "AIF2TXCLK" },
889 { "AIF3TX1", NULL, "AIF3TXCLK" },
890 { "AIF3TX2", NULL, "AIF3TXCLK" },
891 { "SPD1TX1", NULL, "SPDCLK" },
892 { "SPD1TX2", NULL, "SPDCLK" },
893 { "DSP1", NULL, "DSP1CLK" },
894 { "ISRC1DEC1", NULL, "ISRC1CLK" },
895 { "ISRC1DEC2", NULL, "ISRC1CLK" },
896 { "ISRC1DEC3", NULL, "ISRC1CLK" },
897 { "ISRC1DEC4", NULL, "ISRC1CLK" },
898 { "ISRC1INT1", NULL, "ISRC1CLK" },
899 { "ISRC1INT2", NULL, "ISRC1CLK" },
900 { "ISRC1INT3", NULL, "ISRC1CLK" },
901 { "ISRC1INT4", NULL, "ISRC1CLK" },
902 { "ISRC2DEC1", NULL, "ISRC2CLK" },
903 { "ISRC2DEC2", NULL, "ISRC2CLK" },
904 { "ISRC2DEC3", NULL, "ISRC2CLK" },
905 { "ISRC2DEC4", NULL, "ISRC2CLK" },
906 { "ISRC2INT1", NULL, "ISRC2CLK" },
907 { "ISRC2INT2", NULL, "ISRC2CLK" },
908 { "ISRC2INT3", NULL, "ISRC2CLK" },
909 { "ISRC2INT4", NULL, "ISRC2CLK" },
910
911 { "OUT1L", NULL, "CPVDD1" },
912 { "OUT1R", NULL, "CPVDD1" },
913 { "OUT4L", NULL, "SPKVDD" },
914
915 { "OUT1L", NULL, "SYSCLK" },
916 { "OUT1R", NULL, "SYSCLK" },
917 { "OUT4L", NULL, "SYSCLK" },
918 { "OUT5L", NULL, "SYSCLK" },
919 { "OUT5R", NULL, "SYSCLK" },
920
921 { "SPD1", NULL, "SYSCLK" },
922 { "SPD1", NULL, "SPD1TX1" },
923 { "SPD1", NULL, "SPD1TX2" },
924
925 { "IN1L", NULL, "SYSCLK" },
926 { "IN1R", NULL, "SYSCLK" },
927 { "IN2L", NULL, "SYSCLK" },
928 { "IN2R", NULL, "SYSCLK" },
929
930 { "MICBIAS1", NULL, "MICVDD" },
931
932 { "MICBIAS1A", NULL, "MICBIAS1" },
933 { "MICBIAS1B", NULL, "MICBIAS1" },
934 { "MICBIAS1C", NULL, "MICBIAS1" },
935
936 { "Noise Generator", NULL, "SYSCLK" },
937 { "Tone Generator 1", NULL, "SYSCLK" },
938 { "Tone Generator 2", NULL, "SYSCLK" },
939
940 { "Noise Generator", NULL, "NOISE" },
941 { "Tone Generator 1", NULL, "TONE" },
942 { "Tone Generator 2", NULL, "TONE" },
943
944 { "AIF1 Capture", NULL, "AIF1TX1" },
945 { "AIF1 Capture", NULL, "AIF1TX2" },
946 { "AIF1 Capture", NULL, "AIF1TX3" },
947 { "AIF1 Capture", NULL, "AIF1TX4" },
948 { "AIF1 Capture", NULL, "AIF1TX5" },
949 { "AIF1 Capture", NULL, "AIF1TX6" },
950
951 { "AIF1RX1", NULL, "AIF1 Playback" },
952 { "AIF1RX2", NULL, "AIF1 Playback" },
953 { "AIF1RX3", NULL, "AIF1 Playback" },
954 { "AIF1RX4", NULL, "AIF1 Playback" },
955 { "AIF1RX5", NULL, "AIF1 Playback" },
956 { "AIF1RX6", NULL, "AIF1 Playback" },
957
958 { "AIF2 Capture", NULL, "AIF2TX1" },
959 { "AIF2 Capture", NULL, "AIF2TX2" },
960 { "AIF2 Capture", NULL, "AIF2TX3" },
961 { "AIF2 Capture", NULL, "AIF2TX4" },
962
963 { "AIF2RX1", NULL, "AIF2 Playback" },
964 { "AIF2RX2", NULL, "AIF2 Playback" },
965 { "AIF2RX3", NULL, "AIF2 Playback" },
966 { "AIF2RX4", NULL, "AIF2 Playback" },
967
968 { "AIF3 Capture", NULL, "AIF3TX1" },
969 { "AIF3 Capture", NULL, "AIF3TX2" },
970
971 { "AIF3RX1", NULL, "AIF3 Playback" },
972 { "AIF3RX2", NULL, "AIF3 Playback" },
973
974 { "AIF1 Playback", NULL, "SYSCLK" },
975 { "AIF2 Playback", NULL, "SYSCLK" },
976 { "AIF3 Playback", NULL, "SYSCLK" },
977
978 { "AIF1 Capture", NULL, "SYSCLK" },
979 { "AIF2 Capture", NULL, "SYSCLK" },
980 { "AIF3 Capture", NULL, "SYSCLK" },
981
982 { "Audio Trace DSP", NULL, "DSP1" },
983
984 { "IN1L Analog Mux", "A", "IN1ALN" },
985 { "IN1L Analog Mux", "A", "IN1ALP" },
986 { "IN1L Analog Mux", "B", "IN1BLN" },
987 { "IN1L Analog Mux", "B", "IN1BLP" },
988 { "IN1R Analog Mux", "A", "IN1ARN" },
989 { "IN1R Analog Mux", "A", "IN1ARP" },
990 { "IN1R Analog Mux", "B", "IN1BRN" },
991 { "IN1R Analog Mux", "B", "IN1BRP" },
992
993 { "IN1L Mode", "Analog", "IN1L Analog Mux" },
994 { "IN1R Mode", "Analog", "IN1R Analog Mux" },
995
996 { "IN1L Mode", "Digital", "IN1ALN" },
997 { "IN1L Mode", "Digital", "IN1ALP" },
998 { "IN1R Mode", "Digital", "IN1ALN" },
999 { "IN1R Mode", "Digital", "IN1ALP" },
1000
1001 { "IN1L", NULL, "IN1L Mode" },
1002 { "IN1R", NULL, "IN1R Mode" },
1003
1004 { "IN2L Mode", "Analog", "IN2N" },
1005 { "IN2L Mode", "Analog", "IN2P" },
1006
1007 { "IN2L Mode", "Digital", "SPKRXDAT" },
1008 { "IN2R Mode", "Digital", "SPKRXDAT" },
1009
1010 { "IN2L", NULL, "IN2L Mode" },
1011 { "IN2R", NULL, "IN2R Mode" },
1012
1013 MADERA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
1014 MADERA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
1015 MADERA_MIXER_ROUTES("OUT4L", "SPKOUTL"),
1016 MADERA_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
1017 MADERA_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
1018
1019 MADERA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
1020 MADERA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
1021
1022 MADERA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1023 MADERA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1024 MADERA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1025 MADERA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1026 MADERA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1027 MADERA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1028
1029 MADERA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
1030 MADERA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
1031 MADERA_MIXER_ROUTES("AIF2TX3", "AIF2TX3"),
1032 MADERA_MIXER_ROUTES("AIF2TX4", "AIF2TX4"),
1033
1034 MADERA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
1035 MADERA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
1036
1037 MADERA_MUX_ROUTES("SPD1TX1", "SPDIF1TX1"),
1038 MADERA_MUX_ROUTES("SPD1TX2", "SPDIF1TX2"),
1039
1040 MADERA_MIXER_ROUTES("EQ1", "EQ1"),
1041 MADERA_MIXER_ROUTES("EQ2", "EQ2"),
1042 MADERA_MIXER_ROUTES("EQ3", "EQ3"),
1043 MADERA_MIXER_ROUTES("EQ4", "EQ4"),
1044
1045 MADERA_MIXER_ROUTES("DRC1L", "DRC1L"),
1046 MADERA_MIXER_ROUTES("DRC1R", "DRC1R"),
1047 MADERA_MIXER_ROUTES("DRC2L", "DRC2L"),
1048 MADERA_MIXER_ROUTES("DRC2R", "DRC2R"),
1049
1050 MADERA_MIXER_ROUTES("LHPF1", "LHPF1"),
1051 MADERA_MIXER_ROUTES("LHPF2", "LHPF2"),
1052 MADERA_MIXER_ROUTES("LHPF3", "LHPF3"),
1053 MADERA_MIXER_ROUTES("LHPF4", "LHPF4"),
1054
1055 MADERA_DSP_ROUTES("DSP1"),
1056
1057 { "DSP Trigger Out", NULL, "DSP1 Trigger Output" },
1058
1059 { "DSP1 Trigger Output", "Switch", "DSP1" },
1060
1061 MADERA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
1062 MADERA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
1063 MADERA_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"),
1064 MADERA_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"),
1065
1066 MADERA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
1067 MADERA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
1068 MADERA_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
1069 MADERA_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
1070
1071 MADERA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
1072 MADERA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
1073 MADERA_MUX_ROUTES("ISRC2INT3", "ISRC2INT3"),
1074 MADERA_MUX_ROUTES("ISRC2INT4", "ISRC2INT4"),
1075
1076 MADERA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
1077 MADERA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
1078 MADERA_MUX_ROUTES("ISRC2DEC3", "ISRC2DEC3"),
1079 MADERA_MUX_ROUTES("ISRC2DEC4", "ISRC2DEC4"),
1080
1081 { "AEC1 Loopback", "HPOUT1L", "OUT1L" },
1082 { "AEC1 Loopback", "HPOUT1R", "OUT1R" },
1083 { "AEC2 Loopback", "HPOUT1L", "OUT1L" },
1084 { "AEC2 Loopback", "HPOUT1R", "OUT1R" },
1085 { "HPOUT1 Demux", NULL, "OUT1L" },
1086 { "HPOUT1 Demux", NULL, "OUT1R" },
1087 { "HPOUTL", "HPOUT", "HPOUT1 Demux" },
1088 { "HPOUTR", "HPOUT", "HPOUT1 Demux" },
1089 { "EPOUTP", "EPOUT", "HPOUT1 Demux" },
1090 { "EPOUTN", "EPOUT", "HPOUT1 Demux" },
1091
1092 { "AEC1 Loopback", "SPKOUTL", "OUT4L" },
1093 { "AEC2 Loopback", "SPKOUTL", "OUT4L" },
1094 { "SPKOUTN", NULL, "OUT4L" },
1095 { "SPKOUTP", NULL, "OUT4L" },
1096
1097 { "AEC1 Loopback", "SPKDAT1L", "OUT5L" },
1098 { "AEC1 Loopback", "SPKDAT1R", "OUT5R" },
1099 { "AEC2 Loopback", "SPKDAT1L", "OUT5L" },
1100 { "AEC2 Loopback", "SPKDAT1R", "OUT5R" },
1101 { "SPKDAT1L", NULL, "OUT5L" },
1102 { "SPKDAT1R", NULL, "OUT5R" },
1103
1104 { "SPDIF1", NULL, "SPD1" },
1105
1106 { "MICSUPP", NULL, "SYSCLK" },
1107
1108 { "DRC1 Signal Activity", NULL, "DRC1 Activity Output" },
1109 { "DRC2 Signal Activity", NULL, "DRC2 Activity Output" },
1110 { "DRC1 Activity Output", "Switch", "DRC1L" },
1111 { "DRC1 Activity Output", "Switch", "DRC1R" },
1112 { "DRC2 Activity Output", "Switch", "DRC2L" },
1113 { "DRC2 Activity Output", "Switch", "DRC2R" },
1114};
1115
1116static int cs47l15_set_fll(struct snd_soc_component *component, int fll_id,
1117 int source, unsigned int fref, unsigned int fout)
1118{
1119 struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
1120
1121 switch (fll_id) {
1122 case MADERA_FLL1_REFCLK:
1123 return madera_set_fll_refclk(&cs47l15->fll[0], source, fref,
1124 fout);
1125 case MADERA_FLLAO_REFCLK:
1126 return madera_set_fll_ao_refclk(&cs47l15->fll[1], source, fref,
1127 fout);
1128 case MADERA_FLL1_SYNCCLK:
1129 return madera_set_fll_syncclk(&cs47l15->fll[0], source, fref,
1130 fout);
1131 default:
1132 return -EINVAL;
1133 }
1134}
1135
1136static struct snd_soc_dai_driver cs47l15_dai[] = {
1137 {
1138 .name = "cs47l15-aif1",
1139 .id = 1,
1140 .base = MADERA_AIF1_BCLK_CTRL,
1141 .playback = {
1142 .stream_name = "AIF1 Playback",
1143 .channels_min = 1,
1144 .channels_max = 6,
1145 .rates = MADERA_RATES,
1146 .formats = MADERA_FORMATS,
1147 },
1148 .capture = {
1149 .stream_name = "AIF1 Capture",
1150 .channels_min = 1,
1151 .channels_max = 6,
1152 .rates = MADERA_RATES,
1153 .formats = MADERA_FORMATS,
1154 },
1155 .ops = &madera_dai_ops,
1156 .symmetric_rates = 1,
1157 .symmetric_samplebits = 1,
1158 },
1159 {
1160 .name = "cs47l15-aif2",
1161 .id = 2,
1162 .base = MADERA_AIF2_BCLK_CTRL,
1163 .playback = {
1164 .stream_name = "AIF2 Playback",
1165 .channels_min = 1,
1166 .channels_max = 4,
1167 .rates = MADERA_RATES,
1168 .formats = MADERA_FORMATS,
1169 },
1170 .capture = {
1171 .stream_name = "AIF2 Capture",
1172 .channels_min = 1,
1173 .channels_max = 4,
1174 .rates = MADERA_RATES,
1175 .formats = MADERA_FORMATS,
1176 },
1177 .ops = &madera_dai_ops,
1178 .symmetric_rates = 1,
1179 .symmetric_samplebits = 1,
1180 },
1181 {
1182 .name = "cs47l15-aif3",
1183 .id = 3,
1184 .base = MADERA_AIF3_BCLK_CTRL,
1185 .playback = {
1186 .stream_name = "AIF3 Playback",
1187 .channels_min = 1,
1188 .channels_max = 2,
1189 .rates = MADERA_RATES,
1190 .formats = MADERA_FORMATS,
1191 },
1192 .capture = {
1193 .stream_name = "AIF3 Capture",
1194 .channels_min = 1,
1195 .channels_max = 2,
1196 .rates = MADERA_RATES,
1197 .formats = MADERA_FORMATS,
1198 },
1199 .ops = &madera_dai_ops,
1200 .symmetric_rates = 1,
1201 .symmetric_samplebits = 1,
1202 },
1203 {
1204 .name = "cs47l15-cpu-trace",
1205 .capture = {
1206 .stream_name = "Audio Trace CPU",
1207 .channels_min = 1,
1208 .channels_max = 6,
1209 .rates = MADERA_RATES,
1210 .formats = MADERA_FORMATS,
1211 },
1212 .compress_new = snd_soc_new_compress,
1213 },
1214 {
1215 .name = "cs47l15-dsp-trace",
1216 .capture = {
1217 .stream_name = "Audio Trace DSP",
1218 .channels_min = 1,
1219 .channels_max = 6,
1220 .rates = MADERA_RATES,
1221 .formats = MADERA_FORMATS,
1222 },
1223 },
1224};
1225
1226static int cs47l15_open(struct snd_compr_stream *stream)
1227{
1228 struct snd_soc_pcm_runtime *rtd = stream->private_data;
1229 struct snd_soc_component *component =
1230 snd_soc_rtdcom_lookup(rtd, DRV_NAME);
1231 struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
1232 struct madera_priv *priv = &cs47l15->core;
1233 struct madera *madera = priv->madera;
1234 int n_adsp;
1235
1236 if (strcmp(rtd->codec_dai->name, "cs47l15-dsp-trace") == 0) {
1237 n_adsp = 0;
1238 } else {
1239 dev_err(madera->dev,
1240 "No suitable compressed stream for DAI '%s'\n",
1241 rtd->codec_dai->name);
1242 return -EINVAL;
1243 }
1244
1245 return wm_adsp_compr_open(&priv->adsp[n_adsp], stream);
1246}
1247
1248static irqreturn_t cs47l15_adsp2_irq(int irq, void *data)
1249{
1250 struct cs47l15 *cs47l15 = data;
1251 struct madera_priv *priv = &cs47l15->core;
1252 struct madera *madera = priv->madera;
1253 int ret;
1254
1255 ret = wm_adsp_compr_handle_irq(&priv->adsp[0]);
1256 if (ret == -ENODEV) {
1257 dev_err(madera->dev, "Spurious compressed data IRQ\n");
1258 return IRQ_NONE;
1259 }
1260
1261 return IRQ_HANDLED;
1262}
1263
1264static int cs47l15_component_probe(struct snd_soc_component *component)
1265{
1266 struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
1267 struct madera *madera = cs47l15->core.madera;
1268 int ret;
1269
1270 snd_soc_component_init_regmap(component, madera->regmap);
1271
1272 mutex_lock(&madera->dapm_ptr_lock);
1273 madera->dapm = snd_soc_component_get_dapm(component);
1274 mutex_unlock(&madera->dapm_ptr_lock);
1275
1276 ret = madera_init_inputs(component);
1277 if (ret)
1278 return ret;
1279
1280 ret = madera_init_outputs(component, CS47L15_MONO_OUTPUTS);
1281 if (ret)
1282 return ret;
1283
1284 snd_soc_component_disable_pin(component, "HAPTICS");
1285
1286 ret = snd_soc_add_component_controls(component,
1287 madera_adsp_rate_controls,
1288 CS47L15_NUM_ADSP);
1289 if (ret)
1290 return ret;
1291
1292 wm_adsp2_component_probe(&cs47l15->core.adsp[0], component);
1293
1294 return 0;
1295}
1296
1297static void cs47l15_component_remove(struct snd_soc_component *component)
1298{
1299 struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
1300 struct madera *madera = cs47l15->core.madera;
1301
1302 mutex_lock(&madera->dapm_ptr_lock);
1303 madera->dapm = NULL;
1304 mutex_unlock(&madera->dapm_ptr_lock);
1305
1306 wm_adsp2_component_remove(&cs47l15->core.adsp[0], component);
1307}
1308
1309#define CS47L15_DIG_VU 0x0200
1310
1311static unsigned int cs47l15_digital_vu[] = {
1312 MADERA_DAC_DIGITAL_VOLUME_1L,
1313 MADERA_DAC_DIGITAL_VOLUME_1R,
1314 MADERA_DAC_DIGITAL_VOLUME_4L,
1315 MADERA_DAC_DIGITAL_VOLUME_5L,
1316 MADERA_DAC_DIGITAL_VOLUME_5R,
1317};
1318
1319static const struct snd_compr_ops cs47l15_compr_ops = {
1320 .open = &cs47l15_open,
1321 .free = &wm_adsp_compr_free,
1322 .set_params = &wm_adsp_compr_set_params,
1323 .get_caps = &wm_adsp_compr_get_caps,
1324 .trigger = &wm_adsp_compr_trigger,
1325 .pointer = &wm_adsp_compr_pointer,
1326 .copy = &wm_adsp_compr_copy,
1327};
1328
1329static const struct snd_soc_component_driver soc_component_dev_cs47l15 = {
1330 .probe = &cs47l15_component_probe,
1331 .remove = &cs47l15_component_remove,
1332 .set_sysclk = &madera_set_sysclk,
1333 .set_pll = &cs47l15_set_fll,
1334 .name = DRV_NAME,
1335 .compr_ops = &cs47l15_compr_ops,
1336 .controls = cs47l15_snd_controls,
1337 .num_controls = ARRAY_SIZE(cs47l15_snd_controls),
1338 .dapm_widgets = cs47l15_dapm_widgets,
1339 .num_dapm_widgets = ARRAY_SIZE(cs47l15_dapm_widgets),
1340 .dapm_routes = cs47l15_dapm_routes,
1341 .num_dapm_routes = ARRAY_SIZE(cs47l15_dapm_routes),
1342 .use_pmdown_time = 1,
1343 .endianness = 1,
1344 .non_legacy_dai_naming = 1,
1345};
1346
1347static int cs47l15_probe(struct platform_device *pdev)
1348{
1349 struct madera *madera = dev_get_drvdata(pdev->dev.parent);
1350 struct cs47l15 *cs47l15;
1351 int i, ret;
1352
1353 BUILD_BUG_ON(ARRAY_SIZE(cs47l15_dai) > MADERA_MAX_DAI);
1354
1355 /* quick exit if Madera irqchip driver hasn't completed probe */
1356 if (!madera->irq_dev) {
1357 dev_dbg(&pdev->dev, "irqchip driver not ready\n");
1358 return -EPROBE_DEFER;
1359 }
1360
1361 cs47l15 = devm_kzalloc(&pdev->dev, sizeof(struct cs47l15),
1362 GFP_KERNEL);
1363 if (!cs47l15)
1364 return -ENOMEM;
1365
1366 platform_set_drvdata(pdev, cs47l15);
1367
1368 cs47l15->core.madera = madera;
1369 cs47l15->core.dev = &pdev->dev;
1370 cs47l15->core.num_inputs = 4;
1371
1372 ret = madera_core_init(&cs47l15->core);
1373 if (ret)
1374 return ret;
1375
1376 ret = madera_init_overheat(&cs47l15->core);
1377 if (ret)
1378 goto error_core;
1379
1380 ret = madera_request_irq(madera, MADERA_IRQ_DSP_IRQ1,
1381 "ADSP2 Compressed IRQ", cs47l15_adsp2_irq,
1382 cs47l15);
1383 if (ret != 0) {
1384 dev_err(&pdev->dev, "Failed to request DSP IRQ: %d\n", ret);
1385 goto error_overheat;
1386 }
1387
1388 ret = madera_set_irq_wake(madera, MADERA_IRQ_DSP_IRQ1, 1);
1389 if (ret)
1390 dev_warn(&pdev->dev, "Failed to set DSP IRQ wake: %d\n", ret);
1391
1392 cs47l15->core.adsp[0].part = "cs47l15";
1393 cs47l15->core.adsp[0].num = 1;
1394 cs47l15->core.adsp[0].type = WMFW_ADSP2;
1395 cs47l15->core.adsp[0].rev = 2;
1396 cs47l15->core.adsp[0].dev = madera->dev;
1397 cs47l15->core.adsp[0].regmap = madera->regmap_32bit;
1398
1399 cs47l15->core.adsp[0].base = MADERA_DSP1_CONFIG_1;
1400 cs47l15->core.adsp[0].mem = cs47l15_dsp1_regions;
1401 cs47l15->core.adsp[0].num_mems = ARRAY_SIZE(cs47l15_dsp1_regions);
1402
1403 cs47l15->core.adsp[0].lock_regions =
1404 WM_ADSP2_REGION_1 | WM_ADSP2_REGION_2 | WM_ADSP2_REGION_3;
1405
1406 ret = wm_adsp2_init(&cs47l15->core.adsp[0]);
1407 if (ret != 0)
1408 goto error_dsp_irq;
1409
1410 ret = madera_init_bus_error_irq(&cs47l15->core, 0, wm_adsp2_bus_error);
1411 if (ret)
1412 goto error_adsp;
1413
1414 madera_init_fll(madera, 1, MADERA_FLL1_CONTROL_1 - 1,
1415 &cs47l15->fll[0]);
1416 madera_init_fll(madera, 4, MADERA_FLLAO_CONTROL_1 - 1,
1417 &cs47l15->fll[1]);
1418
1419 for (i = 0; i < ARRAY_SIZE(cs47l15_dai); i++)
1420 madera_init_dai(&cs47l15->core, i);
1421
1422 /* Latch volume update bits */
1423 for (i = 0; i < ARRAY_SIZE(cs47l15_digital_vu); i++)
1424 regmap_update_bits(madera->regmap, cs47l15_digital_vu[i],
1425 CS47L15_DIG_VU, CS47L15_DIG_VU);
1426
1427 pm_runtime_enable(&pdev->dev);
1428 pm_runtime_idle(&pdev->dev);
1429
1430 ret = devm_snd_soc_register_component(&pdev->dev,
1431 &soc_component_dev_cs47l15,
1432 cs47l15_dai,
1433 ARRAY_SIZE(cs47l15_dai));
1434 if (ret < 0) {
1435 dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
1436 goto error_pm_runtime;
1437 }
1438
1439 return ret;
1440
1441error_pm_runtime:
1442 pm_runtime_disable(&pdev->dev);
1443 madera_free_bus_error_irq(&cs47l15->core, 0);
1444error_adsp:
1445 wm_adsp2_remove(&cs47l15->core.adsp[0]);
1446error_dsp_irq:
1447 madera_set_irq_wake(madera, MADERA_IRQ_DSP_IRQ1, 0);
1448 madera_free_irq(madera, MADERA_IRQ_DSP_IRQ1, cs47l15);
1449error_overheat:
1450 madera_free_overheat(&cs47l15->core);
1451error_core:
1452 madera_core_free(&cs47l15->core);
1453
1454 return ret;
1455}
1456
1457static int cs47l15_remove(struct platform_device *pdev)
1458{
1459 struct cs47l15 *cs47l15 = platform_get_drvdata(pdev);
1460
1461 pm_runtime_disable(&pdev->dev);
1462
1463 madera_free_bus_error_irq(&cs47l15->core, 0);
1464
1465 wm_adsp2_remove(&cs47l15->core.adsp[0]);
1466
1467 madera_set_irq_wake(cs47l15->core.madera, MADERA_IRQ_DSP_IRQ1, 0);
1468 madera_free_irq(cs47l15->core.madera, MADERA_IRQ_DSP_IRQ1, cs47l15);
1469 madera_free_overheat(&cs47l15->core);
1470 madera_core_free(&cs47l15->core);
1471
1472 return 0;
1473}
1474
1475static struct platform_driver cs47l15_codec_driver = {
1476 .driver = {
1477 .name = "cs47l15-codec",
1478 },
1479 .probe = &cs47l15_probe,
1480 .remove = &cs47l15_remove,
1481};
1482
1483module_platform_driver(cs47l15_codec_driver);
1484
1485MODULE_SOFTDEP("pre: madera irq-madera arizona-micsupp");
1486MODULE_DESCRIPTION("ASoC CS47L15 driver");
1487MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
1488MODULE_AUTHOR("Jaswinder Jassal <jjassal@opensource.cirrus.com>");
1489MODULE_LICENSE("GPL v2");
1490MODULE_ALIAS("platform:cs47l15-codec");
diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c
index e3585c1dab3d..d396a8545d51 100644
--- a/sound/soc/codecs/cs47l35.c
+++ b/sound/soc/codecs/cs47l35.c
@@ -524,7 +524,7 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", MADERA_SYSTEM_CLOCK_1, MADERA_SYSCLK_ENA_SHIFT,
524 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 524 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
525SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK, 525SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK,
526 MADERA_OPCLK_ENA_SHIFT, 0, NULL, 0), 526 MADERA_OPCLK_ENA_SHIFT, 0, NULL, 0),
527SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1, 6, 527SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1, MADERA_DSP_CLK_ENA_SHIFT,
528 0, NULL, 0), 528 0, NULL, 0),
529 529
530SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0), 530SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c
index c4ecb0e6911a..67cac60a859d 100644
--- a/sound/soc/codecs/cs47l90.c
+++ b/sound/soc/codecs/cs47l90.c
@@ -2402,13 +2402,6 @@ static irqreturn_t cs47l90_adsp2_irq(int irq, void *data)
2402 return IRQ_HANDLED; 2402 return IRQ_HANDLED;
2403} 2403}
2404 2404
2405static irqreturn_t cs47l90_dsp_bus_error(int irq, void *data)
2406{
2407 struct wm_adsp *dsp = (struct wm_adsp *)data;
2408
2409 return wm_adsp2_bus_error(dsp);
2410}
2411
2412static int cs47l90_component_probe(struct snd_soc_component *component) 2405static int cs47l90_component_probe(struct snd_soc_component *component)
2413{ 2406{
2414 struct cs47l90 *cs47l90 = snd_soc_component_get_drvdata(component); 2407 struct cs47l90 *cs47l90 = snd_soc_component_get_drvdata(component);
@@ -2558,7 +2551,7 @@ static int cs47l90_probe(struct platform_device *pdev)
2558 2551
2559 if (ret == 0) { 2552 if (ret == 0) {
2560 ret = madera_init_bus_error_irq(&cs47l90->core, i, 2553 ret = madera_init_bus_error_irq(&cs47l90->core, i,
2561 cs47l90_dsp_bus_error); 2554 wm_adsp2_bus_error);
2562 if (ret != 0) 2555 if (ret != 0)
2563 wm_adsp2_remove(&cs47l90->core.adsp[i]); 2556 wm_adsp2_remove(&cs47l90->core.adsp[i]);
2564 } 2557 }
diff --git a/sound/soc/codecs/cs47l92.c b/sound/soc/codecs/cs47l92.c
new file mode 100644
index 000000000000..d50f75f3b3e4
--- /dev/null
+++ b/sound/soc/codecs/cs47l92.c
@@ -0,0 +1,2039 @@
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// ALSA SoC Audio driver for CS47L92 codec
4//
5// Copyright (C) 2016-2019 Cirrus Logic, Inc. and
6// Cirrus Logic International Semiconductor Ltd.
7//
8
9#include <linux/module.h>
10#include <linux/moduleparam.h>
11#include <linux/device.h>
12#include <linux/delay.h>
13#include <linux/init.h>
14#include <linux/pm.h>
15#include <linux/pm_runtime.h>
16#include <linux/regmap.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/tlv.h>
22
23#include <linux/irqchip/irq-madera.h>
24#include <linux/mfd/madera/core.h>
25#include <linux/mfd/madera/registers.h>
26
27#include "madera.h"
28#include "wm_adsp.h"
29
30#define CS47L92_NUM_ADSP 1
31#define CS47L92_MONO_OUTPUTS 3
32
33#define DRV_NAME "cs47l92-codec"
34
35struct cs47l92 {
36 struct madera_priv core;
37 struct madera_fll fll[2];
38};
39
40static const struct wm_adsp_region cs47l92_dsp1_regions[] = {
41 { .type = WMFW_ADSP2_PM, .base = 0x080000 },
42 { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 },
43 { .type = WMFW_ADSP2_XM, .base = 0x0a0000 },
44 { .type = WMFW_ADSP2_YM, .base = 0x0c0000 },
45};
46
47static const char * const cs47l92_outdemux_texts[] = {
48 "HPOUT3",
49 "HPOUT4",
50};
51
52static int cs47l92_put_demux(struct snd_kcontrol *kcontrol,
53 struct snd_ctl_elem_value *ucontrol)
54{
55 struct snd_soc_component *component =
56 snd_soc_dapm_kcontrol_component(kcontrol);
57 struct snd_soc_dapm_context *dapm =
58 snd_soc_component_get_dapm(component);
59 struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component);
60 struct madera_priv *priv = &cs47l92->core;
61 struct madera *madera = priv->madera;
62 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
63 unsigned int ep_sel, mux, change, cur;
64 bool out_mono;
65 int ret;
66
67 if (ucontrol->value.enumerated.item[0] > e->items - 1)
68 return -EINVAL;
69
70 mux = ucontrol->value.enumerated.item[0];
71
72 snd_soc_dapm_mutex_lock(dapm);
73
74 ep_sel = mux << e->shift_l;
75
76 change = snd_soc_component_test_bits(component, MADERA_OUTPUT_ENABLES_1,
77 MADERA_EP_SEL_MASK,
78 ep_sel);
79 if (!change)
80 goto end;
81
82 ret = regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &cur);
83 if (ret != 0)
84 dev_warn(madera->dev, "Failed to read outputs: %d\n", ret);
85
86 /* EP_SEL should not be modified while HPOUT3 or 4 is enabled */
87 ret = regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1,
88 MADERA_OUT3L_ENA | MADERA_OUT3R_ENA, 0);
89 if (ret)
90 dev_warn(madera->dev, "Failed to disable outputs: %d\n", ret);
91
92 usleep_range(2000, 3000); /* wait for wseq to complete */
93
94 ret = regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1,
95 MADERA_EP_SEL, ep_sel);
96 if (ret) {
97 dev_err(madera->dev, "Failed to set OUT3 demux: %d\n", ret);
98 } else {
99 out_mono = madera->pdata.codec.out_mono[2 + mux];
100
101 ret = madera_set_output_mode(component, 3, out_mono);
102 if (ret < 0)
103 dev_warn(madera->dev,
104 "Failed to set output mode: %d\n", ret);
105 }
106
107 ret = regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1,
108 MADERA_OUT3L_ENA | MADERA_OUT3R_ENA, cur);
109 if (ret) {
110 dev_warn(madera->dev, "Failed to restore outputs: %d\n", ret);
111 } else {
112 /* wait for wseq */
113 if (cur & (MADERA_OUT3L_ENA | MADERA_OUT3R_ENA))
114 msleep(34); /* enable delay */
115 else
116 usleep_range(2000, 3000); /* disable delay */
117 }
118
119end:
120 snd_soc_dapm_mutex_unlock(dapm);
121
122 return snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL);
123}
124
125static SOC_ENUM_SINGLE_DECL(cs47l92_outdemux_enum,
126 MADERA_OUTPUT_ENABLES_1,
127 MADERA_EP_SEL_SHIFT,
128 cs47l92_outdemux_texts);
129
130static const struct snd_kcontrol_new cs47l92_outdemux =
131 SOC_DAPM_ENUM_EXT("OUT3 Demux", cs47l92_outdemux_enum,
132 snd_soc_dapm_get_enum_double, cs47l92_put_demux);
133
134static int cs47l92_adsp_power_ev(struct snd_soc_dapm_widget *w,
135 struct snd_kcontrol *kcontrol,
136 int event)
137{
138 struct snd_soc_component *component =
139 snd_soc_dapm_to_component(w->dapm);
140 struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component);
141 struct madera_priv *priv = &cs47l92->core;
142 struct madera *madera = priv->madera;
143 unsigned int freq;
144 int ret;
145
146 ret = regmap_read(madera->regmap, MADERA_DSP_CLOCK_2, &freq);
147 if (ret != 0) {
148 dev_err(madera->dev,
149 "Failed to read MADERA_DSP_CLOCK_2: %d\n", ret);
150 return ret;
151 }
152
153 switch (event) {
154 case SND_SOC_DAPM_PRE_PMU:
155 ret = madera_set_adsp_clk(&cs47l92->core, w->shift, freq);
156 if (ret)
157 return ret;
158 break;
159 default:
160 break;
161 }
162
163 return wm_adsp_early_event(w, kcontrol, event);
164}
165
166#define CS47L92_NG_SRC(name, base) \
167 SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \
168 SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \
169 SOC_SINGLE(name " NG HPOUT2L Switch", base, 2, 1, 0), \
170 SOC_SINGLE(name " NG HPOUT2R Switch", base, 3, 1, 0), \
171 SOC_SINGLE(name " NG HPOUT3L Switch", base, 4, 1, 0), \
172 SOC_SINGLE(name " NG HPOUT3R Switch", base, 5, 1, 0), \
173 SOC_SINGLE(name " NG SPKDAT1L Switch", base, 8, 1, 0), \
174 SOC_SINGLE(name " NG SPKDAT1R Switch", base, 9, 1, 0)
175
176static const struct snd_kcontrol_new cs47l92_snd_controls[] = {
177SOC_ENUM("IN1 OSR", madera_in_dmic_osr[0]),
178SOC_ENUM("IN2 OSR", madera_in_dmic_osr[1]),
179SOC_ENUM("IN3 OSR", madera_in_dmic_osr[2]),
180SOC_ENUM("IN4 OSR", madera_in_dmic_osr[3]),
181
182SOC_SINGLE_RANGE_TLV("IN1L Volume", MADERA_IN1L_CONTROL,
183 MADERA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
184SOC_SINGLE_RANGE_TLV("IN1R Volume", MADERA_IN1R_CONTROL,
185 MADERA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
186SOC_SINGLE_RANGE_TLV("IN2L Volume", MADERA_IN2L_CONTROL,
187 MADERA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
188SOC_SINGLE_RANGE_TLV("IN2R Volume", MADERA_IN2R_CONTROL,
189 MADERA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, madera_ana_tlv),
190
191SOC_ENUM("IN HPF Cutoff Frequency", madera_in_hpf_cut_enum),
192
193SOC_SINGLE_EXT("IN1L LP Switch", MADERA_ADC_DIGITAL_VOLUME_1L,
194 MADERA_IN1L_LP_MODE_SHIFT, 1, 0,
195 snd_soc_get_volsw, madera_lp_mode_put),
196SOC_SINGLE_EXT("IN1R LP Switch", MADERA_ADC_DIGITAL_VOLUME_1R,
197 MADERA_IN1L_LP_MODE_SHIFT, 1, 0,
198 snd_soc_get_volsw, madera_lp_mode_put),
199SOC_SINGLE_EXT("IN2L LP Switch", MADERA_ADC_DIGITAL_VOLUME_2L,
200 MADERA_IN1L_LP_MODE_SHIFT, 1, 0,
201 snd_soc_get_volsw, madera_lp_mode_put),
202SOC_SINGLE_EXT("IN2R LP Switch", MADERA_ADC_DIGITAL_VOLUME_2R,
203 MADERA_IN1L_LP_MODE_SHIFT, 1, 0,
204 snd_soc_get_volsw, madera_lp_mode_put),
205
206SOC_SINGLE("IN1L HPF Switch", MADERA_IN1L_CONTROL,
207 MADERA_IN1L_HPF_SHIFT, 1, 0),
208SOC_SINGLE("IN1R HPF Switch", MADERA_IN1R_CONTROL,
209 MADERA_IN1R_HPF_SHIFT, 1, 0),
210SOC_SINGLE("IN2L HPF Switch", MADERA_IN2L_CONTROL,
211 MADERA_IN2L_HPF_SHIFT, 1, 0),
212SOC_SINGLE("IN2R HPF Switch", MADERA_IN2R_CONTROL,
213 MADERA_IN2R_HPF_SHIFT, 1, 0),
214SOC_SINGLE("IN3L HPF Switch", MADERA_IN3L_CONTROL,
215 MADERA_IN3L_HPF_SHIFT, 1, 0),
216SOC_SINGLE("IN3R HPF Switch", MADERA_IN3R_CONTROL,
217 MADERA_IN3R_HPF_SHIFT, 1, 0),
218SOC_SINGLE("IN4L HPF Switch", MADERA_IN4L_CONTROL,
219 MADERA_IN4L_HPF_SHIFT, 1, 0),
220SOC_SINGLE("IN4R HPF Switch", MADERA_IN4R_CONTROL,
221 MADERA_IN4R_HPF_SHIFT, 1, 0),
222
223SOC_SINGLE_TLV("IN1L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1L,
224 MADERA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
225SOC_SINGLE_TLV("IN1R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_1R,
226 MADERA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
227SOC_SINGLE_TLV("IN2L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2L,
228 MADERA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
229SOC_SINGLE_TLV("IN2R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_2R,
230 MADERA_IN2R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
231SOC_SINGLE_TLV("IN3L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_3L,
232 MADERA_IN3L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
233SOC_SINGLE_TLV("IN3R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_3R,
234 MADERA_IN3R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
235SOC_SINGLE_TLV("IN4L Digital Volume", MADERA_ADC_DIGITAL_VOLUME_4L,
236 MADERA_IN4L_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
237SOC_SINGLE_TLV("IN4R Digital Volume", MADERA_ADC_DIGITAL_VOLUME_4R,
238 MADERA_IN4R_DIG_VOL_SHIFT, 0xbf, 0, madera_digital_tlv),
239
240SOC_ENUM("Input Ramp Up", madera_in_vi_ramp),
241SOC_ENUM("Input Ramp Down", madera_in_vd_ramp),
242
243MADERA_MIXER_CONTROLS("EQ1", MADERA_EQ1MIX_INPUT_1_SOURCE),
244MADERA_MIXER_CONTROLS("EQ2", MADERA_EQ2MIX_INPUT_1_SOURCE),
245MADERA_MIXER_CONTROLS("EQ3", MADERA_EQ3MIX_INPUT_1_SOURCE),
246MADERA_MIXER_CONTROLS("EQ4", MADERA_EQ4MIX_INPUT_1_SOURCE),
247
248MADERA_EQ_CONTROL("EQ1 Coefficients", MADERA_EQ1_2),
249SOC_SINGLE_TLV("EQ1 B1 Volume", MADERA_EQ1_1, MADERA_EQ1_B1_GAIN_SHIFT,
250 24, 0, madera_eq_tlv),
251SOC_SINGLE_TLV("EQ1 B2 Volume", MADERA_EQ1_1, MADERA_EQ1_B2_GAIN_SHIFT,
252 24, 0, madera_eq_tlv),
253SOC_SINGLE_TLV("EQ1 B3 Volume", MADERA_EQ1_1, MADERA_EQ1_B3_GAIN_SHIFT,
254 24, 0, madera_eq_tlv),
255SOC_SINGLE_TLV("EQ1 B4 Volume", MADERA_EQ1_2, MADERA_EQ1_B4_GAIN_SHIFT,
256 24, 0, madera_eq_tlv),
257SOC_SINGLE_TLV("EQ1 B5 Volume", MADERA_EQ1_2, MADERA_EQ1_B5_GAIN_SHIFT,
258 24, 0, madera_eq_tlv),
259
260MADERA_EQ_CONTROL("EQ2 Coefficients", MADERA_EQ2_2),
261SOC_SINGLE_TLV("EQ2 B1 Volume", MADERA_EQ2_1, MADERA_EQ2_B1_GAIN_SHIFT,
262 24, 0, madera_eq_tlv),
263SOC_SINGLE_TLV("EQ2 B2 Volume", MADERA_EQ2_1, MADERA_EQ2_B2_GAIN_SHIFT,
264 24, 0, madera_eq_tlv),
265SOC_SINGLE_TLV("EQ2 B3 Volume", MADERA_EQ2_1, MADERA_EQ2_B3_GAIN_SHIFT,
266 24, 0, madera_eq_tlv),
267SOC_SINGLE_TLV("EQ2 B4 Volume", MADERA_EQ2_2, MADERA_EQ2_B4_GAIN_SHIFT,
268 24, 0, madera_eq_tlv),
269SOC_SINGLE_TLV("EQ2 B5 Volume", MADERA_EQ2_2, MADERA_EQ2_B5_GAIN_SHIFT,
270 24, 0, madera_eq_tlv),
271
272MADERA_EQ_CONTROL("EQ3 Coefficients", MADERA_EQ3_2),
273SOC_SINGLE_TLV("EQ3 B1 Volume", MADERA_EQ3_1, MADERA_EQ3_B1_GAIN_SHIFT,
274 24, 0, madera_eq_tlv),
275SOC_SINGLE_TLV("EQ3 B2 Volume", MADERA_EQ3_1, MADERA_EQ3_B2_GAIN_SHIFT,
276 24, 0, madera_eq_tlv),
277SOC_SINGLE_TLV("EQ3 B3 Volume", MADERA_EQ3_1, MADERA_EQ3_B3_GAIN_SHIFT,
278 24, 0, madera_eq_tlv),
279SOC_SINGLE_TLV("EQ3 B4 Volume", MADERA_EQ3_2, MADERA_EQ3_B4_GAIN_SHIFT,
280 24, 0, madera_eq_tlv),
281SOC_SINGLE_TLV("EQ3 B5 Volume", MADERA_EQ3_2, MADERA_EQ3_B5_GAIN_SHIFT,
282 24, 0, madera_eq_tlv),
283
284MADERA_EQ_CONTROL("EQ4 Coefficients", MADERA_EQ4_2),
285SOC_SINGLE_TLV("EQ4 B1 Volume", MADERA_EQ4_1, MADERA_EQ4_B1_GAIN_SHIFT,
286 24, 0, madera_eq_tlv),
287SOC_SINGLE_TLV("EQ4 B2 Volume", MADERA_EQ4_1, MADERA_EQ4_B2_GAIN_SHIFT,
288 24, 0, madera_eq_tlv),
289SOC_SINGLE_TLV("EQ4 B3 Volume", MADERA_EQ4_1, MADERA_EQ4_B3_GAIN_SHIFT,
290 24, 0, madera_eq_tlv),
291SOC_SINGLE_TLV("EQ4 B4 Volume", MADERA_EQ4_2, MADERA_EQ4_B4_GAIN_SHIFT,
292 24, 0, madera_eq_tlv),
293SOC_SINGLE_TLV("EQ4 B5 Volume", MADERA_EQ4_2, MADERA_EQ4_B5_GAIN_SHIFT,
294 24, 0, madera_eq_tlv),
295
296SOC_SINGLE("DAC High Performance Mode Switch", MADERA_OUTPUT_RATE_1,
297 MADERA_CP_DAC_MODE_SHIFT, 1, 0),
298
299MADERA_MIXER_CONTROLS("DRC1L", MADERA_DRC1LMIX_INPUT_1_SOURCE),
300MADERA_MIXER_CONTROLS("DRC1R", MADERA_DRC1RMIX_INPUT_1_SOURCE),
301MADERA_MIXER_CONTROLS("DRC2L", MADERA_DRC2LMIX_INPUT_1_SOURCE),
302MADERA_MIXER_CONTROLS("DRC2R", MADERA_DRC2RMIX_INPUT_1_SOURCE),
303
304SND_SOC_BYTES_MASK("DRC1", MADERA_DRC1_CTRL1, 5,
305 MADERA_DRC1R_ENA | MADERA_DRC1L_ENA),
306SND_SOC_BYTES_MASK("DRC2", MADERA_DRC2_CTRL1, 5,
307 MADERA_DRC2R_ENA | MADERA_DRC2L_ENA),
308
309MADERA_MIXER_CONTROLS("LHPF1", MADERA_HPLP1MIX_INPUT_1_SOURCE),
310MADERA_MIXER_CONTROLS("LHPF2", MADERA_HPLP2MIX_INPUT_1_SOURCE),
311MADERA_MIXER_CONTROLS("LHPF3", MADERA_HPLP3MIX_INPUT_1_SOURCE),
312MADERA_MIXER_CONTROLS("LHPF4", MADERA_HPLP4MIX_INPUT_1_SOURCE),
313
314MADERA_LHPF_CONTROL("LHPF1 Coefficients", MADERA_HPLPF1_2),
315MADERA_LHPF_CONTROL("LHPF2 Coefficients", MADERA_HPLPF2_2),
316MADERA_LHPF_CONTROL("LHPF3 Coefficients", MADERA_HPLPF3_2),
317MADERA_LHPF_CONTROL("LHPF4 Coefficients", MADERA_HPLPF4_2),
318
319SOC_ENUM("LHPF1 Mode", madera_lhpf1_mode),
320SOC_ENUM("LHPF2 Mode", madera_lhpf2_mode),
321SOC_ENUM("LHPF3 Mode", madera_lhpf3_mode),
322SOC_ENUM("LHPF4 Mode", madera_lhpf4_mode),
323
324MADERA_RATE_ENUM("ISRC1 FSL", madera_isrc_fsl[0]),
325MADERA_RATE_ENUM("ISRC2 FSL", madera_isrc_fsl[1]),
326MADERA_RATE_ENUM("ISRC1 FSH", madera_isrc_fsh[0]),
327MADERA_RATE_ENUM("ISRC2 FSH", madera_isrc_fsh[1]),
328MADERA_RATE_ENUM("ASRC1 Rate 1", madera_asrc1_bidir_rate[0]),
329MADERA_RATE_ENUM("ASRC1 Rate 2", madera_asrc1_bidir_rate[1]),
330
331WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
332
333MADERA_MIXER_CONTROLS("DSP1L", MADERA_DSP1LMIX_INPUT_1_SOURCE),
334MADERA_MIXER_CONTROLS("DSP1R", MADERA_DSP1RMIX_INPUT_1_SOURCE),
335
336SOC_SINGLE_TLV("Noise Generator Volume", MADERA_COMFORT_NOISE_GENERATOR,
337 MADERA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, madera_noise_tlv),
338
339MADERA_MIXER_CONTROLS("HPOUT1L", MADERA_OUT1LMIX_INPUT_1_SOURCE),
340MADERA_MIXER_CONTROLS("HPOUT1R", MADERA_OUT1RMIX_INPUT_1_SOURCE),
341MADERA_MIXER_CONTROLS("HPOUT2L", MADERA_OUT2LMIX_INPUT_1_SOURCE),
342MADERA_MIXER_CONTROLS("HPOUT2R", MADERA_OUT2RMIX_INPUT_1_SOURCE),
343MADERA_MIXER_CONTROLS("HPOUT3L", MADERA_OUT3LMIX_INPUT_1_SOURCE),
344MADERA_MIXER_CONTROLS("HPOUT3R", MADERA_OUT3RMIX_INPUT_1_SOURCE),
345MADERA_MIXER_CONTROLS("SPKDAT1L", MADERA_OUT5LMIX_INPUT_1_SOURCE),
346MADERA_MIXER_CONTROLS("SPKDAT1R", MADERA_OUT5RMIX_INPUT_1_SOURCE),
347
348SOC_SINGLE("HPOUT1 SC Protect Switch", MADERA_HP1_SHORT_CIRCUIT_CTRL,
349 MADERA_HP1_SC_ENA_SHIFT, 1, 0),
350SOC_SINGLE("HPOUT2 SC Protect Switch", MADERA_HP2_SHORT_CIRCUIT_CTRL,
351 MADERA_HP2_SC_ENA_SHIFT, 1, 0),
352SOC_SINGLE("HPOUT3 SC Protect Switch", MADERA_HP3_SHORT_CIRCUIT_CTRL,
353 MADERA_HP3_SC_ENA_SHIFT, 1, 0),
354
355SOC_SINGLE("SPKDAT1 High Performance Switch", MADERA_OUTPUT_PATH_CONFIG_5L,
356 MADERA_OUT5_OSR_SHIFT, 1, 0),
357
358SOC_DOUBLE_R("HPOUT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_1L,
359 MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_MUTE_SHIFT, 1, 1),
360SOC_DOUBLE_R("HPOUT2 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_2L,
361 MADERA_DAC_DIGITAL_VOLUME_2R, MADERA_OUT2L_MUTE_SHIFT, 1, 1),
362SOC_DOUBLE_R("HPOUT3 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_3L,
363 MADERA_DAC_DIGITAL_VOLUME_3R, MADERA_OUT3L_MUTE_SHIFT, 1, 1),
364SOC_DOUBLE_R("SPKDAT1 Digital Switch", MADERA_DAC_DIGITAL_VOLUME_5L,
365 MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_MUTE_SHIFT, 1, 1),
366
367SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_1L,
368 MADERA_DAC_DIGITAL_VOLUME_1R, MADERA_OUT1L_VOL_SHIFT,
369 0xbf, 0, madera_digital_tlv),
370SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_2L,
371 MADERA_DAC_DIGITAL_VOLUME_2R, MADERA_OUT2L_VOL_SHIFT,
372 0xbf, 0, madera_digital_tlv),
373SOC_DOUBLE_R_TLV("HPOUT3 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_3L,
374 MADERA_DAC_DIGITAL_VOLUME_3R, MADERA_OUT3L_VOL_SHIFT,
375 0xbf, 0, madera_digital_tlv),
376SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", MADERA_DAC_DIGITAL_VOLUME_5L,
377 MADERA_DAC_DIGITAL_VOLUME_5R, MADERA_OUT5L_VOL_SHIFT,
378 0xbf, 0, madera_digital_tlv),
379
380SOC_DOUBLE("SPKDAT1 Switch", MADERA_PDM_SPK1_CTRL_1, MADERA_SPK1L_MUTE_SHIFT,
381 MADERA_SPK1R_MUTE_SHIFT, 1, 1),
382
383SOC_ENUM("Output Ramp Up", madera_out_vi_ramp),
384SOC_ENUM("Output Ramp Down", madera_out_vd_ramp),
385
386SOC_SINGLE("Noise Gate Switch", MADERA_NOISE_GATE_CONTROL,
387 MADERA_NGATE_ENA_SHIFT, 1, 0),
388SOC_SINGLE_TLV("Noise Gate Threshold Volume", MADERA_NOISE_GATE_CONTROL,
389 MADERA_NGATE_THR_SHIFT, 7, 1, madera_ng_tlv),
390SOC_ENUM("Noise Gate Hold", madera_ng_hold),
391
392SOC_ENUM_EXT("DFC1RX Width", madera_dfc_width[0],
393 snd_soc_get_enum_double, madera_dfc_put),
394SOC_ENUM_EXT("DFC1RX Type", madera_dfc_type[0],
395 snd_soc_get_enum_double, madera_dfc_put),
396SOC_ENUM_EXT("DFC1TX Width", madera_dfc_width[1],
397 snd_soc_get_enum_double, madera_dfc_put),
398SOC_ENUM_EXT("DFC1TX Type", madera_dfc_type[1],
399 snd_soc_get_enum_double, madera_dfc_put),
400SOC_ENUM_EXT("DFC2RX Width", madera_dfc_width[2],
401 snd_soc_get_enum_double, madera_dfc_put),
402SOC_ENUM_EXT("DFC2RX Type", madera_dfc_type[2],
403 snd_soc_get_enum_double, madera_dfc_put),
404SOC_ENUM_EXT("DFC2TX Width", madera_dfc_width[3],
405 snd_soc_get_enum_double, madera_dfc_put),
406SOC_ENUM_EXT("DFC2TX Type", madera_dfc_type[3],
407 snd_soc_get_enum_double, madera_dfc_put),
408SOC_ENUM_EXT("DFC3RX Width", madera_dfc_width[4],
409 snd_soc_get_enum_double, madera_dfc_put),
410SOC_ENUM_EXT("DFC3RX Type", madera_dfc_type[4],
411 snd_soc_get_enum_double, madera_dfc_put),
412SOC_ENUM_EXT("DFC3TX Width", madera_dfc_width[5],
413 snd_soc_get_enum_double, madera_dfc_put),
414SOC_ENUM_EXT("DFC3TX Type", madera_dfc_type[5],
415 snd_soc_get_enum_double, madera_dfc_put),
416SOC_ENUM_EXT("DFC4RX Width", madera_dfc_width[6],
417 snd_soc_get_enum_double, madera_dfc_put),
418SOC_ENUM_EXT("DFC4RX Type", madera_dfc_type[6],
419 snd_soc_get_enum_double, madera_dfc_put),
420SOC_ENUM_EXT("DFC4TX Width", madera_dfc_width[7],
421 snd_soc_get_enum_double, madera_dfc_put),
422SOC_ENUM_EXT("DFC4TX Type", madera_dfc_type[7],
423 snd_soc_get_enum_double, madera_dfc_put),
424SOC_ENUM_EXT("DFC5RX Width", madera_dfc_width[8],
425 snd_soc_get_enum_double, madera_dfc_put),
426SOC_ENUM_EXT("DFC5RX Type", madera_dfc_type[8],
427 snd_soc_get_enum_double, madera_dfc_put),
428SOC_ENUM_EXT("DFC5TX Width", madera_dfc_width[9],
429 snd_soc_get_enum_double, madera_dfc_put),
430SOC_ENUM_EXT("DFC5TX Type", madera_dfc_type[9],
431 snd_soc_get_enum_double, madera_dfc_put),
432SOC_ENUM_EXT("DFC6RX Width", madera_dfc_width[10],
433 snd_soc_get_enum_double, madera_dfc_put),
434SOC_ENUM_EXT("DFC6RX Type", madera_dfc_type[10],
435 snd_soc_get_enum_double, madera_dfc_put),
436SOC_ENUM_EXT("DFC6TX Width", madera_dfc_width[11],
437 snd_soc_get_enum_double, madera_dfc_put),
438SOC_ENUM_EXT("DFC6TX Type", madera_dfc_type[11],
439 snd_soc_get_enum_double, madera_dfc_put),
440SOC_ENUM_EXT("DFC7RX Width", madera_dfc_width[12],
441 snd_soc_get_enum_double, madera_dfc_put),
442SOC_ENUM_EXT("DFC7RX Type", madera_dfc_type[12],
443 snd_soc_get_enum_double, madera_dfc_put),
444SOC_ENUM_EXT("DFC7TX Width", madera_dfc_width[13],
445 snd_soc_get_enum_double, madera_dfc_put),
446SOC_ENUM_EXT("DFC7TX Type", madera_dfc_type[13],
447 snd_soc_get_enum_double, madera_dfc_put),
448SOC_ENUM_EXT("DFC8RX Width", madera_dfc_width[14],
449 snd_soc_get_enum_double, madera_dfc_put),
450SOC_ENUM_EXT("DFC8RX Type", madera_dfc_type[14],
451 snd_soc_get_enum_double, madera_dfc_put),
452SOC_ENUM_EXT("DFC8TX Width", madera_dfc_width[15],
453 snd_soc_get_enum_double, madera_dfc_put),
454SOC_ENUM_EXT("DFC8TX Type", madera_dfc_type[15],
455 snd_soc_get_enum_double, madera_dfc_put),
456
457CS47L92_NG_SRC("HPOUT1L", MADERA_NOISE_GATE_SELECT_1L),
458CS47L92_NG_SRC("HPOUT1R", MADERA_NOISE_GATE_SELECT_1R),
459CS47L92_NG_SRC("HPOUT2L", MADERA_NOISE_GATE_SELECT_2L),
460CS47L92_NG_SRC("HPOUT2R", MADERA_NOISE_GATE_SELECT_2R),
461CS47L92_NG_SRC("HPOUT3L", MADERA_NOISE_GATE_SELECT_3L),
462CS47L92_NG_SRC("HPOUT3R", MADERA_NOISE_GATE_SELECT_3R),
463CS47L92_NG_SRC("SPKDAT1L", MADERA_NOISE_GATE_SELECT_5L),
464CS47L92_NG_SRC("SPKDAT1R", MADERA_NOISE_GATE_SELECT_5R),
465
466MADERA_MIXER_CONTROLS("AIF1TX1", MADERA_AIF1TX1MIX_INPUT_1_SOURCE),
467MADERA_MIXER_CONTROLS("AIF1TX2", MADERA_AIF1TX2MIX_INPUT_1_SOURCE),
468MADERA_MIXER_CONTROLS("AIF1TX3", MADERA_AIF1TX3MIX_INPUT_1_SOURCE),
469MADERA_MIXER_CONTROLS("AIF1TX4", MADERA_AIF1TX4MIX_INPUT_1_SOURCE),
470MADERA_MIXER_CONTROLS("AIF1TX5", MADERA_AIF1TX5MIX_INPUT_1_SOURCE),
471MADERA_MIXER_CONTROLS("AIF1TX6", MADERA_AIF1TX6MIX_INPUT_1_SOURCE),
472MADERA_MIXER_CONTROLS("AIF1TX7", MADERA_AIF1TX7MIX_INPUT_1_SOURCE),
473MADERA_MIXER_CONTROLS("AIF1TX8", MADERA_AIF1TX8MIX_INPUT_1_SOURCE),
474
475MADERA_MIXER_CONTROLS("AIF2TX1", MADERA_AIF2TX1MIX_INPUT_1_SOURCE),
476MADERA_MIXER_CONTROLS("AIF2TX2", MADERA_AIF2TX2MIX_INPUT_1_SOURCE),
477MADERA_MIXER_CONTROLS("AIF2TX3", MADERA_AIF2TX3MIX_INPUT_1_SOURCE),
478MADERA_MIXER_CONTROLS("AIF2TX4", MADERA_AIF2TX4MIX_INPUT_1_SOURCE),
479MADERA_MIXER_CONTROLS("AIF2TX5", MADERA_AIF2TX5MIX_INPUT_1_SOURCE),
480MADERA_MIXER_CONTROLS("AIF2TX6", MADERA_AIF2TX6MIX_INPUT_1_SOURCE),
481MADERA_MIXER_CONTROLS("AIF2TX7", MADERA_AIF2TX7MIX_INPUT_1_SOURCE),
482MADERA_MIXER_CONTROLS("AIF2TX8", MADERA_AIF2TX8MIX_INPUT_1_SOURCE),
483
484MADERA_MIXER_CONTROLS("AIF3TX1", MADERA_AIF3TX1MIX_INPUT_1_SOURCE),
485MADERA_MIXER_CONTROLS("AIF3TX2", MADERA_AIF3TX2MIX_INPUT_1_SOURCE),
486MADERA_MIXER_CONTROLS("AIF3TX3", MADERA_AIF3TX3MIX_INPUT_1_SOURCE),
487MADERA_MIXER_CONTROLS("AIF3TX4", MADERA_AIF3TX4MIX_INPUT_1_SOURCE),
488
489MADERA_MIXER_CONTROLS("SLIMTX1", MADERA_SLIMTX1MIX_INPUT_1_SOURCE),
490MADERA_MIXER_CONTROLS("SLIMTX2", MADERA_SLIMTX2MIX_INPUT_1_SOURCE),
491MADERA_MIXER_CONTROLS("SLIMTX3", MADERA_SLIMTX3MIX_INPUT_1_SOURCE),
492MADERA_MIXER_CONTROLS("SLIMTX4", MADERA_SLIMTX4MIX_INPUT_1_SOURCE),
493MADERA_MIXER_CONTROLS("SLIMTX5", MADERA_SLIMTX5MIX_INPUT_1_SOURCE),
494MADERA_MIXER_CONTROLS("SLIMTX6", MADERA_SLIMTX6MIX_INPUT_1_SOURCE),
495MADERA_MIXER_CONTROLS("SLIMTX7", MADERA_SLIMTX7MIX_INPUT_1_SOURCE),
496MADERA_MIXER_CONTROLS("SLIMTX8", MADERA_SLIMTX8MIX_INPUT_1_SOURCE),
497
498MADERA_GAINMUX_CONTROLS("SPDIFTX1", MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE),
499MADERA_GAINMUX_CONTROLS("SPDIFTX2", MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE),
500
501WM_ADSP_FW_CONTROL("DSP1", 0),
502};
503
504MADERA_MIXER_ENUMS(EQ1, MADERA_EQ1MIX_INPUT_1_SOURCE);
505MADERA_MIXER_ENUMS(EQ2, MADERA_EQ2MIX_INPUT_1_SOURCE);
506MADERA_MIXER_ENUMS(EQ3, MADERA_EQ3MIX_INPUT_1_SOURCE);
507MADERA_MIXER_ENUMS(EQ4, MADERA_EQ4MIX_INPUT_1_SOURCE);
508
509MADERA_MIXER_ENUMS(DRC1L, MADERA_DRC1LMIX_INPUT_1_SOURCE);
510MADERA_MIXER_ENUMS(DRC1R, MADERA_DRC1RMIX_INPUT_1_SOURCE);
511MADERA_MIXER_ENUMS(DRC2L, MADERA_DRC2LMIX_INPUT_1_SOURCE);
512MADERA_MIXER_ENUMS(DRC2R, MADERA_DRC2RMIX_INPUT_1_SOURCE);
513
514MADERA_MIXER_ENUMS(LHPF1, MADERA_HPLP1MIX_INPUT_1_SOURCE);
515MADERA_MIXER_ENUMS(LHPF2, MADERA_HPLP2MIX_INPUT_1_SOURCE);
516MADERA_MIXER_ENUMS(LHPF3, MADERA_HPLP3MIX_INPUT_1_SOURCE);
517MADERA_MIXER_ENUMS(LHPF4, MADERA_HPLP4MIX_INPUT_1_SOURCE);
518
519MADERA_MIXER_ENUMS(DSP1L, MADERA_DSP1LMIX_INPUT_1_SOURCE);
520MADERA_MIXER_ENUMS(DSP1R, MADERA_DSP1RMIX_INPUT_1_SOURCE);
521MADERA_DSP_AUX_ENUMS(DSP1, MADERA_DSP1AUX1MIX_INPUT_1_SOURCE);
522
523MADERA_MIXER_ENUMS(PWM1, MADERA_PWM1MIX_INPUT_1_SOURCE);
524MADERA_MIXER_ENUMS(PWM2, MADERA_PWM2MIX_INPUT_1_SOURCE);
525
526MADERA_MIXER_ENUMS(OUT1L, MADERA_OUT1LMIX_INPUT_1_SOURCE);
527MADERA_MIXER_ENUMS(OUT1R, MADERA_OUT1RMIX_INPUT_1_SOURCE);
528MADERA_MIXER_ENUMS(OUT2L, MADERA_OUT2LMIX_INPUT_1_SOURCE);
529MADERA_MIXER_ENUMS(OUT2R, MADERA_OUT2RMIX_INPUT_1_SOURCE);
530MADERA_MIXER_ENUMS(OUT3L, MADERA_OUT3LMIX_INPUT_1_SOURCE);
531MADERA_MIXER_ENUMS(OUT3R, MADERA_OUT3RMIX_INPUT_1_SOURCE);
532MADERA_MIXER_ENUMS(SPKDAT1L, MADERA_OUT5LMIX_INPUT_1_SOURCE);
533MADERA_MIXER_ENUMS(SPKDAT1R, MADERA_OUT5RMIX_INPUT_1_SOURCE);
534
535MADERA_MIXER_ENUMS(AIF1TX1, MADERA_AIF1TX1MIX_INPUT_1_SOURCE);
536MADERA_MIXER_ENUMS(AIF1TX2, MADERA_AIF1TX2MIX_INPUT_1_SOURCE);
537MADERA_MIXER_ENUMS(AIF1TX3, MADERA_AIF1TX3MIX_INPUT_1_SOURCE);
538MADERA_MIXER_ENUMS(AIF1TX4, MADERA_AIF1TX4MIX_INPUT_1_SOURCE);
539MADERA_MIXER_ENUMS(AIF1TX5, MADERA_AIF1TX5MIX_INPUT_1_SOURCE);
540MADERA_MIXER_ENUMS(AIF1TX6, MADERA_AIF1TX6MIX_INPUT_1_SOURCE);
541MADERA_MIXER_ENUMS(AIF1TX7, MADERA_AIF1TX7MIX_INPUT_1_SOURCE);
542MADERA_MIXER_ENUMS(AIF1TX8, MADERA_AIF1TX8MIX_INPUT_1_SOURCE);
543
544MADERA_MIXER_ENUMS(AIF2TX1, MADERA_AIF2TX1MIX_INPUT_1_SOURCE);
545MADERA_MIXER_ENUMS(AIF2TX2, MADERA_AIF2TX2MIX_INPUT_1_SOURCE);
546MADERA_MIXER_ENUMS(AIF2TX3, MADERA_AIF2TX3MIX_INPUT_1_SOURCE);
547MADERA_MIXER_ENUMS(AIF2TX4, MADERA_AIF2TX4MIX_INPUT_1_SOURCE);
548MADERA_MIXER_ENUMS(AIF2TX5, MADERA_AIF2TX5MIX_INPUT_1_SOURCE);
549MADERA_MIXER_ENUMS(AIF2TX6, MADERA_AIF2TX6MIX_INPUT_1_SOURCE);
550MADERA_MIXER_ENUMS(AIF2TX7, MADERA_AIF2TX7MIX_INPUT_1_SOURCE);
551MADERA_MIXER_ENUMS(AIF2TX8, MADERA_AIF2TX8MIX_INPUT_1_SOURCE);
552
553MADERA_MIXER_ENUMS(AIF3TX1, MADERA_AIF3TX1MIX_INPUT_1_SOURCE);
554MADERA_MIXER_ENUMS(AIF3TX2, MADERA_AIF3TX2MIX_INPUT_1_SOURCE);
555MADERA_MIXER_ENUMS(AIF3TX3, MADERA_AIF3TX3MIX_INPUT_1_SOURCE);
556MADERA_MIXER_ENUMS(AIF3TX4, MADERA_AIF3TX4MIX_INPUT_1_SOURCE);
557
558MADERA_MIXER_ENUMS(SLIMTX1, MADERA_SLIMTX1MIX_INPUT_1_SOURCE);
559MADERA_MIXER_ENUMS(SLIMTX2, MADERA_SLIMTX2MIX_INPUT_1_SOURCE);
560MADERA_MIXER_ENUMS(SLIMTX3, MADERA_SLIMTX3MIX_INPUT_1_SOURCE);
561MADERA_MIXER_ENUMS(SLIMTX4, MADERA_SLIMTX4MIX_INPUT_1_SOURCE);
562MADERA_MIXER_ENUMS(SLIMTX5, MADERA_SLIMTX5MIX_INPUT_1_SOURCE);
563MADERA_MIXER_ENUMS(SLIMTX6, MADERA_SLIMTX6MIX_INPUT_1_SOURCE);
564MADERA_MIXER_ENUMS(SLIMTX7, MADERA_SLIMTX7MIX_INPUT_1_SOURCE);
565MADERA_MIXER_ENUMS(SLIMTX8, MADERA_SLIMTX8MIX_INPUT_1_SOURCE);
566
567MADERA_MUX_ENUMS(SPD1TX1, MADERA_SPDIF1TX1MIX_INPUT_1_SOURCE);
568MADERA_MUX_ENUMS(SPD1TX2, MADERA_SPDIF1TX2MIX_INPUT_1_SOURCE);
569
570MADERA_MUX_ENUMS(ASRC1IN1L, MADERA_ASRC1_1LMIX_INPUT_1_SOURCE);
571MADERA_MUX_ENUMS(ASRC1IN1R, MADERA_ASRC1_1RMIX_INPUT_1_SOURCE);
572MADERA_MUX_ENUMS(ASRC1IN2L, MADERA_ASRC1_2LMIX_INPUT_1_SOURCE);
573MADERA_MUX_ENUMS(ASRC1IN2R, MADERA_ASRC1_2RMIX_INPUT_1_SOURCE);
574
575MADERA_MUX_ENUMS(ISRC1INT1, MADERA_ISRC1INT1MIX_INPUT_1_SOURCE);
576MADERA_MUX_ENUMS(ISRC1INT2, MADERA_ISRC1INT2MIX_INPUT_1_SOURCE);
577
578MADERA_MUX_ENUMS(ISRC1DEC1, MADERA_ISRC1DEC1MIX_INPUT_1_SOURCE);
579MADERA_MUX_ENUMS(ISRC1DEC2, MADERA_ISRC1DEC2MIX_INPUT_1_SOURCE);
580
581MADERA_MUX_ENUMS(ISRC2INT1, MADERA_ISRC2INT1MIX_INPUT_1_SOURCE);
582MADERA_MUX_ENUMS(ISRC2INT2, MADERA_ISRC2INT2MIX_INPUT_1_SOURCE);
583
584MADERA_MUX_ENUMS(ISRC2DEC1, MADERA_ISRC2DEC1MIX_INPUT_1_SOURCE);
585MADERA_MUX_ENUMS(ISRC2DEC2, MADERA_ISRC2DEC2MIX_INPUT_1_SOURCE);
586
587MADERA_MUX_ENUMS(DFC1, MADERA_DFC1MIX_INPUT_1_SOURCE);
588MADERA_MUX_ENUMS(DFC2, MADERA_DFC2MIX_INPUT_1_SOURCE);
589MADERA_MUX_ENUMS(DFC3, MADERA_DFC3MIX_INPUT_1_SOURCE);
590MADERA_MUX_ENUMS(DFC4, MADERA_DFC4MIX_INPUT_1_SOURCE);
591MADERA_MUX_ENUMS(DFC5, MADERA_DFC5MIX_INPUT_1_SOURCE);
592MADERA_MUX_ENUMS(DFC6, MADERA_DFC6MIX_INPUT_1_SOURCE);
593MADERA_MUX_ENUMS(DFC7, MADERA_DFC7MIX_INPUT_1_SOURCE);
594MADERA_MUX_ENUMS(DFC8, MADERA_DFC8MIX_INPUT_1_SOURCE);
595
596static const char * const cs47l92_aec_loopback_texts[] = {
597 "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R",
598 "SPKDAT1L", "SPKDAT1R",
599};
600
601static const unsigned int cs47l92_aec_loopback_values[] = {
602 0, 1, 2, 3, 4, 5, 8, 9
603};
604
605static const struct soc_enum cs47l92_aec_loopback =
606 SOC_VALUE_ENUM_SINGLE(MADERA_DAC_AEC_CONTROL_1,
607 MADERA_AEC1_LOOPBACK_SRC_SHIFT, 0xf,
608 ARRAY_SIZE(cs47l92_aec_loopback_texts),
609 cs47l92_aec_loopback_texts,
610 cs47l92_aec_loopback_values);
611
612static const struct snd_kcontrol_new cs47l92_aec_loopback_mux =
613 SOC_DAPM_ENUM("AEC1 Loopback", cs47l92_aec_loopback);
614
615static const struct snd_soc_dapm_widget cs47l92_dapm_widgets[] = {
616SND_SOC_DAPM_SUPPLY("SYSCLK", MADERA_SYSTEM_CLOCK_1, MADERA_SYSCLK_ENA_SHIFT,
617 0, madera_sysclk_ev,
618 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
619SND_SOC_DAPM_SUPPLY("ASYNCCLK", MADERA_ASYNC_CLOCK_1,
620 MADERA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
621SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK,
622 MADERA_OPCLK_ENA_SHIFT, 0, NULL, 0),
623SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", MADERA_OUTPUT_ASYNC_CLOCK,
624 MADERA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
625SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1,
626 MADERA_DSP_CLK_ENA_SHIFT, 0, NULL, 0),
627
628SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD1", 20, 0),
629SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD2", 20, 0),
630SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
631
632SND_SOC_DAPM_SUPPLY("MICBIAS1", MADERA_MIC_BIAS_CTRL_1,
633 MADERA_MICB1_ENA_SHIFT, 0, NULL, 0),
634SND_SOC_DAPM_SUPPLY("MICBIAS2", MADERA_MIC_BIAS_CTRL_2,
635 MADERA_MICB1_ENA_SHIFT, 0, NULL, 0),
636
637SND_SOC_DAPM_SUPPLY("MICBIAS1A", MADERA_MIC_BIAS_CTRL_5,
638 MADERA_MICB1A_ENA_SHIFT, 0, NULL, 0),
639SND_SOC_DAPM_SUPPLY("MICBIAS1B", MADERA_MIC_BIAS_CTRL_5,
640 MADERA_MICB1B_ENA_SHIFT, 0, NULL, 0),
641SND_SOC_DAPM_SUPPLY("MICBIAS1C", MADERA_MIC_BIAS_CTRL_5,
642 MADERA_MICB1C_ENA_SHIFT, 0, NULL, 0),
643SND_SOC_DAPM_SUPPLY("MICBIAS1D", MADERA_MIC_BIAS_CTRL_5,
644 MADERA_MICB1D_ENA_SHIFT, 0, NULL, 0),
645
646SND_SOC_DAPM_SUPPLY("MICBIAS2A", MADERA_MIC_BIAS_CTRL_6,
647 MADERA_MICB2A_ENA_SHIFT, 0, NULL, 0),
648SND_SOC_DAPM_SUPPLY("MICBIAS2B", MADERA_MIC_BIAS_CTRL_6,
649 MADERA_MICB2B_ENA_SHIFT, 0, NULL, 0),
650
651SND_SOC_DAPM_SUPPLY("FXCLK", SND_SOC_NOPM,
652 MADERA_DOM_GRP_FX, 0,
653 madera_domain_clk_ev,
654 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
655SND_SOC_DAPM_SUPPLY("ASRC1CLK", SND_SOC_NOPM,
656 MADERA_DOM_GRP_ASRC1, 0,
657 madera_domain_clk_ev,
658 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
659SND_SOC_DAPM_SUPPLY("ISRC1CLK", SND_SOC_NOPM,
660 MADERA_DOM_GRP_ISRC1, 0,
661 madera_domain_clk_ev,
662 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
663SND_SOC_DAPM_SUPPLY("ISRC2CLK", SND_SOC_NOPM,
664 MADERA_DOM_GRP_ISRC2, 0,
665 madera_domain_clk_ev,
666 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
667SND_SOC_DAPM_SUPPLY("OUTCLK", SND_SOC_NOPM,
668 MADERA_DOM_GRP_OUT, 0,
669 madera_domain_clk_ev,
670 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
671SND_SOC_DAPM_SUPPLY("SPDCLK", SND_SOC_NOPM,
672 MADERA_DOM_GRP_SPD, 0,
673 madera_domain_clk_ev,
674 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
675SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM,
676 MADERA_DOM_GRP_DSP1, 0,
677 madera_domain_clk_ev,
678 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
679SND_SOC_DAPM_SUPPLY("AIF1TXCLK", SND_SOC_NOPM,
680 MADERA_DOM_GRP_AIF1, 0,
681 madera_domain_clk_ev,
682 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
683SND_SOC_DAPM_SUPPLY("AIF2TXCLK", SND_SOC_NOPM,
684 MADERA_DOM_GRP_AIF2, 0,
685 madera_domain_clk_ev,
686 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
687SND_SOC_DAPM_SUPPLY("AIF3TXCLK", SND_SOC_NOPM,
688 MADERA_DOM_GRP_AIF3, 0,
689 madera_domain_clk_ev,
690 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
691SND_SOC_DAPM_SUPPLY("SLIMBUSCLK", SND_SOC_NOPM,
692 MADERA_DOM_GRP_SLIMBUS, 0,
693 madera_domain_clk_ev,
694 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
695SND_SOC_DAPM_SUPPLY("PWMCLK", SND_SOC_NOPM,
696 MADERA_DOM_GRP_PWM, 0,
697 madera_domain_clk_ev,
698 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
699SND_SOC_DAPM_SUPPLY("DFCCLK", SND_SOC_NOPM,
700 MADERA_DOM_GRP_DFC, 0,
701 madera_domain_clk_ev,
702 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
703
704SND_SOC_DAPM_SIGGEN("TONE"),
705SND_SOC_DAPM_SIGGEN("NOISE"),
706
707SND_SOC_DAPM_INPUT("IN1ALN"),
708SND_SOC_DAPM_INPUT("IN1ALP"),
709SND_SOC_DAPM_INPUT("IN1BLN"),
710SND_SOC_DAPM_INPUT("IN1BLP"),
711SND_SOC_DAPM_INPUT("IN1ARN"),
712SND_SOC_DAPM_INPUT("IN1ARP"),
713SND_SOC_DAPM_INPUT("IN1BR"),
714SND_SOC_DAPM_INPUT("IN2ALN"),
715SND_SOC_DAPM_INPUT("IN2ALP"),
716SND_SOC_DAPM_INPUT("IN2BL"),
717SND_SOC_DAPM_INPUT("IN2ARN"),
718SND_SOC_DAPM_INPUT("IN2ARP"),
719SND_SOC_DAPM_INPUT("IN2BR"),
720
721SND_SOC_DAPM_MUX("IN1L Analog Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[0]),
722SND_SOC_DAPM_MUX("IN1R Analog Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[1]),
723SND_SOC_DAPM_MUX("IN2L Analog Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[2]),
724SND_SOC_DAPM_MUX("IN2R Analog Mux", SND_SOC_NOPM, 0, 0, &madera_inmux[3]),
725
726SND_SOC_DAPM_MUX("IN1L Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[0]),
727SND_SOC_DAPM_MUX("IN1R Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[0]),
728
729SND_SOC_DAPM_MUX("IN2L Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[1]),
730SND_SOC_DAPM_MUX("IN2R Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[1]),
731
732SND_SOC_DAPM_DEMUX("OUT3 Demux", SND_SOC_NOPM, 0, 0, &cs47l92_outdemux),
733
734SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
735SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
736
737SND_SOC_DAPM_PGA("PWM1 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM1_ENA_SHIFT,
738 0, NULL, 0),
739SND_SOC_DAPM_PGA("PWM2 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM2_ENA_SHIFT,
740 0, NULL, 0),
741
742SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
743 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX1_ENA_SHIFT, 0),
744SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
745 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX2_ENA_SHIFT, 0),
746SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
747 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX3_ENA_SHIFT, 0),
748SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
749 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX4_ENA_SHIFT, 0),
750SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
751 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX5_ENA_SHIFT, 0),
752SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
753 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX6_ENA_SHIFT, 0),
754SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0,
755 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX7_ENA_SHIFT, 0),
756SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0,
757 MADERA_AIF1_TX_ENABLES, MADERA_AIF1TX8_ENA_SHIFT, 0),
758
759SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
760 MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX1_ENA_SHIFT, 0),
761SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
762 MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX2_ENA_SHIFT, 0),
763SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0,
764 MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX3_ENA_SHIFT, 0),
765SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0,
766 MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX4_ENA_SHIFT, 0),
767SND_SOC_DAPM_AIF_OUT("AIF2TX5", NULL, 0,
768 MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX5_ENA_SHIFT, 0),
769SND_SOC_DAPM_AIF_OUT("AIF2TX6", NULL, 0,
770 MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX6_ENA_SHIFT, 0),
771SND_SOC_DAPM_AIF_OUT("AIF2TX7", NULL, 0,
772 MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX7_ENA_SHIFT, 0),
773SND_SOC_DAPM_AIF_OUT("AIF2TX8", NULL, 0,
774 MADERA_AIF2_TX_ENABLES, MADERA_AIF2TX8_ENA_SHIFT, 0),
775
776SND_SOC_DAPM_AIF_OUT("SLIMTX1", NULL, 0,
777 MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
778 MADERA_SLIMTX1_ENA_SHIFT, 0),
779SND_SOC_DAPM_AIF_OUT("SLIMTX2", NULL, 0,
780 MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
781 MADERA_SLIMTX2_ENA_SHIFT, 0),
782SND_SOC_DAPM_AIF_OUT("SLIMTX3", NULL, 0,
783 MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
784 MADERA_SLIMTX3_ENA_SHIFT, 0),
785SND_SOC_DAPM_AIF_OUT("SLIMTX4", NULL, 0,
786 MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
787 MADERA_SLIMTX4_ENA_SHIFT, 0),
788SND_SOC_DAPM_AIF_OUT("SLIMTX5", NULL, 0,
789 MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
790 MADERA_SLIMTX5_ENA_SHIFT, 0),
791SND_SOC_DAPM_AIF_OUT("SLIMTX6", NULL, 0,
792 MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
793 MADERA_SLIMTX6_ENA_SHIFT, 0),
794SND_SOC_DAPM_AIF_OUT("SLIMTX7", NULL, 0,
795 MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
796 MADERA_SLIMTX7_ENA_SHIFT, 0),
797SND_SOC_DAPM_AIF_OUT("SLIMTX8", NULL, 0,
798 MADERA_SLIMBUS_TX_CHANNEL_ENABLE,
799 MADERA_SLIMTX8_ENA_SHIFT, 0),
800
801SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
802 MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX1_ENA_SHIFT, 0),
803SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
804 MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX2_ENA_SHIFT, 0),
805SND_SOC_DAPM_AIF_OUT("AIF3TX3", NULL, 0,
806 MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX3_ENA_SHIFT, 0),
807SND_SOC_DAPM_AIF_OUT("AIF3TX4", NULL, 0,
808 MADERA_AIF3_TX_ENABLES, MADERA_AIF3TX4_ENA_SHIFT, 0),
809
810SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
811 MADERA_OUT1L_ENA_SHIFT, 0, NULL, 0, madera_hp_ev,
812 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
813 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
814SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
815 MADERA_OUT1R_ENA_SHIFT, 0, NULL, 0, madera_hp_ev,
816 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
817 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
818SND_SOC_DAPM_PGA_E("OUT2L", SND_SOC_NOPM,
819 MADERA_OUT2L_ENA_SHIFT, 0, NULL, 0, madera_hp_ev,
820 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
821 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
822SND_SOC_DAPM_PGA_E("OUT2R", SND_SOC_NOPM,
823 MADERA_OUT2R_ENA_SHIFT, 0, NULL, 0, madera_hp_ev,
824 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
825 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
826SND_SOC_DAPM_PGA_E("OUT3L", MADERA_OUTPUT_ENABLES_1,
827 MADERA_OUT3L_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
828 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
829 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
830SND_SOC_DAPM_PGA_E("OUT3R", MADERA_OUTPUT_ENABLES_1,
831 MADERA_OUT3R_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
832 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
833 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
834SND_SOC_DAPM_PGA_E("OUT5L", MADERA_OUTPUT_ENABLES_1,
835 MADERA_OUT5L_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
836 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
837SND_SOC_DAPM_PGA_E("OUT5R", MADERA_OUTPUT_ENABLES_1,
838 MADERA_OUT5R_ENA_SHIFT, 0, NULL, 0, madera_out_ev,
839 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
840
841SND_SOC_DAPM_PGA("SPD1TX1", MADERA_SPD1_TX_CONTROL,
842 MADERA_SPD1_VAL1_SHIFT, 0, NULL, 0),
843SND_SOC_DAPM_PGA("SPD1TX2", MADERA_SPD1_TX_CONTROL,
844 MADERA_SPD1_VAL2_SHIFT, 0, NULL, 0),
845SND_SOC_DAPM_OUT_DRV("SPD1", MADERA_SPD1_TX_CONTROL,
846 MADERA_SPD1_ENA_SHIFT, 0, NULL, 0),
847
848/*
849 * mux_in widgets : arranged in the order of sources
850 * specified in MADERA_MIXER_INPUT_ROUTES
851 */
852
853SND_SOC_DAPM_PGA("Noise Generator", MADERA_COMFORT_NOISE_GENERATOR,
854 MADERA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
855
856SND_SOC_DAPM_PGA("Tone Generator 1", MADERA_TONE_GENERATOR_1,
857 MADERA_TONE1_ENA_SHIFT, 0, NULL, 0),
858SND_SOC_DAPM_PGA("Tone Generator 2", MADERA_TONE_GENERATOR_1,
859 MADERA_TONE2_ENA_SHIFT, 0, NULL, 0),
860
861SND_SOC_DAPM_SIGGEN("HAPTICS"),
862
863SND_SOC_DAPM_MUX("AEC1 Loopback", MADERA_DAC_AEC_CONTROL_1,
864 MADERA_AEC1_LOOPBACK_ENA_SHIFT, 0,
865 &cs47l92_aec_loopback_mux),
866
867SND_SOC_DAPM_PGA_E("IN1L", MADERA_INPUT_ENABLES, MADERA_IN1L_ENA_SHIFT,
868 0, NULL, 0, madera_in_ev,
869 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
870 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
871SND_SOC_DAPM_PGA_E("IN1R", MADERA_INPUT_ENABLES, MADERA_IN1R_ENA_SHIFT,
872 0, NULL, 0, madera_in_ev,
873 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
874 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
875SND_SOC_DAPM_PGA_E("IN2L", MADERA_INPUT_ENABLES, MADERA_IN2L_ENA_SHIFT,
876 0, NULL, 0, madera_in_ev,
877 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
878 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
879SND_SOC_DAPM_PGA_E("IN2R", MADERA_INPUT_ENABLES, MADERA_IN2R_ENA_SHIFT,
880 0, NULL, 0, madera_in_ev,
881 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
882 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
883SND_SOC_DAPM_PGA_E("IN3L", MADERA_INPUT_ENABLES, MADERA_IN3L_ENA_SHIFT,
884 0, NULL, 0, madera_in_ev,
885 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
886 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
887SND_SOC_DAPM_PGA_E("IN3R", MADERA_INPUT_ENABLES, MADERA_IN3R_ENA_SHIFT,
888 0, NULL, 0, madera_in_ev,
889 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
890 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
891SND_SOC_DAPM_PGA_E("IN4L", MADERA_INPUT_ENABLES, MADERA_IN4L_ENA_SHIFT,
892 0, NULL, 0, madera_in_ev,
893 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
894 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
895SND_SOC_DAPM_PGA_E("IN4R", MADERA_INPUT_ENABLES, MADERA_IN4R_ENA_SHIFT,
896 0, NULL, 0, madera_in_ev,
897 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
898 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
899
900SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
901 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX1_ENA_SHIFT, 0),
902SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
903 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX2_ENA_SHIFT, 0),
904SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
905 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX3_ENA_SHIFT, 0),
906SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
907 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX4_ENA_SHIFT, 0),
908SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
909 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX5_ENA_SHIFT, 0),
910SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
911 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX6_ENA_SHIFT, 0),
912SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0,
913 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX7_ENA_SHIFT, 0),
914SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0,
915 MADERA_AIF1_RX_ENABLES, MADERA_AIF1RX8_ENA_SHIFT, 0),
916
917SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
918 MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX1_ENA_SHIFT, 0),
919SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
920 MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX2_ENA_SHIFT, 0),
921SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0,
922 MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX3_ENA_SHIFT, 0),
923SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0,
924 MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX4_ENA_SHIFT, 0),
925SND_SOC_DAPM_AIF_IN("AIF2RX5", NULL, 0,
926 MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX5_ENA_SHIFT, 0),
927SND_SOC_DAPM_AIF_IN("AIF2RX6", NULL, 0,
928 MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX6_ENA_SHIFT, 0),
929SND_SOC_DAPM_AIF_IN("AIF2RX7", NULL, 0,
930 MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX7_ENA_SHIFT, 0),
931SND_SOC_DAPM_AIF_IN("AIF2RX8", NULL, 0,
932 MADERA_AIF2_RX_ENABLES, MADERA_AIF2RX8_ENA_SHIFT, 0),
933
934SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
935 MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX1_ENA_SHIFT, 0),
936SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
937 MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX2_ENA_SHIFT, 0),
938SND_SOC_DAPM_AIF_IN("AIF3RX3", NULL, 0,
939 MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX3_ENA_SHIFT, 0),
940SND_SOC_DAPM_AIF_IN("AIF3RX4", NULL, 0,
941 MADERA_AIF3_RX_ENABLES, MADERA_AIF3RX4_ENA_SHIFT, 0),
942
943SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
944 MADERA_SLIMRX1_ENA_SHIFT, 0),
945SND_SOC_DAPM_AIF_IN("SLIMRX2", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
946 MADERA_SLIMRX2_ENA_SHIFT, 0),
947SND_SOC_DAPM_AIF_IN("SLIMRX3", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
948 MADERA_SLIMRX3_ENA_SHIFT, 0),
949SND_SOC_DAPM_AIF_IN("SLIMRX4", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
950 MADERA_SLIMRX4_ENA_SHIFT, 0),
951SND_SOC_DAPM_AIF_IN("SLIMRX5", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
952 MADERA_SLIMRX5_ENA_SHIFT, 0),
953SND_SOC_DAPM_AIF_IN("SLIMRX6", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
954 MADERA_SLIMRX6_ENA_SHIFT, 0),
955SND_SOC_DAPM_AIF_IN("SLIMRX7", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
956 MADERA_SLIMRX7_ENA_SHIFT, 0),
957SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0, MADERA_SLIMBUS_RX_CHANNEL_ENABLE,
958 MADERA_SLIMRX8_ENA_SHIFT, 0),
959
960SND_SOC_DAPM_PGA("EQ1", MADERA_EQ1_1, MADERA_EQ1_ENA_SHIFT, 0, NULL, 0),
961SND_SOC_DAPM_PGA("EQ2", MADERA_EQ2_1, MADERA_EQ2_ENA_SHIFT, 0, NULL, 0),
962SND_SOC_DAPM_PGA("EQ3", MADERA_EQ3_1, MADERA_EQ3_ENA_SHIFT, 0, NULL, 0),
963SND_SOC_DAPM_PGA("EQ4", MADERA_EQ4_1, MADERA_EQ4_ENA_SHIFT, 0, NULL, 0),
964
965SND_SOC_DAPM_PGA("DRC1L", MADERA_DRC1_CTRL1, MADERA_DRC1L_ENA_SHIFT, 0,
966 NULL, 0),
967SND_SOC_DAPM_PGA("DRC1R", MADERA_DRC1_CTRL1, MADERA_DRC1R_ENA_SHIFT, 0,
968 NULL, 0),
969SND_SOC_DAPM_PGA("DRC2L", MADERA_DRC2_CTRL1, MADERA_DRC2L_ENA_SHIFT, 0,
970 NULL, 0),
971SND_SOC_DAPM_PGA("DRC2R", MADERA_DRC2_CTRL1, MADERA_DRC2R_ENA_SHIFT, 0,
972 NULL, 0),
973
974SND_SOC_DAPM_PGA("LHPF1", MADERA_HPLPF1_1, MADERA_LHPF1_ENA_SHIFT, 0,
975 NULL, 0),
976SND_SOC_DAPM_PGA("LHPF2", MADERA_HPLPF2_1, MADERA_LHPF2_ENA_SHIFT, 0,
977 NULL, 0),
978SND_SOC_DAPM_PGA("LHPF3", MADERA_HPLPF3_1, MADERA_LHPF3_ENA_SHIFT, 0,
979 NULL, 0),
980SND_SOC_DAPM_PGA("LHPF4", MADERA_HPLPF4_1, MADERA_LHPF4_ENA_SHIFT, 0,
981 NULL, 0),
982
983SND_SOC_DAPM_PGA("ASRC1IN1L", MADERA_ASRC1_ENABLE,
984 MADERA_ASRC1_IN1L_ENA_SHIFT, 0, NULL, 0),
985SND_SOC_DAPM_PGA("ASRC1IN1R", MADERA_ASRC1_ENABLE,
986 MADERA_ASRC1_IN1R_ENA_SHIFT, 0, NULL, 0),
987SND_SOC_DAPM_PGA("ASRC1IN2L", MADERA_ASRC1_ENABLE,
988 MADERA_ASRC1_IN2L_ENA_SHIFT, 0, NULL, 0),
989SND_SOC_DAPM_PGA("ASRC1IN2R", MADERA_ASRC1_ENABLE,
990 MADERA_ASRC1_IN2R_ENA_SHIFT, 0, NULL, 0),
991
992SND_SOC_DAPM_PGA("ISRC1DEC1", MADERA_ISRC_1_CTRL_3,
993 MADERA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0),
994SND_SOC_DAPM_PGA("ISRC1DEC2", MADERA_ISRC_1_CTRL_3,
995 MADERA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0),
996
997SND_SOC_DAPM_PGA("ISRC1INT1", MADERA_ISRC_1_CTRL_3,
998 MADERA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0),
999SND_SOC_DAPM_PGA("ISRC1INT2", MADERA_ISRC_1_CTRL_3,
1000 MADERA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0),
1001
1002SND_SOC_DAPM_PGA("ISRC2DEC1", MADERA_ISRC_2_CTRL_3,
1003 MADERA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
1004SND_SOC_DAPM_PGA("ISRC2DEC2", MADERA_ISRC_2_CTRL_3,
1005 MADERA_ISRC2_DEC2_ENA_SHIFT, 0, NULL, 0),
1006
1007SND_SOC_DAPM_PGA("ISRC2INT1", MADERA_ISRC_2_CTRL_3,
1008 MADERA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0),
1009SND_SOC_DAPM_PGA("ISRC2INT2", MADERA_ISRC_2_CTRL_3,
1010 MADERA_ISRC2_INT2_ENA_SHIFT, 0, NULL, 0),
1011
1012WM_ADSP2("DSP1", 0, cs47l92_adsp_power_ev),
1013
1014/* end of ordered widget list */
1015
1016SND_SOC_DAPM_PGA("DFC1", MADERA_DFC1_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
1017SND_SOC_DAPM_PGA("DFC2", MADERA_DFC2_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
1018SND_SOC_DAPM_PGA("DFC3", MADERA_DFC3_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
1019SND_SOC_DAPM_PGA("DFC4", MADERA_DFC4_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
1020SND_SOC_DAPM_PGA("DFC5", MADERA_DFC5_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
1021SND_SOC_DAPM_PGA("DFC6", MADERA_DFC6_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
1022SND_SOC_DAPM_PGA("DFC7", MADERA_DFC7_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
1023SND_SOC_DAPM_PGA("DFC8", MADERA_DFC8_CTRL, MADERA_DFC1_ENA_SHIFT, 0, NULL, 0),
1024
1025MADERA_MIXER_WIDGETS(EQ1, "EQ1"),
1026MADERA_MIXER_WIDGETS(EQ2, "EQ2"),
1027MADERA_MIXER_WIDGETS(EQ3, "EQ3"),
1028MADERA_MIXER_WIDGETS(EQ4, "EQ4"),
1029
1030MADERA_MIXER_WIDGETS(DRC1L, "DRC1L"),
1031MADERA_MIXER_WIDGETS(DRC1R, "DRC1R"),
1032MADERA_MIXER_WIDGETS(DRC2L, "DRC2L"),
1033MADERA_MIXER_WIDGETS(DRC2R, "DRC2R"),
1034
1035SND_SOC_DAPM_SWITCH("DRC1 Activity Output", SND_SOC_NOPM, 0, 0,
1036 &madera_drc_activity_output_mux[0]),
1037SND_SOC_DAPM_SWITCH("DRC2 Activity Output", SND_SOC_NOPM, 0, 0,
1038 &madera_drc_activity_output_mux[1]),
1039
1040MADERA_MIXER_WIDGETS(LHPF1, "LHPF1"),
1041MADERA_MIXER_WIDGETS(LHPF2, "LHPF2"),
1042MADERA_MIXER_WIDGETS(LHPF3, "LHPF3"),
1043MADERA_MIXER_WIDGETS(LHPF4, "LHPF4"),
1044
1045MADERA_MIXER_WIDGETS(PWM1, "PWM1"),
1046MADERA_MIXER_WIDGETS(PWM2, "PWM2"),
1047
1048MADERA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
1049MADERA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
1050MADERA_MIXER_WIDGETS(OUT2L, "HPOUT2L"),
1051MADERA_MIXER_WIDGETS(OUT2R, "HPOUT2R"),
1052MADERA_MIXER_WIDGETS(OUT3L, "HPOUT3L"),
1053MADERA_MIXER_WIDGETS(OUT3R, "HPOUT3R"),
1054MADERA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
1055MADERA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
1056
1057MADERA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
1058MADERA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
1059MADERA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
1060MADERA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
1061MADERA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
1062MADERA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
1063MADERA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
1064MADERA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
1065
1066MADERA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
1067MADERA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
1068MADERA_MIXER_WIDGETS(AIF2TX3, "AIF2TX3"),
1069MADERA_MIXER_WIDGETS(AIF2TX4, "AIF2TX4"),
1070MADERA_MIXER_WIDGETS(AIF2TX5, "AIF2TX5"),
1071MADERA_MIXER_WIDGETS(AIF2TX6, "AIF2TX6"),
1072MADERA_MIXER_WIDGETS(AIF2TX7, "AIF2TX7"),
1073MADERA_MIXER_WIDGETS(AIF2TX8, "AIF2TX8"),
1074
1075MADERA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
1076MADERA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
1077MADERA_MIXER_WIDGETS(AIF3TX3, "AIF3TX3"),
1078MADERA_MIXER_WIDGETS(AIF3TX4, "AIF3TX4"),
1079
1080MADERA_MIXER_WIDGETS(SLIMTX1, "SLIMTX1"),
1081MADERA_MIXER_WIDGETS(SLIMTX2, "SLIMTX2"),
1082MADERA_MIXER_WIDGETS(SLIMTX3, "SLIMTX3"),
1083MADERA_MIXER_WIDGETS(SLIMTX4, "SLIMTX4"),
1084MADERA_MIXER_WIDGETS(SLIMTX5, "SLIMTX5"),
1085MADERA_MIXER_WIDGETS(SLIMTX6, "SLIMTX6"),
1086MADERA_MIXER_WIDGETS(SLIMTX7, "SLIMTX7"),
1087MADERA_MIXER_WIDGETS(SLIMTX8, "SLIMTX8"),
1088
1089MADERA_MUX_WIDGETS(SPD1TX1, "SPDIFTX1"),
1090MADERA_MUX_WIDGETS(SPD1TX2, "SPDIFTX2"),
1091
1092MADERA_MUX_WIDGETS(ASRC1IN1L, "ASRC1IN1L"),
1093MADERA_MUX_WIDGETS(ASRC1IN1R, "ASRC1IN1R"),
1094MADERA_MUX_WIDGETS(ASRC1IN2L, "ASRC1IN2L"),
1095MADERA_MUX_WIDGETS(ASRC1IN2R, "ASRC1IN2R"),
1096
1097MADERA_DSP_WIDGETS(DSP1, "DSP1"),
1098
1099MADERA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
1100MADERA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
1101
1102MADERA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
1103MADERA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
1104
1105MADERA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
1106MADERA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
1107
1108MADERA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
1109MADERA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
1110
1111MADERA_MUX_WIDGETS(DFC1, "DFC1"),
1112MADERA_MUX_WIDGETS(DFC2, "DFC2"),
1113MADERA_MUX_WIDGETS(DFC3, "DFC3"),
1114MADERA_MUX_WIDGETS(DFC4, "DFC4"),
1115MADERA_MUX_WIDGETS(DFC5, "DFC5"),
1116MADERA_MUX_WIDGETS(DFC6, "DFC6"),
1117MADERA_MUX_WIDGETS(DFC7, "DFC7"),
1118MADERA_MUX_WIDGETS(DFC8, "DFC8"),
1119
1120SND_SOC_DAPM_OUTPUT("HPOUT1L"),
1121SND_SOC_DAPM_OUTPUT("HPOUT1R"),
1122SND_SOC_DAPM_OUTPUT("HPOUT2L"),
1123SND_SOC_DAPM_OUTPUT("HPOUT2R"),
1124SND_SOC_DAPM_OUTPUT("HPOUT3L"),
1125SND_SOC_DAPM_OUTPUT("HPOUT3R"),
1126SND_SOC_DAPM_OUTPUT("HPOUT4L"),
1127SND_SOC_DAPM_OUTPUT("HPOUT4R"),
1128SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
1129SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
1130SND_SOC_DAPM_OUTPUT("SPDIF1"),
1131
1132SND_SOC_DAPM_OUTPUT("MICSUPP"),
1133};
1134
1135#define MADERA_MIXER_INPUT_ROUTES(name) \
1136 { name, "Noise Generator", "Noise Generator" }, \
1137 { name, "Tone Generator 1", "Tone Generator 1" }, \
1138 { name, "Tone Generator 2", "Tone Generator 2" }, \
1139 { name, "Haptics", "HAPTICS" }, \
1140 { name, "AEC1", "AEC1 Loopback" }, \
1141 { name, "IN1L", "IN1L" }, \
1142 { name, "IN1R", "IN1R" }, \
1143 { name, "IN2L", "IN2L" }, \
1144 { name, "IN2R", "IN2R" }, \
1145 { name, "IN3L", "IN3L" }, \
1146 { name, "IN3R", "IN3R" }, \
1147 { name, "IN4L", "IN4L" }, \
1148 { name, "IN4R", "IN4R" }, \
1149 { name, "AIF1RX1", "AIF1RX1" }, \
1150 { name, "AIF1RX2", "AIF1RX2" }, \
1151 { name, "AIF1RX3", "AIF1RX3" }, \
1152 { name, "AIF1RX4", "AIF1RX4" }, \
1153 { name, "AIF1RX5", "AIF1RX5" }, \
1154 { name, "AIF1RX6", "AIF1RX6" }, \
1155 { name, "AIF1RX7", "AIF1RX7" }, \
1156 { name, "AIF1RX8", "AIF1RX8" }, \
1157 { name, "AIF2RX1", "AIF2RX1" }, \
1158 { name, "AIF2RX2", "AIF2RX2" }, \
1159 { name, "AIF2RX3", "AIF2RX3" }, \
1160 { name, "AIF2RX4", "AIF2RX4" }, \
1161 { name, "AIF2RX5", "AIF2RX5" }, \
1162 { name, "AIF2RX6", "AIF2RX6" }, \
1163 { name, "AIF2RX7", "AIF2RX7" }, \
1164 { name, "AIF2RX8", "AIF2RX8" }, \
1165 { name, "AIF3RX1", "AIF3RX1" }, \
1166 { name, "AIF3RX2", "AIF3RX2" }, \
1167 { name, "AIF3RX3", "AIF3RX3" }, \
1168 { name, "AIF3RX4", "AIF3RX4" }, \
1169 { name, "SLIMRX1", "SLIMRX1" }, \
1170 { name, "SLIMRX2", "SLIMRX2" }, \
1171 { name, "SLIMRX3", "SLIMRX3" }, \
1172 { name, "SLIMRX4", "SLIMRX4" }, \
1173 { name, "SLIMRX5", "SLIMRX5" }, \
1174 { name, "SLIMRX6", "SLIMRX6" }, \
1175 { name, "SLIMRX7", "SLIMRX7" }, \
1176 { name, "SLIMRX8", "SLIMRX8" }, \
1177 { name, "EQ1", "EQ1" }, \
1178 { name, "EQ2", "EQ2" }, \
1179 { name, "EQ3", "EQ3" }, \
1180 { name, "EQ4", "EQ4" }, \
1181 { name, "DRC1L", "DRC1L" }, \
1182 { name, "DRC1R", "DRC1R" }, \
1183 { name, "DRC2L", "DRC2L" }, \
1184 { name, "DRC2R", "DRC2R" }, \
1185 { name, "LHPF1", "LHPF1" }, \
1186 { name, "LHPF2", "LHPF2" }, \
1187 { name, "LHPF3", "LHPF3" }, \
1188 { name, "LHPF4", "LHPF4" }, \
1189 { name, "ASRC1IN1L", "ASRC1IN1L" }, \
1190 { name, "ASRC1IN1R", "ASRC1IN1R" }, \
1191 { name, "ASRC1IN2L", "ASRC1IN2L" }, \
1192 { name, "ASRC1IN2R", "ASRC1IN2R" }, \
1193 { name, "ISRC1DEC1", "ISRC1DEC1" }, \
1194 { name, "ISRC1DEC2", "ISRC1DEC2" }, \
1195 { name, "ISRC1INT1", "ISRC1INT1" }, \
1196 { name, "ISRC1INT2", "ISRC1INT2" }, \
1197 { name, "ISRC2DEC1", "ISRC2DEC1" }, \
1198 { name, "ISRC2DEC2", "ISRC2DEC2" }, \
1199 { name, "ISRC2INT1", "ISRC2INT1" }, \
1200 { name, "ISRC2INT2", "ISRC2INT2" }, \
1201 { name, "DSP1.1", "DSP1" }, \
1202 { name, "DSP1.2", "DSP1" }, \
1203 { name, "DSP1.3", "DSP1" }, \
1204 { name, "DSP1.4", "DSP1" }, \
1205 { name, "DSP1.5", "DSP1" }, \
1206 { name, "DSP1.6", "DSP1" }, \
1207 { name, "DFC1", "DFC1" }, \
1208 { name, "DFC2", "DFC2" }, \
1209 { name, "DFC3", "DFC3" }, \
1210 { name, "DFC4", "DFC4" }, \
1211 { name, "DFC5", "DFC5" }, \
1212 { name, "DFC6", "DFC6" }, \
1213 { name, "DFC7", "DFC7" }, \
1214 { name, "DFC8", "DFC8" }
1215
1216static const struct snd_soc_dapm_route cs47l92_dapm_routes[] = {
1217 /* Internal clock domains */
1218 { "EQ1", NULL, "FXCLK" },
1219 { "EQ2", NULL, "FXCLK" },
1220 { "EQ3", NULL, "FXCLK" },
1221 { "EQ4", NULL, "FXCLK" },
1222 { "DRC1L", NULL, "FXCLK" },
1223 { "DRC1R", NULL, "FXCLK" },
1224 { "DRC2L", NULL, "FXCLK" },
1225 { "DRC2R", NULL, "FXCLK" },
1226 { "LHPF1", NULL, "FXCLK" },
1227 { "LHPF2", NULL, "FXCLK" },
1228 { "LHPF3", NULL, "FXCLK" },
1229 { "LHPF4", NULL, "FXCLK" },
1230 { "PWM1 Mixer", NULL, "PWMCLK" },
1231 { "PWM2 Mixer", NULL, "PWMCLK" },
1232 { "OUT1L", NULL, "OUTCLK" },
1233 { "OUT1R", NULL, "OUTCLK" },
1234 { "OUT2L", NULL, "OUTCLK" },
1235 { "OUT2R", NULL, "OUTCLK" },
1236 { "OUT3L", NULL, "OUTCLK" },
1237 { "OUT3R", NULL, "OUTCLK" },
1238 { "OUT5L", NULL, "OUTCLK" },
1239 { "OUT5R", NULL, "OUTCLK" },
1240 { "AIF1TX1", NULL, "AIF1TXCLK" },
1241 { "AIF1TX2", NULL, "AIF1TXCLK" },
1242 { "AIF1TX3", NULL, "AIF1TXCLK" },
1243 { "AIF1TX4", NULL, "AIF1TXCLK" },
1244 { "AIF1TX5", NULL, "AIF1TXCLK" },
1245 { "AIF1TX6", NULL, "AIF1TXCLK" },
1246 { "AIF1TX7", NULL, "AIF1TXCLK" },
1247 { "AIF1TX8", NULL, "AIF1TXCLK" },
1248 { "AIF2TX1", NULL, "AIF2TXCLK" },
1249 { "AIF2TX2", NULL, "AIF2TXCLK" },
1250 { "AIF2TX3", NULL, "AIF2TXCLK" },
1251 { "AIF2TX4", NULL, "AIF2TXCLK" },
1252 { "AIF2TX5", NULL, "AIF2TXCLK" },
1253 { "AIF2TX6", NULL, "AIF2TXCLK" },
1254 { "AIF2TX7", NULL, "AIF2TXCLK" },
1255 { "AIF2TX8", NULL, "AIF2TXCLK" },
1256 { "AIF3TX1", NULL, "AIF3TXCLK" },
1257 { "AIF3TX2", NULL, "AIF3TXCLK" },
1258 { "AIF3TX3", NULL, "AIF3TXCLK" },
1259 { "AIF3TX4", NULL, "AIF3TXCLK" },
1260 { "SLIMTX1", NULL, "SLIMBUSCLK" },
1261 { "SLIMTX2", NULL, "SLIMBUSCLK" },
1262 { "SLIMTX3", NULL, "SLIMBUSCLK" },
1263 { "SLIMTX4", NULL, "SLIMBUSCLK" },
1264 { "SLIMTX5", NULL, "SLIMBUSCLK" },
1265 { "SLIMTX6", NULL, "SLIMBUSCLK" },
1266 { "SLIMTX7", NULL, "SLIMBUSCLK" },
1267 { "SLIMTX8", NULL, "SLIMBUSCLK" },
1268 { "SPD1TX1", NULL, "SPDCLK" },
1269 { "SPD1TX2", NULL, "SPDCLK" },
1270 { "DSP1", NULL, "DSP1CLK" },
1271 { "ISRC1DEC1", NULL, "ISRC1CLK" },
1272 { "ISRC1DEC2", NULL, "ISRC1CLK" },
1273 { "ISRC1INT1", NULL, "ISRC1CLK" },
1274 { "ISRC1INT2", NULL, "ISRC1CLK" },
1275 { "ISRC2DEC1", NULL, "ISRC2CLK" },
1276 { "ISRC2DEC2", NULL, "ISRC2CLK" },
1277 { "ISRC2INT1", NULL, "ISRC2CLK" },
1278 { "ISRC2INT2", NULL, "ISRC2CLK" },
1279 { "ASRC1IN1L", NULL, "ASRC1CLK" },
1280 { "ASRC1IN1R", NULL, "ASRC1CLK" },
1281 { "ASRC1IN2L", NULL, "ASRC1CLK" },
1282 { "ASRC1IN2R", NULL, "ASRC1CLK" },
1283 { "DFC1", NULL, "DFCCLK" },
1284 { "DFC2", NULL, "DFCCLK" },
1285 { "DFC3", NULL, "DFCCLK" },
1286 { "DFC4", NULL, "DFCCLK" },
1287 { "DFC5", NULL, "DFCCLK" },
1288 { "DFC6", NULL, "DFCCLK" },
1289 { "DFC7", NULL, "DFCCLK" },
1290 { "DFC8", NULL, "DFCCLK" },
1291
1292 { "OUT1L", NULL, "CPVDD1" },
1293 { "OUT1L", NULL, "CPVDD2" },
1294 { "OUT1R", NULL, "CPVDD1" },
1295 { "OUT1R", NULL, "CPVDD2" },
1296 { "OUT2L", NULL, "CPVDD1" },
1297 { "OUT2L", NULL, "CPVDD2" },
1298 { "OUT2R", NULL, "CPVDD1" },
1299 { "OUT2R", NULL, "CPVDD2" },
1300 { "OUT3L", NULL, "CPVDD1" },
1301 { "OUT3L", NULL, "CPVDD2" },
1302 { "OUT3R", NULL, "CPVDD1" },
1303 { "OUT3R", NULL, "CPVDD2" },
1304
1305 { "OUT1L", NULL, "SYSCLK" },
1306 { "OUT1R", NULL, "SYSCLK" },
1307 { "OUT2L", NULL, "SYSCLK" },
1308 { "OUT2R", NULL, "SYSCLK" },
1309 { "OUT3L", NULL, "SYSCLK" },
1310 { "OUT3R", NULL, "SYSCLK" },
1311 { "OUT5L", NULL, "SYSCLK" },
1312 { "OUT5R", NULL, "SYSCLK" },
1313
1314 { "SPD1", NULL, "SYSCLK" },
1315 { "SPD1", NULL, "SPD1TX1" },
1316 { "SPD1", NULL, "SPD1TX2" },
1317
1318 { "IN1L", NULL, "SYSCLK" },
1319 { "IN1R", NULL, "SYSCLK" },
1320 { "IN2L", NULL, "SYSCLK" },
1321 { "IN2R", NULL, "SYSCLK" },
1322 { "IN3L", NULL, "SYSCLK" },
1323 { "IN3R", NULL, "SYSCLK" },
1324 { "IN4L", NULL, "SYSCLK" },
1325 { "IN4R", NULL, "SYSCLK" },
1326
1327 { "ASRC1IN1L", NULL, "SYSCLK" },
1328 { "ASRC1IN1R", NULL, "SYSCLK" },
1329 { "ASRC1IN2L", NULL, "SYSCLK" },
1330 { "ASRC1IN2R", NULL, "SYSCLK" },
1331
1332 { "ASRC1IN1L", NULL, "ASYNCCLK" },
1333 { "ASRC1IN1R", NULL, "ASYNCCLK" },
1334 { "ASRC1IN2L", NULL, "ASYNCCLK" },
1335 { "ASRC1IN2R", NULL, "ASYNCCLK" },
1336
1337 { "MICBIAS1", NULL, "MICVDD" },
1338 { "MICBIAS2", NULL, "MICVDD" },
1339
1340 { "MICBIAS1A", NULL, "MICBIAS1" },
1341 { "MICBIAS1B", NULL, "MICBIAS1" },
1342 { "MICBIAS1C", NULL, "MICBIAS1" },
1343 { "MICBIAS1D", NULL, "MICBIAS1" },
1344
1345 { "MICBIAS2A", NULL, "MICBIAS2" },
1346 { "MICBIAS2B", NULL, "MICBIAS2" },
1347
1348 { "Noise Generator", NULL, "SYSCLK" },
1349 { "Tone Generator 1", NULL, "SYSCLK" },
1350 { "Tone Generator 2", NULL, "SYSCLK" },
1351
1352 { "Noise Generator", NULL, "NOISE" },
1353 { "Tone Generator 1", NULL, "TONE" },
1354 { "Tone Generator 2", NULL, "TONE" },
1355
1356 { "AIF1 Capture", NULL, "AIF1TX1" },
1357 { "AIF1 Capture", NULL, "AIF1TX2" },
1358 { "AIF1 Capture", NULL, "AIF1TX3" },
1359 { "AIF1 Capture", NULL, "AIF1TX4" },
1360 { "AIF1 Capture", NULL, "AIF1TX5" },
1361 { "AIF1 Capture", NULL, "AIF1TX6" },
1362 { "AIF1 Capture", NULL, "AIF1TX7" },
1363 { "AIF1 Capture", NULL, "AIF1TX8" },
1364
1365 { "AIF1RX1", NULL, "AIF1 Playback" },
1366 { "AIF1RX2", NULL, "AIF1 Playback" },
1367 { "AIF1RX3", NULL, "AIF1 Playback" },
1368 { "AIF1RX4", NULL, "AIF1 Playback" },
1369 { "AIF1RX5", NULL, "AIF1 Playback" },
1370 { "AIF1RX6", NULL, "AIF1 Playback" },
1371 { "AIF1RX7", NULL, "AIF1 Playback" },
1372 { "AIF1RX8", NULL, "AIF1 Playback" },
1373
1374 { "AIF2 Capture", NULL, "AIF2TX1" },
1375 { "AIF2 Capture", NULL, "AIF2TX2" },
1376 { "AIF2 Capture", NULL, "AIF2TX3" },
1377 { "AIF2 Capture", NULL, "AIF2TX4" },
1378 { "AIF2 Capture", NULL, "AIF2TX5" },
1379 { "AIF2 Capture", NULL, "AIF2TX6" },
1380 { "AIF2 Capture", NULL, "AIF2TX7" },
1381 { "AIF2 Capture", NULL, "AIF2TX8" },
1382
1383 { "AIF2RX1", NULL, "AIF2 Playback" },
1384 { "AIF2RX2", NULL, "AIF2 Playback" },
1385 { "AIF2RX3", NULL, "AIF2 Playback" },
1386 { "AIF2RX4", NULL, "AIF2 Playback" },
1387 { "AIF2RX5", NULL, "AIF2 Playback" },
1388 { "AIF2RX6", NULL, "AIF2 Playback" },
1389 { "AIF2RX7", NULL, "AIF2 Playback" },
1390 { "AIF2RX8", NULL, "AIF2 Playback" },
1391
1392 { "AIF3 Capture", NULL, "AIF3TX1" },
1393 { "AIF3 Capture", NULL, "AIF3TX2" },
1394 { "AIF3 Capture", NULL, "AIF3TX3" },
1395 { "AIF3 Capture", NULL, "AIF3TX4" },
1396
1397 { "AIF3RX1", NULL, "AIF3 Playback" },
1398 { "AIF3RX2", NULL, "AIF3 Playback" },
1399 { "AIF3RX3", NULL, "AIF3 Playback" },
1400 { "AIF3RX4", NULL, "AIF3 Playback" },
1401
1402 { "Slim1 Capture", NULL, "SLIMTX1" },
1403 { "Slim1 Capture", NULL, "SLIMTX2" },
1404 { "Slim1 Capture", NULL, "SLIMTX3" },
1405 { "Slim1 Capture", NULL, "SLIMTX4" },
1406
1407 { "SLIMRX1", NULL, "Slim1 Playback" },
1408 { "SLIMRX2", NULL, "Slim1 Playback" },
1409 { "SLIMRX3", NULL, "Slim1 Playback" },
1410 { "SLIMRX4", NULL, "Slim1 Playback" },
1411
1412 { "Slim2 Capture", NULL, "SLIMTX5" },
1413 { "Slim2 Capture", NULL, "SLIMTX6" },
1414
1415 { "SLIMRX5", NULL, "Slim2 Playback" },
1416 { "SLIMRX6", NULL, "Slim2 Playback" },
1417
1418 { "Slim3 Capture", NULL, "SLIMTX7" },
1419 { "Slim3 Capture", NULL, "SLIMTX8" },
1420
1421 { "SLIMRX7", NULL, "Slim3 Playback" },
1422 { "SLIMRX8", NULL, "Slim3 Playback" },
1423
1424 { "AIF1 Playback", NULL, "SYSCLK" },
1425 { "AIF2 Playback", NULL, "SYSCLK" },
1426 { "AIF3 Playback", NULL, "SYSCLK" },
1427 { "Slim1 Playback", NULL, "SYSCLK" },
1428 { "Slim2 Playback", NULL, "SYSCLK" },
1429 { "Slim3 Playback", NULL, "SYSCLK" },
1430
1431 { "AIF1 Capture", NULL, "SYSCLK" },
1432 { "AIF2 Capture", NULL, "SYSCLK" },
1433 { "AIF3 Capture", NULL, "SYSCLK" },
1434 { "Slim1 Capture", NULL, "SYSCLK" },
1435 { "Slim2 Capture", NULL, "SYSCLK" },
1436 { "Slim3 Capture", NULL, "SYSCLK" },
1437
1438 { "Audio Trace DSP", NULL, "DSP1" },
1439
1440 { "IN1L Analog Mux", "A", "IN1ALN" },
1441 { "IN1L Analog Mux", "A", "IN1ALP" },
1442 { "IN1L Analog Mux", "B", "IN1BLN" },
1443 { "IN1L Analog Mux", "B", "IN1BLP" },
1444 { "IN1R Analog Mux", "A", "IN1ARN" },
1445 { "IN1R Analog Mux", "A", "IN1ARP" },
1446 { "IN1R Analog Mux", "B", "IN1BR" },
1447 { "IN1R Analog Mux", "B", "IN1ALN" },
1448
1449 { "IN1L Mode", "Analog", "IN1L Analog Mux" },
1450 { "IN1R Mode", "Analog", "IN1R Analog Mux" },
1451
1452 { "IN1L Mode", "Digital", "IN1ALN" },
1453 { "IN1L Mode", "Digital", "IN1ALP" },
1454 { "IN1R Mode", "Digital", "IN1ALN" },
1455 { "IN1R Mode", "Digital", "IN1ALP" },
1456
1457 { "IN1L", NULL, "IN1L Mode" },
1458 { "IN1R", NULL, "IN1R Mode" },
1459
1460 { "IN2L Analog Mux", "A", "IN2ALN" },
1461 { "IN2L Analog Mux", "A", "IN2ALP" },
1462 { "IN2L Analog Mux", "B", "IN2ALN" },
1463 { "IN2L Analog Mux", "B", "IN2BL" },
1464 { "IN2R Analog Mux", "A", "IN2ARN" },
1465 { "IN2R Analog Mux", "A", "IN2ARP" },
1466 { "IN2R Analog Mux", "B", "IN2ARN" },
1467 { "IN2R Analog Mux", "B", "IN2BR" },
1468
1469 { "IN2L Mode", "Analog", "IN2L Analog Mux" },
1470 { "IN2R Mode", "Analog", "IN2R Analog Mux" },
1471
1472 { "IN2L Mode", "Digital", "IN2ALN" },
1473 { "IN2L Mode", "Digital", "IN2ALP" },
1474 { "IN2R Mode", "Digital", "IN2ALN" },
1475 { "IN2R Mode", "Digital", "IN2ALP" },
1476
1477 { "IN2L", NULL, "IN2L Mode" },
1478 { "IN2R", NULL, "IN2R Mode" },
1479
1480 { "IN3L", NULL, "IN1ARN" },
1481 { "IN3L", NULL, "IN1ARP" },
1482 { "IN3R", NULL, "IN1ARN" },
1483 { "IN3R", NULL, "IN1ARP" },
1484
1485 { "IN4L", NULL, "IN2ARN" },
1486 { "IN4L", NULL, "IN2ARP" },
1487 { "IN4R", NULL, "IN2ARN" },
1488 { "IN4R", NULL, "IN2ARP" },
1489
1490 MADERA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
1491 MADERA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
1492 MADERA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
1493 MADERA_MIXER_ROUTES("OUT2R", "HPOUT2R"),
1494 MADERA_MIXER_ROUTES("OUT3L", "HPOUT3L"),
1495 MADERA_MIXER_ROUTES("OUT3R", "HPOUT3R"),
1496
1497 MADERA_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
1498 MADERA_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
1499
1500 MADERA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
1501 MADERA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
1502
1503 MADERA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1504 MADERA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1505 MADERA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1506 MADERA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1507 MADERA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1508 MADERA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1509 MADERA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
1510 MADERA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
1511
1512 MADERA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
1513 MADERA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
1514 MADERA_MIXER_ROUTES("AIF2TX3", "AIF2TX3"),
1515 MADERA_MIXER_ROUTES("AIF2TX4", "AIF2TX4"),
1516 MADERA_MIXER_ROUTES("AIF2TX5", "AIF2TX5"),
1517 MADERA_MIXER_ROUTES("AIF2TX6", "AIF2TX6"),
1518 MADERA_MIXER_ROUTES("AIF2TX7", "AIF2TX7"),
1519 MADERA_MIXER_ROUTES("AIF2TX8", "AIF2TX8"),
1520
1521 MADERA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
1522 MADERA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
1523 MADERA_MIXER_ROUTES("AIF3TX3", "AIF3TX3"),
1524 MADERA_MIXER_ROUTES("AIF3TX4", "AIF3TX4"),
1525
1526 MADERA_MIXER_ROUTES("SLIMTX1", "SLIMTX1"),
1527 MADERA_MIXER_ROUTES("SLIMTX2", "SLIMTX2"),
1528 MADERA_MIXER_ROUTES("SLIMTX3", "SLIMTX3"),
1529 MADERA_MIXER_ROUTES("SLIMTX4", "SLIMTX4"),
1530 MADERA_MIXER_ROUTES("SLIMTX5", "SLIMTX5"),
1531 MADERA_MIXER_ROUTES("SLIMTX6", "SLIMTX6"),
1532 MADERA_MIXER_ROUTES("SLIMTX7", "SLIMTX7"),
1533 MADERA_MIXER_ROUTES("SLIMTX8", "SLIMTX8"),
1534
1535 MADERA_MUX_ROUTES("SPD1TX1", "SPDIFTX1"),
1536 MADERA_MUX_ROUTES("SPD1TX2", "SPDIFTX2"),
1537
1538 MADERA_MIXER_ROUTES("EQ1", "EQ1"),
1539 MADERA_MIXER_ROUTES("EQ2", "EQ2"),
1540 MADERA_MIXER_ROUTES("EQ3", "EQ3"),
1541 MADERA_MIXER_ROUTES("EQ4", "EQ4"),
1542
1543 MADERA_MIXER_ROUTES("DRC1L", "DRC1L"),
1544 MADERA_MIXER_ROUTES("DRC1R", "DRC1R"),
1545 MADERA_MIXER_ROUTES("DRC2L", "DRC2L"),
1546 MADERA_MIXER_ROUTES("DRC2R", "DRC2R"),
1547
1548 MADERA_MIXER_ROUTES("LHPF1", "LHPF1"),
1549 MADERA_MIXER_ROUTES("LHPF2", "LHPF2"),
1550 MADERA_MIXER_ROUTES("LHPF3", "LHPF3"),
1551 MADERA_MIXER_ROUTES("LHPF4", "LHPF4"),
1552
1553 MADERA_MUX_ROUTES("ASRC1IN1L", "ASRC1IN1L"),
1554 MADERA_MUX_ROUTES("ASRC1IN1R", "ASRC1IN1R"),
1555 MADERA_MUX_ROUTES("ASRC1IN2L", "ASRC1IN2L"),
1556 MADERA_MUX_ROUTES("ASRC1IN2R", "ASRC1IN2R"),
1557
1558 MADERA_DSP_ROUTES("DSP1"),
1559
1560 MADERA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
1561 MADERA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
1562
1563 MADERA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
1564 MADERA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
1565
1566 MADERA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
1567 MADERA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
1568
1569 MADERA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
1570 MADERA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
1571
1572 { "AEC1 Loopback", "HPOUT1L", "OUT1L" },
1573 { "AEC1 Loopback", "HPOUT1R", "OUT1R" },
1574 { "HPOUT1L", NULL, "OUT1L" },
1575 { "HPOUT1R", NULL, "OUT1R" },
1576
1577 { "AEC1 Loopback", "HPOUT2L", "OUT2L" },
1578 { "AEC1 Loopback", "HPOUT2R", "OUT2R" },
1579 { "HPOUT2L", NULL, "OUT2L" },
1580 { "HPOUT2R", NULL, "OUT2R" },
1581
1582 { "AEC1 Loopback", "HPOUT3L", "OUT3L" },
1583 { "AEC1 Loopback", "HPOUT3R", "OUT3R" },
1584 { "OUT3 Demux", NULL, "OUT3L" },
1585 { "OUT3 Demux", NULL, "OUT3R" },
1586
1587 { "HPOUT3L", "HPOUT3", "OUT3 Demux" },
1588 { "HPOUT3R", "HPOUT3", "OUT3 Demux" },
1589 { "HPOUT4L", "HPOUT4", "OUT3 Demux" },
1590 { "HPOUT4R", "HPOUT4", "OUT3 Demux" },
1591
1592 { "AEC1 Loopback", "SPKDAT1L", "OUT5L" },
1593 { "AEC1 Loopback", "SPKDAT1R", "OUT5R" },
1594 { "SPKDAT1L", NULL, "OUT5L" },
1595 { "SPKDAT1R", NULL, "OUT5R" },
1596
1597 { "SPDIF1", NULL, "SPD1" },
1598
1599 { "MICSUPP", NULL, "SYSCLK" },
1600
1601 { "DRC1 Signal Activity", NULL, "DRC1 Activity Output" },
1602 { "DRC2 Signal Activity", NULL, "DRC2 Activity Output" },
1603 { "DRC1 Activity Output", "Switch", "DRC1L" },
1604 { "DRC1 Activity Output", "Switch", "DRC1R" },
1605 { "DRC2 Activity Output", "Switch", "DRC2L" },
1606 { "DRC2 Activity Output", "Switch", "DRC2R" },
1607
1608 MADERA_MUX_ROUTES("DFC1", "DFC1"),
1609 MADERA_MUX_ROUTES("DFC2", "DFC2"),
1610 MADERA_MUX_ROUTES("DFC3", "DFC3"),
1611 MADERA_MUX_ROUTES("DFC4", "DFC4"),
1612 MADERA_MUX_ROUTES("DFC5", "DFC5"),
1613 MADERA_MUX_ROUTES("DFC6", "DFC6"),
1614 MADERA_MUX_ROUTES("DFC7", "DFC7"),
1615 MADERA_MUX_ROUTES("DFC8", "DFC8"),
1616};
1617
1618static int cs47l92_set_fll(struct snd_soc_component *component, int fll_id,
1619 int source, unsigned int fref, unsigned int fout)
1620{
1621 struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component);
1622
1623 switch (fll_id) {
1624 case MADERA_FLL1_REFCLK:
1625 return madera_fllhj_set_refclk(&cs47l92->fll[0], source, fref,
1626 fout);
1627 case MADERA_FLL2_REFCLK:
1628 return madera_fllhj_set_refclk(&cs47l92->fll[1], source, fref,
1629 fout);
1630 default:
1631 return -EINVAL;
1632 }
1633}
1634
1635static struct snd_soc_dai_driver cs47l92_dai[] = {
1636 {
1637 .name = "cs47l92-aif1",
1638 .id = 1,
1639 .base = MADERA_AIF1_BCLK_CTRL,
1640 .playback = {
1641 .stream_name = "AIF1 Playback",
1642 .channels_min = 1,
1643 .channels_max = 8,
1644 .rates = MADERA_RATES,
1645 .formats = MADERA_FORMATS,
1646 },
1647 .capture = {
1648 .stream_name = "AIF1 Capture",
1649 .channels_min = 1,
1650 .channels_max = 8,
1651 .rates = MADERA_RATES,
1652 .formats = MADERA_FORMATS,
1653 },
1654 .ops = &madera_dai_ops,
1655 .symmetric_rates = 1,
1656 .symmetric_samplebits = 1,
1657 },
1658 {
1659 .name = "cs47l92-aif2",
1660 .id = 2,
1661 .base = MADERA_AIF2_BCLK_CTRL,
1662 .playback = {
1663 .stream_name = "AIF2 Playback",
1664 .channels_min = 1,
1665 .channels_max = 8,
1666 .rates = MADERA_RATES,
1667 .formats = MADERA_FORMATS,
1668 },
1669 .capture = {
1670 .stream_name = "AIF2 Capture",
1671 .channels_min = 1,
1672 .channels_max = 8,
1673 .rates = MADERA_RATES,
1674 .formats = MADERA_FORMATS,
1675 },
1676 .ops = &madera_dai_ops,
1677 .symmetric_rates = 1,
1678 .symmetric_samplebits = 1,
1679 },
1680 {
1681 .name = "cs47l92-aif3",
1682 .id = 3,
1683 .base = MADERA_AIF3_BCLK_CTRL,
1684 .playback = {
1685 .stream_name = "AIF3 Playback",
1686 .channels_min = 1,
1687 .channels_max = 4,
1688 .rates = MADERA_RATES,
1689 .formats = MADERA_FORMATS,
1690 },
1691 .capture = {
1692 .stream_name = "AIF3 Capture",
1693 .channels_min = 1,
1694 .channels_max = 4,
1695 .rates = MADERA_RATES,
1696 .formats = MADERA_FORMATS,
1697 },
1698 .ops = &madera_dai_ops,
1699 .symmetric_rates = 1,
1700 .symmetric_samplebits = 1,
1701 },
1702 {
1703 .name = "cs47l92-slim1",
1704 .id = 5,
1705 .playback = {
1706 .stream_name = "Slim1 Playback",
1707 .channels_min = 1,
1708 .channels_max = 4,
1709 .rates = MADERA_RATES,
1710 .formats = MADERA_FORMATS,
1711 },
1712 .capture = {
1713 .stream_name = "Slim1 Capture",
1714 .channels_min = 1,
1715 .channels_max = 4,
1716 .rates = MADERA_RATES,
1717 .formats = MADERA_FORMATS,
1718 },
1719 .ops = &madera_simple_dai_ops,
1720 },
1721 {
1722 .name = "cs47l92-slim2",
1723 .id = 6,
1724 .playback = {
1725 .stream_name = "Slim2 Playback",
1726 .channels_min = 1,
1727 .channels_max = 2,
1728 .rates = MADERA_RATES,
1729 .formats = MADERA_FORMATS,
1730 },
1731 .capture = {
1732 .stream_name = "Slim2 Capture",
1733 .channels_min = 1,
1734 .channels_max = 2,
1735 .rates = MADERA_RATES,
1736 .formats = MADERA_FORMATS,
1737 },
1738 .ops = &madera_simple_dai_ops,
1739 },
1740 {
1741 .name = "cs47l92-slim3",
1742 .id = 7,
1743 .playback = {
1744 .stream_name = "Slim3 Playback",
1745 .channels_min = 1,
1746 .channels_max = 2,
1747 .rates = MADERA_RATES,
1748 .formats = MADERA_FORMATS,
1749 },
1750 .capture = {
1751 .stream_name = "Slim3 Capture",
1752 .channels_min = 1,
1753 .channels_max = 2,
1754 .rates = MADERA_RATES,
1755 .formats = MADERA_FORMATS,
1756 },
1757 .ops = &madera_simple_dai_ops,
1758 },
1759 {
1760 .name = "cs47l92-cpu-trace",
1761 .capture = {
1762 .stream_name = "Audio Trace CPU",
1763 .channels_min = 1,
1764 .channels_max = 2,
1765 .rates = MADERA_RATES,
1766 .formats = MADERA_FORMATS,
1767 },
1768 .compress_new = snd_soc_new_compress,
1769 },
1770 {
1771 .name = "cs47l92-dsp-trace",
1772 .capture = {
1773 .stream_name = "Audio Trace DSP",
1774 .channels_min = 1,
1775 .channels_max = 2,
1776 .rates = MADERA_RATES,
1777 .formats = MADERA_FORMATS,
1778 },
1779 },
1780};
1781
1782static int cs47l92_open(struct snd_compr_stream *stream)
1783{
1784 struct snd_soc_pcm_runtime *rtd = stream->private_data;
1785 struct snd_soc_component *component =
1786 snd_soc_rtdcom_lookup(rtd, DRV_NAME);
1787 struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component);
1788 struct madera_priv *priv = &cs47l92->core;
1789 struct madera *madera = priv->madera;
1790 int n_adsp;
1791
1792 if (strcmp(rtd->codec_dai->name, "cs47l92-dsp-trace") == 0) {
1793 n_adsp = 0;
1794 } else {
1795 dev_err(madera->dev,
1796 "No suitable compressed stream for DAI '%s'\n",
1797 rtd->codec_dai->name);
1798 return -EINVAL;
1799 }
1800
1801 return wm_adsp_compr_open(&priv->adsp[n_adsp], stream);
1802}
1803
1804static irqreturn_t cs47l92_adsp2_irq(int irq, void *data)
1805{
1806 struct cs47l92 *cs47l92 = data;
1807 struct madera_priv *priv = &cs47l92->core;
1808 struct madera *madera = priv->madera;
1809 int ret;
1810
1811 ret = wm_adsp_compr_handle_irq(&priv->adsp[0]);
1812 if (ret == -ENODEV) {
1813 dev_err(madera->dev, "Spurious compressed data IRQ\n");
1814 return IRQ_NONE;
1815 }
1816
1817 return IRQ_HANDLED;
1818}
1819
1820static int cs47l92_component_probe(struct snd_soc_component *component)
1821{
1822 struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component);
1823 struct madera *madera = cs47l92->core.madera;
1824 int ret;
1825
1826 snd_soc_component_init_regmap(component, madera->regmap);
1827
1828 mutex_lock(&madera->dapm_ptr_lock);
1829 madera->dapm = snd_soc_component_get_dapm(component);
1830 mutex_unlock(&madera->dapm_ptr_lock);
1831
1832 ret = madera_init_inputs(component);
1833 if (ret)
1834 return ret;
1835
1836 ret = madera_init_outputs(component, CS47L92_MONO_OUTPUTS);
1837 if (ret)
1838 return ret;
1839
1840 snd_soc_component_disable_pin(component, "HAPTICS");
1841
1842 ret = snd_soc_add_component_controls(component,
1843 madera_adsp_rate_controls,
1844 CS47L92_NUM_ADSP);
1845 if (ret)
1846 return ret;
1847
1848 return wm_adsp2_component_probe(&cs47l92->core.adsp[0], component);
1849}
1850
1851static void cs47l92_component_remove(struct snd_soc_component *component)
1852{
1853 struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component);
1854 struct madera *madera = cs47l92->core.madera;
1855
1856 mutex_lock(&madera->dapm_ptr_lock);
1857 madera->dapm = NULL;
1858 mutex_unlock(&madera->dapm_ptr_lock);
1859
1860 wm_adsp2_component_remove(&cs47l92->core.adsp[0], component);
1861}
1862
1863#define CS47L92_DIG_VU 0x0200
1864
1865static unsigned int cs47l92_digital_vu[] = {
1866 MADERA_DAC_DIGITAL_VOLUME_1L,
1867 MADERA_DAC_DIGITAL_VOLUME_1R,
1868 MADERA_DAC_DIGITAL_VOLUME_2L,
1869 MADERA_DAC_DIGITAL_VOLUME_2R,
1870 MADERA_DAC_DIGITAL_VOLUME_3L,
1871 MADERA_DAC_DIGITAL_VOLUME_3R,
1872 MADERA_DAC_DIGITAL_VOLUME_5L,
1873 MADERA_DAC_DIGITAL_VOLUME_5R,
1874};
1875
1876static const struct snd_compr_ops cs47l92_compr_ops = {
1877 .open = &cs47l92_open,
1878 .free = &wm_adsp_compr_free,
1879 .set_params = &wm_adsp_compr_set_params,
1880 .get_caps = &wm_adsp_compr_get_caps,
1881 .trigger = &wm_adsp_compr_trigger,
1882 .pointer = &wm_adsp_compr_pointer,
1883 .copy = &wm_adsp_compr_copy,
1884};
1885
1886static const struct snd_soc_component_driver soc_component_dev_cs47l92 = {
1887 .probe = &cs47l92_component_probe,
1888 .remove = &cs47l92_component_remove,
1889 .set_sysclk = &madera_set_sysclk,
1890 .set_pll = &cs47l92_set_fll,
1891 .name = DRV_NAME,
1892 .compr_ops = &cs47l92_compr_ops,
1893 .controls = cs47l92_snd_controls,
1894 .num_controls = ARRAY_SIZE(cs47l92_snd_controls),
1895 .dapm_widgets = cs47l92_dapm_widgets,
1896 .num_dapm_widgets = ARRAY_SIZE(cs47l92_dapm_widgets),
1897 .dapm_routes = cs47l92_dapm_routes,
1898 .num_dapm_routes = ARRAY_SIZE(cs47l92_dapm_routes),
1899 .use_pmdown_time = 1,
1900 .endianness = 1,
1901 .non_legacy_dai_naming = 1,
1902};
1903
1904static int cs47l92_probe(struct platform_device *pdev)
1905{
1906 struct madera *madera = dev_get_drvdata(pdev->dev.parent);
1907 struct cs47l92 *cs47l92;
1908 int i, ret;
1909
1910 BUILD_BUG_ON(ARRAY_SIZE(cs47l92_dai) > MADERA_MAX_DAI);
1911
1912 /* quick exit if Madera irqchip driver hasn't completed probe */
1913 if (!madera->irq_dev) {
1914 dev_dbg(&pdev->dev, "irqchip driver not ready\n");
1915 return -EPROBE_DEFER;
1916 }
1917
1918 cs47l92 = devm_kzalloc(&pdev->dev, sizeof(struct cs47l92), GFP_KERNEL);
1919 if (!cs47l92)
1920 return -ENOMEM;
1921
1922 platform_set_drvdata(pdev, cs47l92);
1923
1924 cs47l92->core.madera = madera;
1925 cs47l92->core.dev = &pdev->dev;
1926 cs47l92->core.num_inputs = 8;
1927
1928 ret = madera_core_init(&cs47l92->core);
1929 if (ret)
1930 return ret;
1931
1932 ret = madera_request_irq(madera, MADERA_IRQ_DSP_IRQ1,
1933 "ADSP2 Compressed IRQ", cs47l92_adsp2_irq,
1934 cs47l92);
1935 if (ret != 0) {
1936 dev_err(&pdev->dev, "Failed to request DSP IRQ: %d\n", ret);
1937 goto error_core;
1938 }
1939
1940 ret = madera_set_irq_wake(madera, MADERA_IRQ_DSP_IRQ1, 1);
1941 if (ret)
1942 dev_warn(&pdev->dev, "Failed to set DSP IRQ wake: %d\n", ret);
1943
1944 cs47l92->core.adsp[0].part = "cs47l92";
1945 cs47l92->core.adsp[0].num = 1;
1946 cs47l92->core.adsp[0].type = WMFW_ADSP2;
1947 cs47l92->core.adsp[0].rev = 2;
1948 cs47l92->core.adsp[0].dev = madera->dev;
1949 cs47l92->core.adsp[0].regmap = madera->regmap_32bit;
1950
1951 cs47l92->core.adsp[0].base = MADERA_DSP1_CONFIG_1;
1952 cs47l92->core.adsp[0].mem = cs47l92_dsp1_regions;
1953 cs47l92->core.adsp[0].num_mems = ARRAY_SIZE(cs47l92_dsp1_regions);
1954
1955 cs47l92->core.adsp[0].lock_regions = WM_ADSP2_REGION_1_9;
1956
1957 ret = wm_adsp2_init(&cs47l92->core.adsp[0]);
1958 if (ret != 0)
1959 goto error_dsp_irq;
1960
1961 ret = madera_init_bus_error_irq(&cs47l92->core, 0, wm_adsp2_bus_error);
1962 if (ret != 0) {
1963 wm_adsp2_remove(&cs47l92->core.adsp[0]);
1964 goto error_adsp;
1965 }
1966
1967 madera_init_fll(madera, 1, MADERA_FLL1_CONTROL_1 - 1,
1968 &cs47l92->fll[0]);
1969 madera_init_fll(madera, 2, MADERA_FLL2_CONTROL_1 - 1,
1970 &cs47l92->fll[1]);
1971
1972 for (i = 0; i < ARRAY_SIZE(cs47l92_dai); i++)
1973 madera_init_dai(&cs47l92->core, i);
1974
1975 /* Latch volume update bits */
1976 for (i = 0; i < ARRAY_SIZE(cs47l92_digital_vu); i++)
1977 regmap_update_bits(madera->regmap, cs47l92_digital_vu[i],
1978 CS47L92_DIG_VU, CS47L92_DIG_VU);
1979
1980 pm_runtime_enable(&pdev->dev);
1981 pm_runtime_idle(&pdev->dev);
1982
1983 ret = devm_snd_soc_register_component(&pdev->dev,
1984 &soc_component_dev_cs47l92,
1985 cs47l92_dai,
1986 ARRAY_SIZE(cs47l92_dai));
1987 if (ret < 0) {
1988 dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
1989 goto error_pm_runtime;
1990 }
1991
1992 return ret;
1993
1994error_pm_runtime:
1995 pm_runtime_disable(&pdev->dev);
1996 madera_free_bus_error_irq(&cs47l92->core, 0);
1997error_adsp:
1998 wm_adsp2_remove(&cs47l92->core.adsp[0]);
1999error_dsp_irq:
2000 madera_set_irq_wake(madera, MADERA_IRQ_DSP_IRQ1, 0);
2001 madera_free_irq(madera, MADERA_IRQ_DSP_IRQ1, cs47l92);
2002error_core:
2003 madera_core_free(&cs47l92->core);
2004
2005 return ret;
2006}
2007
2008static int cs47l92_remove(struct platform_device *pdev)
2009{
2010 struct cs47l92 *cs47l92 = platform_get_drvdata(pdev);
2011
2012 pm_runtime_disable(&pdev->dev);
2013
2014 madera_free_bus_error_irq(&cs47l92->core, 0);
2015 wm_adsp2_remove(&cs47l92->core.adsp[0]);
2016
2017 madera_set_irq_wake(cs47l92->core.madera, MADERA_IRQ_DSP_IRQ1, 0);
2018 madera_free_irq(cs47l92->core.madera, MADERA_IRQ_DSP_IRQ1, cs47l92);
2019
2020 madera_core_free(&cs47l92->core);
2021
2022 return 0;
2023}
2024
2025static struct platform_driver cs47l92_codec_driver = {
2026 .driver = {
2027 .name = "cs47l92-codec",
2028 },
2029 .probe = &cs47l92_probe,
2030 .remove = &cs47l92_remove,
2031};
2032
2033module_platform_driver(cs47l92_codec_driver);
2034
2035MODULE_SOFTDEP("pre: madera irq-madera arizona-micsupp");
2036MODULE_DESCRIPTION("ASoC CS47L92 driver");
2037MODULE_AUTHOR("Stuart Henderson <stuarth@opensource.cirrus.com>");
2038MODULE_LICENSE("GPL v2");
2039MODULE_ALIAS("platform:cs47l92-codec");
diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
index ed2959dbe1fb..36eef1fb3d18 100644
--- a/sound/soc/codecs/es8316.c
+++ b/sound/soc/codecs/es8316.c
@@ -9,6 +9,7 @@
9 9
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/acpi.h> 11#include <linux/acpi.h>
12#include <linux/clk.h>
12#include <linux/delay.h> 13#include <linux/delay.h>
13#include <linux/i2c.h> 14#include <linux/i2c.h>
14#include <linux/mod_devicetable.h> 15#include <linux/mod_devicetable.h>
@@ -33,6 +34,7 @@ static const unsigned int supported_mclk_lrck_ratios[] = {
33 34
34struct es8316_priv { 35struct es8316_priv {
35 struct mutex lock; 36 struct mutex lock;
37 struct clk *mclk;
36 struct regmap *regmap; 38 struct regmap *regmap;
37 struct snd_soc_component *component; 39 struct snd_soc_component *component;
38 struct snd_soc_jack *jack; 40 struct snd_soc_jack *jack;
@@ -363,13 +365,21 @@ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai,
363{ 365{
364 struct snd_soc_component *component = codec_dai->component; 366 struct snd_soc_component *component = codec_dai->component;
365 struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); 367 struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
366 int i; 368 int i, ret;
367 int count = 0; 369 int count = 0;
368 370
369 es8316->sysclk = freq; 371 es8316->sysclk = freq;
370 372
371 if (freq == 0) 373 if (freq == 0) {
374 es8316->sysclk_constraints.list = NULL;
375 es8316->sysclk_constraints.count = 0;
376
372 return 0; 377 return 0;
378 }
379
380 ret = clk_set_rate(es8316->mclk, freq);
381 if (ret)
382 return ret;
373 383
374 /* Limit supported sample rates to ones that can be autodetected 384 /* Limit supported sample rates to ones that can be autodetected
375 * by the codec running in slave mode. 385 * by the codec running in slave mode.
@@ -444,17 +454,10 @@ static int es8316_pcm_startup(struct snd_pcm_substream *substream,
444 struct snd_soc_component *component = dai->component; 454 struct snd_soc_component *component = dai->component;
445 struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); 455 struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
446 456
447 if (es8316->sysclk == 0) { 457 if (es8316->sysclk_constraints.list)
448 dev_err(component->dev, "No sysclk provided\n"); 458 snd_pcm_hw_constraint_list(substream->runtime, 0,
449 return -EINVAL; 459 SNDRV_PCM_HW_PARAM_RATE,
450 } 460 &es8316->sysclk_constraints);
451
452 /* The set of sample rates that can be supported depends on the
453 * MCLK supplied to the CODEC.
454 */
455 snd_pcm_hw_constraint_list(substream->runtime, 0,
456 SNDRV_PCM_HW_PARAM_RATE,
457 &es8316->sysclk_constraints);
458 461
459 return 0; 462 return 0;
460} 463}
@@ -466,11 +469,19 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream,
466 struct snd_soc_component *component = dai->component; 469 struct snd_soc_component *component = dai->component;
467 struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); 470 struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
468 u8 wordlen = 0; 471 u8 wordlen = 0;
472 int i;
469 473
470 if (!es8316->sysclk) { 474 /* Validate supported sample rates that are autodetected from MCLK */
471 dev_err(component->dev, "No MCLK configured\n"); 475 for (i = 0; i < NR_SUPPORTED_MCLK_LRCK_RATIOS; i++) {
472 return -EINVAL; 476 const unsigned int ratio = supported_mclk_lrck_ratios[i];
477
478 if (es8316->sysclk % ratio != 0)
479 continue;
480 if (es8316->sysclk / ratio == params_rate(params))
481 break;
473 } 482 }
483 if (i == NR_SUPPORTED_MCLK_LRCK_RATIOS)
484 return -EINVAL;
474 485
475 switch (params_format(params)) { 486 switch (params_format(params)) {
476 case SNDRV_PCM_FORMAT_S16_LE: 487 case SNDRV_PCM_FORMAT_S16_LE:
@@ -700,9 +711,24 @@ static int es8316_set_jack(struct snd_soc_component *component,
700static int es8316_probe(struct snd_soc_component *component) 711static int es8316_probe(struct snd_soc_component *component)
701{ 712{
702 struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); 713 struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
714 int ret;
703 715
704 es8316->component = component; 716 es8316->component = component;
705 717
718 es8316->mclk = devm_clk_get_optional(component->dev, "mclk");
719 if (IS_ERR(es8316->mclk)) {
720 dev_err(component->dev, "unable to get mclk\n");
721 return PTR_ERR(es8316->mclk);
722 }
723 if (!es8316->mclk)
724 dev_warn(component->dev, "assuming static mclk\n");
725
726 ret = clk_prepare_enable(es8316->mclk);
727 if (ret) {
728 dev_err(component->dev, "unable to enable mclk\n");
729 return ret;
730 }
731
706 /* Reset codec and enable current state machine */ 732 /* Reset codec and enable current state machine */
707 snd_soc_component_write(component, ES8316_RESET, 0x3f); 733 snd_soc_component_write(component, ES8316_RESET, 0x3f);
708 usleep_range(5000, 5500); 734 usleep_range(5000, 5500);
@@ -725,8 +751,16 @@ static int es8316_probe(struct snd_soc_component *component)
725 return 0; 751 return 0;
726} 752}
727 753
754static void es8316_remove(struct snd_soc_component *component)
755{
756 struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
757
758 clk_disable_unprepare(es8316->mclk);
759}
760
728static const struct snd_soc_component_driver soc_component_dev_es8316 = { 761static const struct snd_soc_component_driver soc_component_dev_es8316 = {
729 .probe = es8316_probe, 762 .probe = es8316_probe,
763 .remove = es8316_remove,
730 .set_jack = es8316_set_jack, 764 .set_jack = es8316_set_jack,
731 .controls = es8316_snd_controls, 765 .controls = es8316_snd_controls,
732 .num_controls = ARRAY_SIZE(es8316_snd_controls), 766 .num_controls = ARRAY_SIZE(es8316_snd_controls),
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c
index 69b81e704127..fdf64c29f563 100644
--- a/sound/soc/codecs/es8328.c
+++ b/sound/soc/codecs/es8328.c
@@ -99,7 +99,6 @@ static SOC_ENUM_SINGLE_DECL(adcpol,
99 99
100static const DECLARE_TLV_DB_SCALE(play_tlv, -3000, 100, 0); 100static const DECLARE_TLV_DB_SCALE(play_tlv, -3000, 100, 0);
101static const DECLARE_TLV_DB_SCALE(dac_adc_tlv, -9600, 50, 0); 101static const DECLARE_TLV_DB_SCALE(dac_adc_tlv, -9600, 50, 0);
102static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
103static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); 102static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
104static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 300, 0); 103static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 300, 0);
105 104
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index 0bf1c8cad108..b5fd8f08726e 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -7,6 +7,7 @@
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/string.h> 8#include <linux/string.h>
9#include <sound/core.h> 9#include <sound/core.h>
10#include <sound/jack.h>
10#include <sound/pcm.h> 11#include <sound/pcm.h>
11#include <sound/pcm_params.h> 12#include <sound/pcm_params.h>
12#include <sound/soc.h> 13#include <sound/soc.h>
@@ -274,6 +275,8 @@ struct hdmi_codec_priv {
274 struct snd_pcm_chmap *chmap_info; 275 struct snd_pcm_chmap *chmap_info;
275 unsigned int chmap_idx; 276 unsigned int chmap_idx;
276 struct mutex lock; 277 struct mutex lock;
278 struct snd_soc_jack *jack;
279 unsigned int jack_status;
277}; 280};
278 281
279static const struct snd_soc_dapm_widget hdmi_widgets[] = { 282static const struct snd_soc_dapm_widget hdmi_widgets[] = {
@@ -663,6 +666,49 @@ static int hdmi_dai_probe(struct snd_soc_dai *dai)
663 return 0; 666 return 0;
664} 667}
665 668
669static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp,
670 unsigned int jack_status)
671{
672 if (hcp->jack && jack_status != hcp->jack_status) {
673 snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT);
674 hcp->jack_status = jack_status;
675 }
676}
677
678static void plugged_cb(struct device *dev, bool plugged)
679{
680 struct hdmi_codec_priv *hcp = dev_get_drvdata(dev);
681
682 if (plugged)
683 hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT);
684 else
685 hdmi_codec_jack_report(hcp, 0);
686}
687
688/**
689 * hdmi_codec_set_jack_detect - register HDMI plugged callback
690 * @component: the hdmi-codec instance
691 * @jack: ASoC jack to report (dis)connection events on
692 */
693int hdmi_codec_set_jack_detect(struct snd_soc_component *component,
694 struct snd_soc_jack *jack)
695{
696 struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
697 int ret = -EOPNOTSUPP;
698
699 if (hcp->hcd.ops->hook_plugged_cb) {
700 hcp->jack = jack;
701 ret = hcp->hcd.ops->hook_plugged_cb(component->dev->parent,
702 hcp->hcd.data,
703 plugged_cb,
704 component->dev);
705 if (ret)
706 hcp->jack = NULL;
707 }
708 return ret;
709}
710EXPORT_SYMBOL_GPL(hdmi_codec_set_jack_detect);
711
666static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai) 712static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai)
667{ 713{
668 struct hdmi_codec_daifmt *cf = dai->playback_dma_data; 714 struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c
index 7feedbb7bbed..14d8fe1c28a4 100644
--- a/sound/soc/codecs/inno_rk3036.c
+++ b/sound/soc/codecs/inno_rk3036.c
@@ -405,7 +405,6 @@ static int rk3036_codec_platform_probe(struct platform_device *pdev)
405{ 405{
406 struct rk3036_codec_priv *priv; 406 struct rk3036_codec_priv *priv;
407 struct device_node *of_node = pdev->dev.of_node; 407 struct device_node *of_node = pdev->dev.of_node;
408 struct resource *res;
409 void __iomem *base; 408 void __iomem *base;
410 struct regmap *grf; 409 struct regmap *grf;
411 int ret; 410 int ret;
@@ -414,8 +413,7 @@ static int rk3036_codec_platform_probe(struct platform_device *pdev)
414 if (!priv) 413 if (!priv)
415 return -ENOMEM; 414 return -ENOMEM;
416 415
417 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 416 base = devm_platform_ioremap_resource(pdev, 0);
418 base = devm_ioremap_resource(&pdev->dev, res);
419 if (IS_ERR(base)) 417 if (IS_ERR(base))
420 return PTR_ERR(base); 418 return PTR_ERR(base);
421 419
diff --git a/sound/soc/codecs/jz4725b.c b/sound/soc/codecs/jz4725b.c
index 766354c73076..2567a5d15b55 100644
--- a/sound/soc/codecs/jz4725b.c
+++ b/sound/soc/codecs/jz4725b.c
@@ -545,15 +545,13 @@ static int jz4725b_codec_probe(struct platform_device *pdev)
545{ 545{
546 struct device *dev = &pdev->dev; 546 struct device *dev = &pdev->dev;
547 struct jz_icdc *icdc; 547 struct jz_icdc *icdc;
548 struct resource *mem;
549 int ret; 548 int ret;
550 549
551 icdc = devm_kzalloc(dev, sizeof(*icdc), GFP_KERNEL); 550 icdc = devm_kzalloc(dev, sizeof(*icdc), GFP_KERNEL);
552 if (!icdc) 551 if (!icdc)
553 return -ENOMEM; 552 return -ENOMEM;
554 553
555 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 554 icdc->base = devm_platform_ioremap_resource(pdev, 0);
556 icdc->base = devm_ioremap_resource(dev, mem);
557 if (IS_ERR(icdc->base)) 555 if (IS_ERR(icdc->base))
558 return PTR_ERR(icdc->base); 556 return PTR_ERR(icdc->base);
559 557
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 974e17fa1911..460aa1fd1efe 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -318,7 +318,6 @@ static int jz4740_codec_probe(struct platform_device *pdev)
318{ 318{
319 int ret; 319 int ret;
320 struct jz4740_codec *jz4740_codec; 320 struct jz4740_codec *jz4740_codec;
321 struct resource *mem;
322 void __iomem *base; 321 void __iomem *base;
323 322
324 jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec), 323 jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec),
@@ -326,8 +325,7 @@ static int jz4740_codec_probe(struct platform_device *pdev)
326 if (!jz4740_codec) 325 if (!jz4740_codec)
327 return -ENOMEM; 326 return -ENOMEM;
328 327
329 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 328 base = devm_platform_ioremap_resource(pdev, 0);
330 base = devm_ioremap_resource(&pdev->dev, mem);
331 if (IS_ERR(base)) 329 if (IS_ERR(base))
332 return PTR_ERR(base); 330 return PTR_ERR(base);
333 331
diff --git a/sound/soc/codecs/madera.c b/sound/soc/codecs/madera.c
index 1b1be19a2f99..52639811cc52 100644
--- a/sound/soc/codecs/madera.c
+++ b/sound/soc/codecs/madera.c
@@ -87,6 +87,16 @@
87#define MADERA_FLLAO_MIN_N 4 87#define MADERA_FLLAO_MIN_N 4
88#define MADERA_FLLAO_MAX_N 1023 88#define MADERA_FLLAO_MAX_N 1023
89#define MADERA_FLLAO_MAX_FBDIV 254 89#define MADERA_FLLAO_MAX_FBDIV 254
90#define MADERA_FLLHJ_INT_MAX_N 1023
91#define MADERA_FLLHJ_INT_MIN_N 1
92#define MADERA_FLLHJ_FRAC_MAX_N 255
93#define MADERA_FLLHJ_FRAC_MIN_N 4
94#define MADERA_FLLHJ_LOW_THRESH 192000
95#define MADERA_FLLHJ_MID_THRESH 1152000
96#define MADERA_FLLHJ_MAX_THRESH 13000000
97#define MADERA_FLLHJ_LOW_GAINS 0x23f0
98#define MADERA_FLLHJ_MID_GAINS 0x22f2
99#define MADERA_FLLHJ_HIGH_GAINS 0x21f0
90 100
91#define MADERA_FLL_SYNCHRONISER_OFFS 0x10 101#define MADERA_FLL_SYNCHRONISER_OFFS 0x10
92#define CS47L35_FLL_SYNCHRONISER_OFFS 0xE 102#define CS47L35_FLL_SYNCHRONISER_OFFS 0xE
@@ -96,6 +106,7 @@
96#define MADERA_FLL_CONTROL_4_OFFS 0x4 106#define MADERA_FLL_CONTROL_4_OFFS 0x4
97#define MADERA_FLL_CONTROL_5_OFFS 0x5 107#define MADERA_FLL_CONTROL_5_OFFS 0x5
98#define MADERA_FLL_CONTROL_6_OFFS 0x6 108#define MADERA_FLL_CONTROL_6_OFFS 0x6
109#define MADERA_FLL_GAIN_OFFS 0x8
99#define MADERA_FLL_CONTROL_7_OFFS 0x9 110#define MADERA_FLL_CONTROL_7_OFFS 0x9
100#define MADERA_FLL_EFS_2_OFFS 0xA 111#define MADERA_FLL_EFS_2_OFFS 0xA
101#define MADERA_FLL_SYNCHRONISER_1_OFFS 0x1 112#define MADERA_FLL_SYNCHRONISER_1_OFFS 0x1
@@ -107,6 +118,9 @@
107#define MADERA_FLL_SYNCHRONISER_7_OFFS 0x7 118#define MADERA_FLL_SYNCHRONISER_7_OFFS 0x7
108#define MADERA_FLL_SPREAD_SPECTRUM_OFFS 0x9 119#define MADERA_FLL_SPREAD_SPECTRUM_OFFS 0x9
109#define MADERA_FLL_GPIO_CLOCK_OFFS 0xA 120#define MADERA_FLL_GPIO_CLOCK_OFFS 0xA
121#define MADERA_FLL_CONTROL_10_OFFS 0xA
122#define MADERA_FLL_CONTROL_11_OFFS 0xB
123#define MADERA_FLL1_DIGITAL_TEST_1_OFFS 0xD
110 124
111#define MADERA_FLLAO_CONTROL_1_OFFS 0x1 125#define MADERA_FLLAO_CONTROL_1_OFFS 0x1
112#define MADERA_FLLAO_CONTROL_2_OFFS 0x2 126#define MADERA_FLLAO_CONTROL_2_OFFS 0x2
@@ -300,6 +314,100 @@ int madera_free_overheat(struct madera_priv *priv)
300} 314}
301EXPORT_SYMBOL_GPL(madera_free_overheat); 315EXPORT_SYMBOL_GPL(madera_free_overheat);
302 316
317static int madera_get_variable_u32_array(struct device *dev,
318 const char *propname,
319 u32 *dest, int n_max,
320 int multiple)
321{
322 int n, ret;
323
324 n = device_property_count_u32(dev, propname);
325 if (n < 0) {
326 if (n == -EINVAL)
327 return 0; /* missing, ignore */
328
329 dev_warn(dev, "%s malformed (%d)\n", propname, n);
330
331 return n;
332 } else if ((n % multiple) != 0) {
333 dev_warn(dev, "%s not a multiple of %d entries\n",
334 propname, multiple);
335
336 return -EINVAL;
337 }
338
339 if (n > n_max)
340 n = n_max;
341
342 ret = device_property_read_u32_array(dev, propname, dest, n);
343 if (ret < 0)
344 return ret;
345
346 return n;
347}
348
349static void madera_prop_get_inmode(struct madera_priv *priv)
350{
351 struct madera *madera = priv->madera;
352 struct madera_codec_pdata *pdata = &madera->pdata.codec;
353 u32 tmp[MADERA_MAX_INPUT * MADERA_MAX_MUXED_CHANNELS];
354 int n, i, in_idx, ch_idx;
355
356 BUILD_BUG_ON(ARRAY_SIZE(pdata->inmode) != MADERA_MAX_INPUT);
357 BUILD_BUG_ON(ARRAY_SIZE(pdata->inmode[0]) != MADERA_MAX_MUXED_CHANNELS);
358
359 n = madera_get_variable_u32_array(madera->dev, "cirrus,inmode",
360 tmp, ARRAY_SIZE(tmp),
361 MADERA_MAX_MUXED_CHANNELS);
362 if (n < 0)
363 return;
364
365 in_idx = 0;
366 ch_idx = 0;
367 for (i = 0; i < n; ++i) {
368 pdata->inmode[in_idx][ch_idx] = tmp[i];
369
370 if (++ch_idx == MADERA_MAX_MUXED_CHANNELS) {
371 ch_idx = 0;
372 ++in_idx;
373 }
374 }
375}
376
377static void madera_prop_get_pdata(struct madera_priv *priv)
378{
379 struct madera *madera = priv->madera;
380 struct madera_codec_pdata *pdata = &madera->pdata.codec;
381 u32 out_mono[ARRAY_SIZE(pdata->out_mono)];
382 int i, n;
383
384 madera_prop_get_inmode(priv);
385
386 n = madera_get_variable_u32_array(madera->dev, "cirrus,out-mono",
387 out_mono, ARRAY_SIZE(out_mono), 1);
388 if (n > 0)
389 for (i = 0; i < n; ++i)
390 pdata->out_mono[i] = !!out_mono[i];
391
392 madera_get_variable_u32_array(madera->dev,
393 "cirrus,max-channels-clocked",
394 pdata->max_channels_clocked,
395 ARRAY_SIZE(pdata->max_channels_clocked),
396 1);
397
398 madera_get_variable_u32_array(madera->dev, "cirrus,pdm-fmt",
399 pdata->pdm_fmt,
400 ARRAY_SIZE(pdata->pdm_fmt), 1);
401
402 madera_get_variable_u32_array(madera->dev, "cirrus,pdm-mute",
403 pdata->pdm_mute,
404 ARRAY_SIZE(pdata->pdm_mute), 1);
405
406 madera_get_variable_u32_array(madera->dev, "cirrus,dmic-ref",
407 pdata->dmic_ref,
408 ARRAY_SIZE(pdata->dmic_ref), 1);
409}
410
303int madera_core_init(struct madera_priv *priv) 411int madera_core_init(struct madera_priv *priv)
304{ 412{
305 int i; 413 int i;
@@ -308,6 +416,9 @@ int madera_core_init(struct madera_priv *priv)
308 BUILD_BUG_ON(!madera_mixer_texts[MADERA_NUM_MIXER_INPUTS - 1]); 416 BUILD_BUG_ON(!madera_mixer_texts[MADERA_NUM_MIXER_INPUTS - 1]);
309 BUILD_BUG_ON(!madera_mixer_values[MADERA_NUM_MIXER_INPUTS - 1]); 417 BUILD_BUG_ON(!madera_mixer_values[MADERA_NUM_MIXER_INPUTS - 1]);
310 418
419 if (!dev_get_platdata(priv->madera->dev))
420 madera_prop_get_pdata(priv);
421
311 mutex_init(&priv->rate_lock); 422 mutex_init(&priv->rate_lock);
312 423
313 for (i = 0; i < MADERA_MAX_HP_OUTPUT; i++) 424 for (i = 0; i < MADERA_MAX_HP_OUTPUT; i++)
@@ -944,6 +1055,10 @@ static void madera_configure_input_mode(struct madera *madera)
944 int max_analogue_inputs, max_dmic_sup, i; 1055 int max_analogue_inputs, max_dmic_sup, i;
945 1056
946 switch (madera->type) { 1057 switch (madera->type) {
1058 case CS47L15:
1059 max_analogue_inputs = 1;
1060 max_dmic_sup = 2;
1061 break;
947 case CS47L35: 1062 case CS47L35:
948 max_analogue_inputs = 2; 1063 max_analogue_inputs = 2;
949 max_dmic_sup = 2; 1064 max_dmic_sup = 2;
@@ -1770,6 +1885,18 @@ const struct soc_enum madera_asrc1_rate[] = {
1770}; 1885};
1771EXPORT_SYMBOL_GPL(madera_asrc1_rate); 1886EXPORT_SYMBOL_GPL(madera_asrc1_rate);
1772 1887
1888const struct soc_enum madera_asrc1_bidir_rate[] = {
1889 SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE1,
1890 MADERA_ASRC1_RATE1_SHIFT, 0xf,
1891 MADERA_RATE_ENUM_SIZE,
1892 madera_rate_text, madera_rate_val),
1893 SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE2,
1894 MADERA_ASRC1_RATE2_SHIFT, 0xf,
1895 MADERA_RATE_ENUM_SIZE,
1896 madera_rate_text, madera_rate_val),
1897};
1898EXPORT_SYMBOL_GPL(madera_asrc1_bidir_rate);
1899
1773const struct soc_enum madera_asrc2_rate[] = { 1900const struct soc_enum madera_asrc2_rate[] = {
1774 SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE1, 1901 SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE1,
1775 MADERA_ASRC2_RATE1_SHIFT, 0xf, 1902 MADERA_ASRC2_RATE1_SHIFT, 0xf,
@@ -2149,6 +2276,9 @@ int madera_out_ev(struct snd_soc_dapm_widget *w,
2149 switch (madera->type) { 2276 switch (madera->type) {
2150 case CS47L90: 2277 case CS47L90:
2151 case CS47L91: 2278 case CS47L91:
2279 case CS42L92:
2280 case CS47L92:
2281 case CS47L93:
2152 out_up_delay = 6; 2282 out_up_delay = 6;
2153 break; 2283 break;
2154 default: 2284 default:
@@ -2264,9 +2394,17 @@ int madera_hp_ev(struct snd_soc_dapm_widget *w,
2264 madera->hp_ena &= ~mask; 2394 madera->hp_ena &= ~mask;
2265 madera->hp_ena |= val; 2395 madera->hp_ena |= val;
2266 2396
2267 /* if OUT1 is routed to EPOUT, ignore HP clamp and impedance */ 2397 switch (madera->type) {
2268 regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel); 2398 case CS42L92:
2269 ep_sel &= MADERA_EP_SEL_MASK; 2399 case CS47L92:
2400 case CS47L93:
2401 break;
2402 default:
2403 /* if OUT1 is routed to EPOUT, ignore HP clamp and impedance */
2404 regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel);
2405 ep_sel &= MADERA_EP_SEL_MASK;
2406 break;
2407 }
2270 2408
2271 /* Force off if HPDET has disabled the clamp for this output */ 2409 /* Force off if HPDET has disabled the clamp for this output */
2272 if (!ep_sel && 2410 if (!ep_sel &&
@@ -2442,6 +2580,58 @@ static int madera_get_dspclk_setting(struct madera *madera,
2442 } 2580 }
2443} 2581}
2444 2582
2583static int madera_set_outclk(struct snd_soc_component *component,
2584 unsigned int source, unsigned int freq)
2585{
2586 int div, div_inc, rate;
2587
2588 switch (source) {
2589 case MADERA_OUTCLK_SYSCLK:
2590 dev_dbg(component->dev, "Configured OUTCLK to SYSCLK\n");
2591 snd_soc_component_update_bits(component, MADERA_OUTPUT_RATE_1,
2592 MADERA_OUT_CLK_SRC_MASK, source);
2593 return 0;
2594 case MADERA_OUTCLK_ASYNCCLK:
2595 dev_dbg(component->dev, "Configured OUTCLK to ASYNCCLK\n");
2596 snd_soc_component_update_bits(component, MADERA_OUTPUT_RATE_1,
2597 MADERA_OUT_CLK_SRC_MASK, source);
2598 return 0;
2599 case MADERA_OUTCLK_MCLK1:
2600 case MADERA_OUTCLK_MCLK2:
2601 case MADERA_OUTCLK_MCLK3:
2602 break;
2603 default:
2604 return -EINVAL;
2605 }
2606
2607 if (freq % 4000)
2608 rate = 5644800;
2609 else
2610 rate = 6144000;
2611
2612 div = 1;
2613 div_inc = 0;
2614 while (div <= 8) {
2615 if (freq / div == rate && !(freq % div)) {
2616 dev_dbg(component->dev, "Configured %dHz OUTCLK\n", rate);
2617 snd_soc_component_update_bits(component,
2618 MADERA_OUTPUT_RATE_1,
2619 MADERA_OUT_EXT_CLK_DIV_MASK |
2620 MADERA_OUT_CLK_SRC_MASK,
2621 (div_inc << MADERA_OUT_EXT_CLK_DIV_SHIFT) |
2622 source);
2623 return 0;
2624 }
2625 div_inc++;
2626 div *= 2;
2627 }
2628
2629 dev_err(component->dev,
2630 "Unable to generate %dHz OUTCLK from %dHz MCLK\n",
2631 rate, freq);
2632 return -EINVAL;
2633}
2634
2445int madera_set_sysclk(struct snd_soc_component *component, int clk_id, 2635int madera_set_sysclk(struct snd_soc_component *component, int clk_id,
2446 int source, unsigned int freq, int dir) 2636 int source, unsigned int freq, int dir)
2447{ 2637{
@@ -2478,6 +2668,8 @@ int madera_set_sysclk(struct snd_soc_component *component, int clk_id,
2478 case MADERA_CLK_OPCLK: 2668 case MADERA_CLK_OPCLK:
2479 case MADERA_CLK_ASYNC_OPCLK: 2669 case MADERA_CLK_ASYNC_OPCLK:
2480 return madera_set_opclk(component, clk_id, freq); 2670 return madera_set_opclk(component, clk_id, freq);
2671 case MADERA_CLK_OUTCLK:
2672 return madera_set_outclk(component, source, freq);
2481 default: 2673 default:
2482 return -EINVAL; 2674 return -EINVAL;
2483 } 2675 }
@@ -2691,6 +2883,10 @@ static const unsigned int madera_sr_vals[] = {
2691#define MADERA_192K_44K1_RATE_MASK 0x003E00 2883#define MADERA_192K_44K1_RATE_MASK 0x003E00
2692#define MADERA_192K_RATE_MASK (MADERA_192K_48K_RATE_MASK | \ 2884#define MADERA_192K_RATE_MASK (MADERA_192K_48K_RATE_MASK | \
2693 MADERA_192K_44K1_RATE_MASK) 2885 MADERA_192K_44K1_RATE_MASK)
2886#define MADERA_384K_48K_RATE_MASK 0x0F007E
2887#define MADERA_384K_44K1_RATE_MASK 0x007E00
2888#define MADERA_384K_RATE_MASK (MADERA_384K_48K_RATE_MASK | \
2889 MADERA_384K_44K1_RATE_MASK)
2694 2890
2695static const struct snd_pcm_hw_constraint_list madera_constraint = { 2891static const struct snd_pcm_hw_constraint_list madera_constraint = {
2696 .count = ARRAY_SIZE(madera_sr_vals), 2892 .count = ARRAY_SIZE(madera_sr_vals),
@@ -2703,6 +2899,7 @@ static int madera_startup(struct snd_pcm_substream *substream,
2703 struct snd_soc_component *component = dai->component; 2899 struct snd_soc_component *component = dai->component;
2704 struct madera_priv *priv = snd_soc_component_get_drvdata(component); 2900 struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2705 struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1]; 2901 struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
2902 struct madera *madera = priv->madera;
2706 unsigned int base_rate; 2903 unsigned int base_rate;
2707 2904
2708 if (!substream->runtime) 2905 if (!substream->runtime)
@@ -2722,12 +2919,26 @@ static int madera_startup(struct snd_pcm_substream *substream,
2722 return 0; 2919 return 0;
2723 } 2920 }
2724 2921
2725 if (base_rate == 0) 2922 switch (madera->type) {
2726 dai_priv->constraint.mask = MADERA_192K_RATE_MASK; 2923 case CS42L92:
2727 else if (base_rate % 4000) 2924 case CS47L92:
2728 dai_priv->constraint.mask = MADERA_192K_44K1_RATE_MASK; 2925 case CS47L93:
2729 else 2926 if (base_rate == 0)
2730 dai_priv->constraint.mask = MADERA_192K_48K_RATE_MASK; 2927 dai_priv->constraint.mask = MADERA_384K_RATE_MASK;
2928 else if (base_rate % 4000)
2929 dai_priv->constraint.mask = MADERA_384K_44K1_RATE_MASK;
2930 else
2931 dai_priv->constraint.mask = MADERA_384K_48K_RATE_MASK;
2932 break;
2933 default:
2934 if (base_rate == 0)
2935 dai_priv->constraint.mask = MADERA_192K_RATE_MASK;
2936 else if (base_rate % 4000)
2937 dai_priv->constraint.mask = MADERA_192K_44K1_RATE_MASK;
2938 else
2939 dai_priv->constraint.mask = MADERA_192K_48K_RATE_MASK;
2940 break;
2941 }
2731 2942
2732 return snd_pcm_hw_constraint_list(substream->runtime, 0, 2943 return snd_pcm_hw_constraint_list(substream->runtime, 0,
2733 SNDRV_PCM_HW_PARAM_RATE, 2944 SNDRV_PCM_HW_PARAM_RATE,
@@ -4048,6 +4259,308 @@ int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
4048} 4259}
4049EXPORT_SYMBOL_GPL(madera_set_fll_ao_refclk); 4260EXPORT_SYMBOL_GPL(madera_set_fll_ao_refclk);
4050 4261
4262static int madera_fllhj_disable(struct madera_fll *fll)
4263{
4264 struct madera *madera = fll->madera;
4265 bool change;
4266
4267 madera_fll_dbg(fll, "Disabling FLL\n");
4268
4269 /* Disable lockdet, but don't set ctrl_upd update but. This allows the
4270 * lock status bit to clear as normal, but should the FLL be enabled
4271 * again due to a control clock being required, the lock won't re-assert
4272 * as the FLL config registers are automatically applied when the FLL
4273 * enables.
4274 */
4275 regmap_update_bits(madera->regmap,
4276 fll->base + MADERA_FLL_CONTROL_11_OFFS,
4277 MADERA_FLL1_LOCKDET_MASK, 0);
4278 regmap_update_bits(madera->regmap,
4279 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4280 MADERA_FLL1_HOLD_MASK, MADERA_FLL1_HOLD_MASK);
4281 regmap_update_bits_check(madera->regmap,
4282 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4283 MADERA_FLL1_ENA_MASK, 0, &change);
4284
4285 madera_wait_for_fll(fll, false);
4286
4287 /* ctrl_up gates the writes to all the fll's registers, setting it to 0
4288 * here ensures that after a runtime suspend/resume cycle when one
4289 * enables the fll then ctrl_up is the last bit that is configured
4290 * by the fll enable code rather than the cache sync operation which
4291 * would have updated it much earlier before writing out all fll
4292 * registers
4293 */
4294 regmap_update_bits(madera->regmap,
4295 fll->base + MADERA_FLL_CONTROL_2_OFFS,
4296 MADERA_FLL1_CTRL_UPD_MASK, 0);
4297
4298 if (change)
4299 pm_runtime_put_autosuspend(madera->dev);
4300
4301 return 0;
4302}
4303
4304static int madera_fllhj_apply(struct madera_fll *fll, int fin)
4305{
4306 struct madera *madera = fll->madera;
4307 int refdiv, fref, fout, lockdet_thr, fbdiv, hp, fast_clk, fllgcd;
4308 bool frac = false;
4309 unsigned int fll_n, min_n, max_n, ratio, theta, lambda;
4310 unsigned int gains, val, num;
4311
4312 madera_fll_dbg(fll, "fin=%d, fout=%d\n", fin, fll->fout);
4313
4314 for (refdiv = 0; refdiv < 4; refdiv++)
4315 if ((fin / (1 << refdiv)) <= MADERA_FLLHJ_MAX_THRESH)
4316 break;
4317
4318 fref = fin / (1 << refdiv);
4319
4320 /* Use simple heuristic approach to find a configuration that
4321 * should work for most input clocks.
4322 */
4323 fast_clk = 0;
4324 fout = fll->fout;
4325 frac = fout % fref;
4326
4327 if (fref < MADERA_FLLHJ_LOW_THRESH) {
4328 lockdet_thr = 2;
4329 gains = MADERA_FLLHJ_LOW_GAINS;
4330 if (frac)
4331 fbdiv = 256;
4332 else
4333 fbdiv = 4;
4334 } else if (fref < MADERA_FLLHJ_MID_THRESH) {
4335 lockdet_thr = 8;
4336 gains = MADERA_FLLHJ_MID_GAINS;
4337 fbdiv = 1;
4338 } else {
4339 lockdet_thr = 8;
4340 gains = MADERA_FLLHJ_HIGH_GAINS;
4341 fbdiv = 1;
4342 /* For high speed input clocks, enable 300MHz fast oscillator
4343 * when we're in fractional divider mode.
4344 */
4345 if (frac) {
4346 fast_clk = 0x3;
4347 fout = fll->fout * 6;
4348 }
4349 }
4350 /* Use high performance mode for fractional configurations. */
4351 if (frac) {
4352 hp = 0x3;
4353 min_n = MADERA_FLLHJ_FRAC_MIN_N;
4354 max_n = MADERA_FLLHJ_FRAC_MAX_N;
4355 } else {
4356 hp = 0x0;
4357 min_n = MADERA_FLLHJ_INT_MIN_N;
4358 max_n = MADERA_FLLHJ_INT_MAX_N;
4359 }
4360
4361 ratio = fout / fref;
4362
4363 madera_fll_dbg(fll, "refdiv=%d, fref=%d, frac:%d\n",
4364 refdiv, fref, frac);
4365
4366 while (ratio / fbdiv < min_n) {
4367 fbdiv /= 2;
4368 if (fbdiv < 1) {
4369 madera_fll_err(fll, "FBDIV (%d) must be >= 1\n", fbdiv);
4370 return -EINVAL;
4371 }
4372 }
4373 while (frac && (ratio / fbdiv > max_n)) {
4374 fbdiv *= 2;
4375 if (fbdiv >= 1024) {
4376 madera_fll_err(fll, "FBDIV (%u) >= 1024\n", fbdiv);
4377 return -EINVAL;
4378 }
4379 }
4380
4381 madera_fll_dbg(fll, "lockdet=%d, hp=0x%x, fbdiv:%d\n",
4382 lockdet_thr, hp, fbdiv);
4383
4384 /* Calculate N.K values */
4385 fllgcd = gcd(fout, fbdiv * fref);
4386 num = fout / fllgcd;
4387 lambda = (fref * fbdiv) / fllgcd;
4388 fll_n = num / lambda;
4389 theta = num % lambda;
4390
4391 madera_fll_dbg(fll, "fll_n=%d, gcd=%d, theta=%d, lambda=%d\n",
4392 fll_n, fllgcd, theta, lambda);
4393
4394 /* Some sanity checks before any registers are written. */
4395 if (fll_n < min_n || fll_n > max_n) {
4396 madera_fll_err(fll, "N not in valid %s mode range %d-%d: %d\n",
4397 frac ? "fractional" : "integer", min_n, max_n,
4398 fll_n);
4399 return -EINVAL;
4400 }
4401 if (fbdiv < 1 || (frac && fbdiv >= 1024) || (!frac && fbdiv >= 256)) {
4402 madera_fll_err(fll, "Invalid fbdiv for %s mode (%u)\n",
4403 frac ? "fractional" : "integer", fbdiv);
4404 return -EINVAL;
4405 }
4406
4407 /* clear the ctrl_upd bit to guarantee we write to it later. */
4408 regmap_write(madera->regmap,
4409 fll->base + MADERA_FLL_CONTROL_2_OFFS,
4410 fll_n << MADERA_FLL1_N_SHIFT);
4411 regmap_update_bits(madera->regmap,
4412 fll->base + MADERA_FLL_CONTROL_3_OFFS,
4413 MADERA_FLL1_THETA_MASK,
4414 theta << MADERA_FLL1_THETA_SHIFT);
4415 regmap_update_bits(madera->regmap,
4416 fll->base + MADERA_FLL_CONTROL_4_OFFS,
4417 MADERA_FLL1_LAMBDA_MASK,
4418 lambda << MADERA_FLL1_LAMBDA_SHIFT);
4419 regmap_update_bits(madera->regmap,
4420 fll->base + MADERA_FLL_CONTROL_5_OFFS,
4421 MADERA_FLL1_FB_DIV_MASK,
4422 fbdiv << MADERA_FLL1_FB_DIV_SHIFT);
4423 regmap_update_bits(madera->regmap,
4424 fll->base + MADERA_FLL_CONTROL_6_OFFS,
4425 MADERA_FLL1_REFCLK_DIV_MASK,
4426 refdiv << MADERA_FLL1_REFCLK_DIV_SHIFT);
4427 regmap_update_bits(madera->regmap,
4428 fll->base + MADERA_FLL_GAIN_OFFS,
4429 0xffff,
4430 gains);
4431 val = hp << MADERA_FLL1_HP_SHIFT;
4432 val |= 1 << MADERA_FLL1_PHASEDET_ENA_SHIFT;
4433 regmap_update_bits(madera->regmap,
4434 fll->base + MADERA_FLL_CONTROL_10_OFFS,
4435 MADERA_FLL1_HP_MASK | MADERA_FLL1_PHASEDET_ENA_MASK,
4436 val);
4437 regmap_update_bits(madera->regmap,
4438 fll->base + MADERA_FLL_CONTROL_11_OFFS,
4439 MADERA_FLL1_LOCKDET_THR_MASK,
4440 lockdet_thr << MADERA_FLL1_LOCKDET_THR_SHIFT);
4441 regmap_update_bits(madera->regmap,
4442 fll->base + MADERA_FLL1_DIGITAL_TEST_1_OFFS,
4443 MADERA_FLL1_SYNC_EFS_ENA_MASK |
4444 MADERA_FLL1_CLK_VCO_FAST_SRC_MASK,
4445 fast_clk);
4446
4447 return 0;
4448}
4449
4450static int madera_fllhj_enable(struct madera_fll *fll)
4451{
4452 struct madera *madera = fll->madera;
4453 int already_enabled = madera_is_enabled_fll(fll, fll->base);
4454 int ret;
4455
4456 if (already_enabled < 0)
4457 return already_enabled;
4458
4459 if (!already_enabled)
4460 pm_runtime_get_sync(madera->dev);
4461
4462 madera_fll_dbg(fll, "Enabling FLL, initially %s\n",
4463 already_enabled ? "enabled" : "disabled");
4464
4465 /* FLLn_HOLD must be set before configuring any registers */
4466 regmap_update_bits(fll->madera->regmap,
4467 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4468 MADERA_FLL1_HOLD_MASK,
4469 MADERA_FLL1_HOLD_MASK);
4470
4471 /* Apply refclk */
4472 ret = madera_fllhj_apply(fll, fll->ref_freq);
4473 if (ret) {
4474 madera_fll_err(fll, "Failed to set FLL: %d\n", ret);
4475 goto out;
4476 }
4477 regmap_update_bits(madera->regmap,
4478 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4479 CS47L92_FLL1_REFCLK_SRC_MASK,
4480 fll->ref_src << CS47L92_FLL1_REFCLK_SRC_SHIFT);
4481
4482 regmap_update_bits(madera->regmap,
4483 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4484 MADERA_FLL1_ENA_MASK,
4485 MADERA_FLL1_ENA_MASK);
4486
4487out:
4488 regmap_update_bits(madera->regmap,
4489 fll->base + MADERA_FLL_CONTROL_11_OFFS,
4490 MADERA_FLL1_LOCKDET_MASK,
4491 MADERA_FLL1_LOCKDET_MASK);
4492
4493 regmap_update_bits(madera->regmap,
4494 fll->base + MADERA_FLL_CONTROL_2_OFFS,
4495 MADERA_FLL1_CTRL_UPD_MASK,
4496 MADERA_FLL1_CTRL_UPD_MASK);
4497
4498 /* Release the hold so that flln locks to external frequency */
4499 regmap_update_bits(madera->regmap,
4500 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4501 MADERA_FLL1_HOLD_MASK,
4502 0);
4503
4504 if (!already_enabled)
4505 madera_wait_for_fll(fll, true);
4506
4507 return 0;
4508}
4509
4510static int madera_fllhj_validate(struct madera_fll *fll,
4511 unsigned int ref_in,
4512 unsigned int fout)
4513{
4514 if (fout && !ref_in) {
4515 madera_fll_err(fll, "fllout set without valid input clk\n");
4516 return -EINVAL;
4517 }
4518
4519 if (fll->fout && fout != fll->fout) {
4520 madera_fll_err(fll, "Can't change output on active FLL\n");
4521 return -EINVAL;
4522 }
4523
4524 if (ref_in / MADERA_FLL_MAX_REFDIV > MADERA_FLLHJ_MAX_THRESH) {
4525 madera_fll_err(fll, "Can't scale %dMHz to <=13MHz\n", ref_in);
4526 return -EINVAL;
4527 }
4528
4529 return 0;
4530}
4531
4532int madera_fllhj_set_refclk(struct madera_fll *fll, int source,
4533 unsigned int fin, unsigned int fout)
4534{
4535 int ret = 0;
4536
4537 /* To remain consistent with previous FLLs, we expect fout to be
4538 * provided in the form of the required sysclk rate, which is
4539 * 2x the calculated fll out.
4540 */
4541 if (fout)
4542 fout /= 2;
4543
4544 if (fll->ref_src == source && fll->ref_freq == fin &&
4545 fll->fout == fout)
4546 return 0;
4547
4548 if (fin && fout && madera_fllhj_validate(fll, fin, fout))
4549 return -EINVAL;
4550
4551 fll->ref_src = source;
4552 fll->ref_freq = fin;
4553 fll->fout = fout;
4554
4555 if (fout)
4556 ret = madera_fllhj_enable(fll);
4557 else
4558 madera_fllhj_disable(fll);
4559
4560 return ret;
4561}
4562EXPORT_SYMBOL_GPL(madera_fllhj_set_refclk);
4563
4051/** 4564/**
4052 * madera_set_output_mode - Set the mode of the specified output 4565 * madera_set_output_mode - Set the mode of the specified output
4053 * 4566 *
diff --git a/sound/soc/codecs/madera.h b/sound/soc/codecs/madera.h
index 0af66f280770..1f3e8e230cf2 100644
--- a/sound/soc/codecs/madera.h
+++ b/sound/soc/codecs/madera.h
@@ -47,6 +47,7 @@
47#define MADERA_CLK_SYSCLK_3 6 47#define MADERA_CLK_SYSCLK_3 6
48#define MADERA_CLK_ASYNCCLK_2 7 48#define MADERA_CLK_ASYNCCLK_2 7
49#define MADERA_CLK_DSPCLK 8 49#define MADERA_CLK_DSPCLK 8
50#define MADERA_CLK_OUTCLK 9
50 51
51#define MADERA_CLK_SRC_MCLK1 0x0 52#define MADERA_CLK_SRC_MCLK1 0x0
52#define MADERA_CLK_SRC_MCLK2 0x1 53#define MADERA_CLK_SRC_MCLK2 0x1
@@ -61,6 +62,12 @@
61#define MADERA_CLK_SRC_AIF4BCLK 0xB 62#define MADERA_CLK_SRC_AIF4BCLK 0xB
62#define MADERA_CLK_SRC_FLLAO 0xF 63#define MADERA_CLK_SRC_FLLAO 0xF
63 64
65#define MADERA_OUTCLK_SYSCLK 0
66#define MADERA_OUTCLK_ASYNCCLK 1
67#define MADERA_OUTCLK_MCLK1 4
68#define MADERA_OUTCLK_MCLK2 5
69#define MADERA_OUTCLK_MCLK3 6
70
64#define MADERA_MIXER_VOL_MASK 0x00FE 71#define MADERA_MIXER_VOL_MASK 0x00FE
65#define MADERA_MIXER_VOL_SHIFT 1 72#define MADERA_MIXER_VOL_SHIFT 1
66#define MADERA_MIXER_VOL_WIDTH 7 73#define MADERA_MIXER_VOL_WIDTH 7
@@ -326,6 +333,7 @@ extern const struct soc_enum madera_sample_rate[];
326extern const struct soc_enum madera_isrc_fsl[]; 333extern const struct soc_enum madera_isrc_fsl[];
327extern const struct soc_enum madera_isrc_fsh[]; 334extern const struct soc_enum madera_isrc_fsh[];
328extern const struct soc_enum madera_asrc1_rate[]; 335extern const struct soc_enum madera_asrc1_rate[];
336extern const struct soc_enum madera_asrc1_bidir_rate[];
329extern const struct soc_enum madera_asrc2_rate[]; 337extern const struct soc_enum madera_asrc2_rate[];
330extern const struct soc_enum madera_dfc_width[]; 338extern const struct soc_enum madera_dfc_width[];
331extern const struct soc_enum madera_dfc_type[]; 339extern const struct soc_enum madera_dfc_type[];
@@ -403,6 +411,8 @@ int madera_set_fll_syncclk(struct madera_fll *fll, int source,
403 unsigned int fref, unsigned int fout); 411 unsigned int fref, unsigned int fout);
404int madera_set_fll_ao_refclk(struct madera_fll *fll, int source, 412int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
405 unsigned int fin, unsigned int fout); 413 unsigned int fin, unsigned int fout);
414int madera_fllhj_set_refclk(struct madera_fll *fll, int source,
415 unsigned int fin, unsigned int fout);
406 416
407int madera_core_init(struct madera_priv *priv); 417int madera_core_init(struct madera_priv *priv);
408int madera_core_free(struct madera_priv *priv); 418int madera_core_free(struct madera_priv *priv);
diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c
index ce801489a86d..dfee05f985bd 100644
--- a/sound/soc/codecs/max98371.c
+++ b/sound/soc/codecs/max98371.c
@@ -154,10 +154,6 @@ static const DECLARE_TLV_DB_RANGE(max98371_gain_tlv,
154 8, 10, TLV_DB_SCALE_ITEM(400, 100, 0) 154 8, 10, TLV_DB_SCALE_ITEM(400, 100, 0)
155); 155);
156 156
157static const DECLARE_TLV_DB_RANGE(max98371_noload_gain_tlv,
158 0, 11, TLV_DB_SCALE_ITEM(950, 100, 0),
159);
160
161static const DECLARE_TLV_DB_SCALE(digital_tlv, -6300, 50, 1); 157static const DECLARE_TLV_DB_SCALE(digital_tlv, -6300, 50, 1);
162 158
163static const struct snd_kcontrol_new max98371_snd_controls[] = { 159static const struct snd_kcontrol_new max98371_snd_controls[] = {
diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c
index 8c601a3ebc27..e609abcf3220 100644
--- a/sound/soc/codecs/max98373.c
+++ b/sound/soc/codecs/max98373.c
@@ -12,6 +12,7 @@
12#include <sound/pcm_params.h> 12#include <sound/pcm_params.h>
13#include <sound/soc.h> 13#include <sound/soc.h>
14#include <linux/gpio.h> 14#include <linux/gpio.h>
15#include <linux/of.h>
15#include <linux/of_gpio.h> 16#include <linux/of_gpio.h>
16#include <sound/tlv.h> 17#include <sound/tlv.h>
17#include "max98373.h" 18#include "max98373.h"
@@ -901,6 +902,17 @@ static void max98373_slot_config(struct i2c_client *i2c,
901 else 902 else
902 max98373->i_slot = 1; 903 max98373->i_slot = 1;
903 904
905 max98373->reset_gpio = of_get_named_gpio(dev->of_node,
906 "maxim,reset-gpio", 0);
907 if (!gpio_is_valid(max98373->reset_gpio)) {
908 dev_err(dev, "Looking up %s property in node %s failed %d\n",
909 "maxim,reset-gpio", dev->of_node->full_name,
910 max98373->reset_gpio);
911 } else {
912 dev_dbg(dev, "maxim,reset-gpio=%d",
913 max98373->reset_gpio);
914 }
915
904 if (!device_property_read_u32(dev, "maxim,spkfb-slot-no", &value)) 916 if (!device_property_read_u32(dev, "maxim,spkfb-slot-no", &value))
905 max98373->spkfb_slot = value & 0xF; 917 max98373->spkfb_slot = value & 0xF;
906 else 918 else
@@ -929,7 +941,6 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
929 else 941 else
930 max98373->interleave_mode = false; 942 max98373->interleave_mode = false;
931 943
932
933 /* regmap initialization */ 944 /* regmap initialization */
934 max98373->regmap 945 max98373->regmap
935 = devm_regmap_init_i2c(i2c, &max98373_regmap); 946 = devm_regmap_init_i2c(i2c, &max98373_regmap);
@@ -940,6 +951,24 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
940 return ret; 951 return ret;
941 } 952 }
942 953
954 /* voltage/current slot & gpio configuration */
955 max98373_slot_config(i2c, max98373);
956
957 /* Power on device */
958 if (gpio_is_valid(max98373->reset_gpio)) {
959 ret = gpio_request(max98373->reset_gpio, "MAX98373_RESET");
960 if (ret) {
961 dev_err(&i2c->dev, "%s: Failed to request gpio %d\n",
962 __func__, max98373->reset_gpio);
963 gpio_free(max98373->reset_gpio);
964 return -EINVAL;
965 }
966 gpio_direction_output(max98373->reset_gpio, 0);
967 msleep(50);
968 gpio_direction_output(max98373->reset_gpio, 1);
969 msleep(20);
970 }
971
943 /* Check Revision ID */ 972 /* Check Revision ID */
944 ret = regmap_read(max98373->regmap, 973 ret = regmap_read(max98373->regmap,
945 MAX98373_R21FF_REV_ID, &reg); 974 MAX98373_R21FF_REV_ID, &reg);
@@ -950,9 +979,6 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
950 } 979 }
951 dev_info(&i2c->dev, "MAX98373 revisionID: 0x%02X\n", reg); 980 dev_info(&i2c->dev, "MAX98373 revisionID: 0x%02X\n", reg);
952 981
953 /* voltage/current slot configuration */
954 max98373_slot_config(i2c, max98373);
955
956 /* codec registeration */ 982 /* codec registeration */
957 ret = devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_max98373, 983 ret = devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_max98373,
958 max98373_dai, ARRAY_SIZE(max98373_dai)); 984 max98373_dai, ARRAY_SIZE(max98373_dai));
diff --git a/sound/soc/codecs/max98373.h b/sound/soc/codecs/max98373.h
index a59e51355a84..63dae8be7105 100644
--- a/sound/soc/codecs/max98373.h
+++ b/sound/soc/codecs/max98373.h
@@ -205,6 +205,7 @@
205 205
206struct max98373_priv { 206struct max98373_priv {
207 struct regmap *regmap; 207 struct regmap *regmap;
208 int reset_gpio;
208 unsigned int v_slot; 209 unsigned int v_slot;
209 unsigned int i_slot; 210 unsigned int i_slot;
210 unsigned int spkfb_slot; 211 unsigned int spkfb_slot;
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
index f50ee8f5fe93..6f43748f9239 100644
--- a/sound/soc/codecs/max9850.c
+++ b/sound/soc/codecs/max9850.c
@@ -27,19 +27,6 @@ struct max9850_priv {
27 unsigned int sysclk; 27 unsigned int sysclk;
28}; 28};
29 29
30/* max9850 register cache */
31static const struct reg_default max9850_reg[] = {
32 { 2, 0x0c },
33 { 3, 0x00 },
34 { 4, 0x00 },
35 { 5, 0x00 },
36 { 6, 0x00 },
37 { 7, 0x00 },
38 { 8, 0x00 },
39 { 9, 0x00 },
40 { 10, 0x00 },
41};
42
43/* these registers are not used at the moment but provided for the sake of 30/* these registers are not used at the moment but provided for the sake of
44 * completeness */ 31 * completeness */
45static bool max9850_volatile_register(struct device *dev, unsigned int reg) 32static bool max9850_volatile_register(struct device *dev, unsigned int reg)
diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c
index 818c0301fb29..c4dfa8ab1d49 100644
--- a/sound/soc/codecs/max98926.c
+++ b/sound/soc/codecs/max98926.c
@@ -20,15 +20,6 @@ static const char * const max98926_boost_voltage_txt[] = {
20 "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V" 20 "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V"
21}; 21};
22 22
23static const char * const max98926_boost_current_txt[] = {
24 "0.6", "0.8", "1.0", "1.2", "1.4", "1.6", "1.8", "2.0",
25 "2.2", "2.4", "2.6", "2.8", "3.2", "3.6", "4.0", "4.4"
26};
27
28static const char *const max98926_dai_txt[] = {
29 "Left", "Right", "LeftRight", "LeftRightDiv2",
30};
31
32static const char *const max98926_pdm_ch_text[] = { 23static const char *const max98926_pdm_ch_text[] = {
33 "Current", "Voltage", 24 "Current", "Voltage",
34}; 25};
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
index 3abd27893ce6..55823bc95d06 100644
--- a/sound/soc/codecs/ml26124.c
+++ b/sound/soc/codecs/ml26124.c
@@ -56,7 +56,6 @@ static const DECLARE_TLV_DB_SCALE(alclvl, -2250, 150, 0);
56static const DECLARE_TLV_DB_SCALE(mingain, -1200, 600, 0); 56static const DECLARE_TLV_DB_SCALE(mingain, -1200, 600, 0);
57static const DECLARE_TLV_DB_SCALE(maxgain, -675, 600, 0); 57static const DECLARE_TLV_DB_SCALE(maxgain, -675, 600, 0);
58static const DECLARE_TLV_DB_SCALE(boost_vol, -1200, 75, 0); 58static const DECLARE_TLV_DB_SCALE(boost_vol, -1200, 75, 0);
59static const DECLARE_TLV_DB_SCALE(ngth, -7650, 150, 0);
60 59
61static const char * const ml26124_companding[] = {"16bit PCM", "u-law", 60static const char * const ml26124_companding[] = {"16bit PCM", "u-law",
62 "A-law"}; 61 "A-law"};
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c
index 368b6c09474b..667e9f73aba3 100644
--- a/sound/soc/codecs/msm8916-wcd-analog.c
+++ b/sound/soc/codecs/msm8916-wcd-analog.c
@@ -1185,10 +1185,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
1185 } 1185 }
1186 1186
1187 irq = platform_get_irq_byname(pdev, "mbhc_switch_int"); 1187 irq = platform_get_irq_byname(pdev, "mbhc_switch_int");
1188 if (irq < 0) { 1188 if (irq < 0)
1189 dev_err(dev, "failed to get mbhc switch irq\n");
1190 return irq; 1189 return irq;
1191 }
1192 1190
1193 ret = devm_request_threaded_irq(dev, irq, NULL, 1191 ret = devm_request_threaded_irq(dev, irq, NULL,
1194 pm8916_mbhc_switch_irq_handler, 1192 pm8916_mbhc_switch_irq_handler,
@@ -1200,10 +1198,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
1200 1198
1201 if (priv->mbhc_btn_enabled) { 1199 if (priv->mbhc_btn_enabled) {
1202 irq = platform_get_irq_byname(pdev, "mbhc_but_press_det"); 1200 irq = platform_get_irq_byname(pdev, "mbhc_but_press_det");
1203 if (irq < 0) { 1201 if (irq < 0)
1204 dev_err(dev, "failed to get button press irq\n");
1205 return irq; 1202 return irq;
1206 }
1207 1203
1208 ret = devm_request_threaded_irq(dev, irq, NULL, 1204 ret = devm_request_threaded_irq(dev, irq, NULL,
1209 mbhc_btn_press_irq_handler, 1205 mbhc_btn_press_irq_handler,
@@ -1214,10 +1210,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
1214 dev_err(dev, "cannot request mbhc button press irq\n"); 1210 dev_err(dev, "cannot request mbhc button press irq\n");
1215 1211
1216 irq = platform_get_irq_byname(pdev, "mbhc_but_rel_det"); 1212 irq = platform_get_irq_byname(pdev, "mbhc_but_rel_det");
1217 if (irq < 0) { 1213 if (irq < 0)
1218 dev_err(dev, "failed to get button release irq\n");
1219 return irq; 1214 return irq;
1220 }
1221 1215
1222 ret = devm_request_threaded_irq(dev, irq, NULL, 1216 ret = devm_request_threaded_irq(dev, irq, NULL,
1223 mbhc_btn_release_irq_handler, 1217 mbhc_btn_release_irq_handler,
diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c
index 1db7e43ec203..9fa5d44fdc79 100644
--- a/sound/soc/codecs/msm8916-wcd-digital.c
+++ b/sound/soc/codecs/msm8916-wcd-digital.c
@@ -1143,7 +1143,6 @@ static int msm8916_wcd_digital_probe(struct platform_device *pdev)
1143 struct msm8916_wcd_digital_priv *priv; 1143 struct msm8916_wcd_digital_priv *priv;
1144 struct device *dev = &pdev->dev; 1144 struct device *dev = &pdev->dev;
1145 void __iomem *base; 1145 void __iomem *base;
1146 struct resource *mem_res;
1147 struct regmap *digital_map; 1146 struct regmap *digital_map;
1148 int ret; 1147 int ret;
1149 1148
@@ -1151,8 +1150,7 @@ static int msm8916_wcd_digital_probe(struct platform_device *pdev)
1151 if (!priv) 1150 if (!priv)
1152 return -ENOMEM; 1151 return -ENOMEM;
1153 1152
1154 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1153 base = devm_platform_ioremap_resource(pdev, 0);
1155 base = devm_ioremap_resource(&pdev->dev, mem_res);
1156 if (IS_ERR(base)) 1154 if (IS_ERR(base))
1157 return PTR_ERR(base); 1155 return PTR_ERR(base);
1158 1156
diff --git a/sound/soc/codecs/mt6351.c b/sound/soc/codecs/mt6351.c
index 4b3ce01c5a93..5c0536eb1044 100644
--- a/sound/soc/codecs/mt6351.c
+++ b/sound/soc/codecs/mt6351.c
@@ -1066,11 +1066,6 @@ static int mt_mic_bias_2_event(struct snd_soc_dapm_widget *w,
1066 return 0; 1066 return 0;
1067} 1067}
1068 1068
1069/* DAPM Kcontrols */
1070static const struct snd_kcontrol_new mt_lineout_control =
1071 SOC_DAPM_SINGLE("Switch", MT6351_AUDDEC_ANA_CON3,
1072 RG_AUDLOLPWRUP_VAUDP32_BIT, 1, 0);
1073
1074/* DAPM Widgets */ 1069/* DAPM Widgets */
1075static const struct snd_soc_dapm_widget mt6351_dapm_widgets[] = { 1070static const struct snd_soc_dapm_widget mt6351_dapm_widgets[] = {
1076 /* Digital Clock */ 1071 /* Digital Clock */
diff --git a/sound/soc/codecs/mt6358.c b/sound/soc/codecs/mt6358.c
index 50b3fc5457ea..bb737fd678cc 100644
--- a/sound/soc/codecs/mt6358.c
+++ b/sound/soc/codecs/mt6358.c
@@ -1730,6 +1730,10 @@ static int mt6358_dmic_enable(struct mt6358_priv *priv)
1730 1730
1731 /* UL turn on */ 1731 /* UL turn on */
1732 regmap_write(priv->regmap, MT6358_AFE_UL_SRC_CON0_L, 0x0003); 1732 regmap_write(priv->regmap, MT6358_AFE_UL_SRC_CON0_L, 0x0003);
1733
1734 /* Prevent pop noise form dmic hw */
1735 msleep(100);
1736
1733 return 0; 1737 return 0;
1734} 1738}
1735 1739
@@ -2255,10 +2259,8 @@ static struct snd_soc_dai_driver mt6358_dai_driver[] = {
2255 }, 2259 },
2256}; 2260};
2257 2261
2258static int mt6358_codec_init_reg(struct mt6358_priv *priv) 2262static void mt6358_codec_init_reg(struct mt6358_priv *priv)
2259{ 2263{
2260 int ret = 0;
2261
2262 /* Disable HeadphoneL/HeadphoneR short circuit protection */ 2264 /* Disable HeadphoneL/HeadphoneR short circuit protection */
2263 regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0, 2265 regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
2264 RG_AUDHPLSCDISABLE_VAUDP15_MASK_SFT, 2266 RG_AUDHPLSCDISABLE_VAUDP15_MASK_SFT,
@@ -2285,8 +2287,6 @@ static int mt6358_codec_init_reg(struct mt6358_priv *priv)
2285 /* set gpio */ 2287 /* set gpio */
2286 playback_gpio_reset(priv); 2288 playback_gpio_reset(priv);
2287 capture_gpio_reset(priv); 2289 capture_gpio_reset(priv);
2288
2289 return ret;
2290} 2290}
2291 2291
2292static int mt6358_codec_probe(struct snd_soc_component *cmpnt) 2292static int mt6358_codec_probe(struct snd_soc_component *cmpnt)
diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c
index f1104d7d6426..50ed86d45c26 100644
--- a/sound/soc/codecs/pcm3168a.c
+++ b/sound/soc/codecs/pcm3168a.c
@@ -44,18 +44,25 @@ static const char *const pcm3168a_supply_names[PCM3168A_NUM_SUPPLIES] = {
44 "VCCDA2" 44 "VCCDA2"
45}; 45};
46 46
47#define PCM3168A_DAI_DAC 0
48#define PCM3168A_DAI_ADC 1
49
50/* ADC/DAC side parameters */
51struct pcm3168a_io_params {
52 bool master_mode;
53 unsigned int fmt;
54 int tdm_slots;
55 u32 tdm_mask;
56 int slot_width;
57};
58
47struct pcm3168a_priv { 59struct pcm3168a_priv {
48 struct regulator_bulk_data supplies[PCM3168A_NUM_SUPPLIES]; 60 struct regulator_bulk_data supplies[PCM3168A_NUM_SUPPLIES];
49 struct regmap *regmap; 61 struct regmap *regmap;
50 struct clk *scki; 62 struct clk *scki;
51 bool adc_master_mode;
52 bool dac_master_mode;
53 unsigned long sysclk; 63 unsigned long sysclk;
54 unsigned int adc_fmt; 64
55 unsigned int dac_fmt; 65 struct pcm3168a_io_params io_params[2];
56 int tdm_slots;
57 u32 tdm_mask[2];
58 int slot_width;
59}; 66};
60 67
61static const char *const pcm3168a_roll_off[] = { "Sharp", "Slow" }; 68static const char *const pcm3168a_roll_off[] = { "Sharp", "Slow" };
@@ -263,7 +270,7 @@ static unsigned int pcm3168a_scki_ratios[] = {
263#define PCM3168A_NUM_SCKI_RATIOS_DAC ARRAY_SIZE(pcm3168a_scki_ratios) 270#define PCM3168A_NUM_SCKI_RATIOS_DAC ARRAY_SIZE(pcm3168a_scki_ratios)
264#define PCM3168A_NUM_SCKI_RATIOS_ADC (ARRAY_SIZE(pcm3168a_scki_ratios) - 2) 271#define PCM3168A_NUM_SCKI_RATIOS_ADC (ARRAY_SIZE(pcm3168a_scki_ratios) - 2)
265 272
266#define PCM1368A_MAX_SYSCLK 36864000 273#define PCM3168A_MAX_SYSCLK 36864000
267 274
268static int pcm3168a_reset(struct pcm3168a_priv *pcm3168a) 275static int pcm3168a_reset(struct pcm3168a_priv *pcm3168a)
269{ 276{
@@ -296,7 +303,7 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
296 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component); 303 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component);
297 int ret; 304 int ret;
298 305
299 if (freq > PCM1368A_MAX_SYSCLK) 306 if (freq > PCM3168A_MAX_SYSCLK)
300 return -EINVAL; 307 return -EINVAL;
301 308
302 ret = clk_set_rate(pcm3168a->scki, freq); 309 ret = clk_set_rate(pcm3168a->scki, freq);
@@ -308,8 +315,7 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
308 return 0; 315 return 0;
309} 316}
310 317
311static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai, 318static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format)
312 unsigned int format, bool dac)
313{ 319{
314 struct snd_soc_component *component = dai->component; 320 struct snd_soc_component *component = dai->component;
315 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component); 321 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
@@ -356,43 +362,31 @@ static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
356 return -EINVAL; 362 return -EINVAL;
357 } 363 }
358 364
359 if (dac) { 365 if (dai->id == PCM3168A_DAI_DAC) {
360 reg = PCM3168A_DAC_PWR_MST_FMT; 366 reg = PCM3168A_DAC_PWR_MST_FMT;
361 mask = PCM3168A_DAC_FMT_MASK; 367 mask = PCM3168A_DAC_FMT_MASK;
362 shift = PCM3168A_DAC_FMT_SHIFT; 368 shift = PCM3168A_DAC_FMT_SHIFT;
363 pcm3168a->dac_master_mode = master_mode;
364 pcm3168a->dac_fmt = fmt;
365 } else { 369 } else {
366 reg = PCM3168A_ADC_MST_FMT; 370 reg = PCM3168A_ADC_MST_FMT;
367 mask = PCM3168A_ADC_FMTAD_MASK; 371 mask = PCM3168A_ADC_FMTAD_MASK;
368 shift = PCM3168A_ADC_FMTAD_SHIFT; 372 shift = PCM3168A_ADC_FMTAD_SHIFT;
369 pcm3168a->adc_master_mode = master_mode;
370 pcm3168a->adc_fmt = fmt;
371 } 373 }
372 374
375 pcm3168a->io_params[dai->id].master_mode = master_mode;
376 pcm3168a->io_params[dai->id].fmt = fmt;
377
373 regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift); 378 regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
374 379
375 return 0; 380 return 0;
376} 381}
377 382
378static int pcm3168a_set_dai_fmt_dac(struct snd_soc_dai *dai,
379 unsigned int format)
380{
381 return pcm3168a_set_dai_fmt(dai, format, true);
382}
383
384static int pcm3168a_set_dai_fmt_adc(struct snd_soc_dai *dai,
385 unsigned int format)
386{
387 return pcm3168a_set_dai_fmt(dai, format, false);
388}
389
390static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 383static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
391 unsigned int rx_mask, int slots, 384 unsigned int rx_mask, int slots,
392 int slot_width) 385 int slot_width)
393{ 386{
394 struct snd_soc_component *component = dai->component; 387 struct snd_soc_component *component = dai->component;
395 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component); 388 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
389 struct pcm3168a_io_params *io_params = &pcm3168a->io_params[dai->id];
396 390
397 if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) { 391 if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) {
398 dev_err(component->dev, 392 dev_err(component->dev,
@@ -408,22 +402,13 @@ static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
408 return -EINVAL; 402 return -EINVAL;
409 } 403 }
410 404
411 if (pcm3168a->tdm_slots && pcm3168a->tdm_slots != slots) { 405 io_params->tdm_slots = slots;
412 dev_err(component->dev, "Not matching slots %d vs %d\n", 406 io_params->slot_width = slot_width;
413 pcm3168a->tdm_slots, slots); 407 /* Ignore the not relevant mask for the DAI/direction */
414 return -EINVAL; 408 if (dai->id == PCM3168A_DAI_DAC)
415 } 409 io_params->tdm_mask = tx_mask;
416 410 else
417 if (pcm3168a->slot_width && pcm3168a->slot_width != slot_width) { 411 io_params->tdm_mask = rx_mask;
418 dev_err(component->dev, "Not matching slot_width %d vs %d\n",
419 pcm3168a->slot_width, slot_width);
420 return -EINVAL;
421 }
422
423 pcm3168a->tdm_slots = slots;
424 pcm3168a->slot_width = slot_width;
425 pcm3168a->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask;
426 pcm3168a->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask;
427 412
428 return 0; 413 return 0;
429} 414}
@@ -434,7 +419,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
434{ 419{
435 struct snd_soc_component *component = dai->component; 420 struct snd_soc_component *component = dai->component;
436 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component); 421 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
437 bool tx, master_mode; 422 struct pcm3168a_io_params *io_params = &pcm3168a->io_params[dai->id];
423 bool master_mode;
438 u32 val, mask, shift, reg; 424 u32 val, mask, shift, reg;
439 unsigned int rate, fmt, ratio, max_ratio; 425 unsigned int rate, fmt, ratio, max_ratio;
440 unsigned int tdm_slots; 426 unsigned int tdm_slots;
@@ -444,23 +430,21 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
444 430
445 ratio = pcm3168a->sysclk / rate; 431 ratio = pcm3168a->sysclk / rate;
446 432
447 tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 433 if (dai->id == PCM3168A_DAI_DAC) {
448 if (tx) {
449 max_ratio = PCM3168A_NUM_SCKI_RATIOS_DAC; 434 max_ratio = PCM3168A_NUM_SCKI_RATIOS_DAC;
450 reg = PCM3168A_DAC_PWR_MST_FMT; 435 reg = PCM3168A_DAC_PWR_MST_FMT;
451 mask = PCM3168A_DAC_MSDA_MASK; 436 mask = PCM3168A_DAC_MSDA_MASK;
452 shift = PCM3168A_DAC_MSDA_SHIFT; 437 shift = PCM3168A_DAC_MSDA_SHIFT;
453 master_mode = pcm3168a->dac_master_mode;
454 fmt = pcm3168a->dac_fmt;
455 } else { 438 } else {
456 max_ratio = PCM3168A_NUM_SCKI_RATIOS_ADC; 439 max_ratio = PCM3168A_NUM_SCKI_RATIOS_ADC;
457 reg = PCM3168A_ADC_MST_FMT; 440 reg = PCM3168A_ADC_MST_FMT;
458 mask = PCM3168A_ADC_MSAD_MASK; 441 mask = PCM3168A_ADC_MSAD_MASK;
459 shift = PCM3168A_ADC_MSAD_SHIFT; 442 shift = PCM3168A_ADC_MSAD_SHIFT;
460 master_mode = pcm3168a->adc_master_mode;
461 fmt = pcm3168a->adc_fmt;
462 } 443 }
463 444
445 master_mode = io_params->master_mode;
446 fmt = io_params->fmt;
447
464 for (i = 0; i < max_ratio; i++) { 448 for (i = 0; i < max_ratio; i++) {
465 if (pcm3168a_scki_ratios[i] == ratio) 449 if (pcm3168a_scki_ratios[i] == ratio)
466 break; 450 break;
@@ -471,8 +455,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
471 return -EINVAL; 455 return -EINVAL;
472 } 456 }
473 457
474 if (pcm3168a->slot_width) 458 if (io_params->slot_width)
475 slot_width = pcm3168a->slot_width; 459 slot_width = io_params->slot_width;
476 else 460 else
477 slot_width = params_width(params); 461 slot_width = params_width(params);
478 462
@@ -497,8 +481,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
497 return -EINVAL; 481 return -EINVAL;
498 } 482 }
499 483
500 if (pcm3168a->tdm_slots) 484 if (io_params->tdm_slots)
501 tdm_slots = pcm3168a->tdm_slots; 485 tdm_slots = io_params->tdm_slots;
502 else 486 else
503 tdm_slots = params_channels(params); 487 tdm_slots = params_channels(params);
504 488
@@ -534,7 +518,7 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
534 518
535 regmap_update_bits(pcm3168a->regmap, reg, mask, val); 519 regmap_update_bits(pcm3168a->regmap, reg, mask, val);
536 520
537 if (tx) { 521 if (dai->id == PCM3168A_DAI_DAC) {
538 mask = PCM3168A_DAC_FMT_MASK; 522 mask = PCM3168A_DAC_FMT_MASK;
539 shift = PCM3168A_DAC_FMT_SHIFT; 523 shift = PCM3168A_DAC_FMT_SHIFT;
540 } else { 524 } else {
@@ -552,20 +536,13 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream,
552{ 536{
553 struct snd_soc_component *component = dai->component; 537 struct snd_soc_component *component = dai->component;
554 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component); 538 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
555 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
556 unsigned int fmt;
557 unsigned int sample_min; 539 unsigned int sample_min;
558 unsigned int channel_max; 540 unsigned int channel_max;
559 unsigned int channel_maxs[] = { 541 unsigned int channel_maxs[] = {
560 6, /* rx */ 542 8, /* DAC */
561 8 /* tx */ 543 6 /* ADC */
562 }; 544 };
563 545
564 if (tx)
565 fmt = pcm3168a->dac_fmt;
566 else
567 fmt = pcm3168a->adc_fmt;
568
569 /* 546 /*
570 * Available Data Bits 547 * Available Data Bits
571 * 548 *
@@ -578,7 +555,7 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream,
578 * I2S 555 * I2S
579 * LEFT_J 556 * LEFT_J
580 */ 557 */
581 switch (fmt) { 558 switch (pcm3168a->io_params[dai->id].fmt) {
582 case PCM3168A_FMT_RIGHT_J: 559 case PCM3168A_FMT_RIGHT_J:
583 sample_min = 16; 560 sample_min = 16;
584 channel_max = 2; 561 channel_max = 2;
@@ -588,7 +565,7 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream,
588 case PCM3168A_FMT_DSP_A: 565 case PCM3168A_FMT_DSP_A:
589 case PCM3168A_FMT_DSP_B: 566 case PCM3168A_FMT_DSP_B:
590 sample_min = 24; 567 sample_min = 24;
591 channel_max = channel_maxs[tx]; 568 channel_max = channel_maxs[dai->id];
592 break; 569 break;
593 default: 570 default:
594 sample_min = 24; 571 sample_min = 24;
@@ -599,32 +576,29 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream,
599 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 576 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
600 sample_min, 32); 577 sample_min, 32);
601 578
579 /* Allow all channels in multi DIN/DOUT mode */
580 if (pcm3168a->io_params[dai->id].tdm_slots == 2)
581 channel_max = channel_maxs[dai->id];
582
602 snd_pcm_hw_constraint_minmax(substream->runtime, 583 snd_pcm_hw_constraint_minmax(substream->runtime,
603 SNDRV_PCM_HW_PARAM_CHANNELS, 584 SNDRV_PCM_HW_PARAM_CHANNELS,
604 2, channel_max); 585 2, channel_max);
605 586
606 return 0; 587 return 0;
607} 588}
608static const struct snd_soc_dai_ops pcm3168a_dac_dai_ops = { 589static const struct snd_soc_dai_ops pcm3168a_dai_ops = {
609 .startup = pcm3168a_startup, 590 .startup = pcm3168a_startup,
610 .set_fmt = pcm3168a_set_dai_fmt_dac, 591 .set_fmt = pcm3168a_set_dai_fmt,
611 .set_sysclk = pcm3168a_set_dai_sysclk, 592 .set_sysclk = pcm3168a_set_dai_sysclk,
612 .hw_params = pcm3168a_hw_params, 593 .hw_params = pcm3168a_hw_params,
613 .digital_mute = pcm3168a_digital_mute, 594 .digital_mute = pcm3168a_digital_mute,
614 .set_tdm_slot = pcm3168a_set_tdm_slot, 595 .set_tdm_slot = pcm3168a_set_tdm_slot,
615}; 596};
616 597
617static const struct snd_soc_dai_ops pcm3168a_adc_dai_ops = {
618 .startup = pcm3168a_startup,
619 .set_fmt = pcm3168a_set_dai_fmt_adc,
620 .set_sysclk = pcm3168a_set_dai_sysclk,
621 .hw_params = pcm3168a_hw_params,
622 .set_tdm_slot = pcm3168a_set_tdm_slot,
623};
624
625static struct snd_soc_dai_driver pcm3168a_dais[] = { 598static struct snd_soc_dai_driver pcm3168a_dais[] = {
626 { 599 {
627 .name = "pcm3168a-dac", 600 .name = "pcm3168a-dac",
601 .id = PCM3168A_DAI_DAC,
628 .playback = { 602 .playback = {
629 .stream_name = "Playback", 603 .stream_name = "Playback",
630 .channels_min = 1, 604 .channels_min = 1,
@@ -632,10 +606,11 @@ static struct snd_soc_dai_driver pcm3168a_dais[] = {
632 .rates = SNDRV_PCM_RATE_8000_192000, 606 .rates = SNDRV_PCM_RATE_8000_192000,
633 .formats = PCM3168A_FORMATS 607 .formats = PCM3168A_FORMATS
634 }, 608 },
635 .ops = &pcm3168a_dac_dai_ops 609 .ops = &pcm3168a_dai_ops
636 }, 610 },
637 { 611 {
638 .name = "pcm3168a-adc", 612 .name = "pcm3168a-adc",
613 .id = PCM3168A_DAI_ADC,
639 .capture = { 614 .capture = {
640 .stream_name = "Capture", 615 .stream_name = "Capture",
641 .channels_min = 1, 616 .channels_min = 1,
@@ -643,7 +618,7 @@ static struct snd_soc_dai_driver pcm3168a_dais[] = {
643 .rates = SNDRV_PCM_RATE_8000_96000, 618 .rates = SNDRV_PCM_RATE_8000_96000,
644 .formats = PCM3168A_FORMATS 619 .formats = PCM3168A_FORMATS
645 }, 620 },
646 .ops = &pcm3168a_adc_dai_ops 621 .ops = &pcm3168a_dai_ops
647 }, 622 },
648}; 623};
649 624
diff --git a/sound/soc/codecs/rk3328_codec.c b/sound/soc/codecs/rk3328_codec.c
index 24f8f86d58e9..287c962ba00d 100644
--- a/sound/soc/codecs/rk3328_codec.c
+++ b/sound/soc/codecs/rk3328_codec.c
@@ -432,7 +432,6 @@ static int rk3328_platform_probe(struct platform_device *pdev)
432{ 432{
433 struct device_node *rk3328_np = pdev->dev.of_node; 433 struct device_node *rk3328_np = pdev->dev.of_node;
434 struct rk3328_codec_priv *rk3328; 434 struct rk3328_codec_priv *rk3328;
435 struct resource *res;
436 struct regmap *grf; 435 struct regmap *grf;
437 void __iomem *base; 436 void __iomem *base;
438 int ret = 0; 437 int ret = 0;
@@ -482,8 +481,7 @@ static int rk3328_platform_probe(struct platform_device *pdev)
482 return ret; 481 return ret;
483 } 482 }
484 483
485 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 484 base = devm_platform_ioremap_resource(pdev, 0);
486 base = devm_ioremap_resource(&pdev->dev, res);
487 if (IS_ERR(base)) 485 if (IS_ERR(base))
488 return PTR_ERR(base); 486 return PTR_ERR(base);
489 487
diff --git a/sound/soc/codecs/rt1011.c b/sound/soc/codecs/rt1011.c
index ed28250d5e34..be1e276e3631 100644
--- a/sound/soc/codecs/rt1011.c
+++ b/sound/soc/codecs/rt1011.c
@@ -978,9 +978,6 @@ static bool rt1011_readable_register(struct device *dev, unsigned int reg)
978 } 978 }
979} 979}
980 980
981static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -9435, 37, 0);
982static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1739, 37, 0);
983
984static const char * const rt1011_din_source_select[] = { 981static const char * const rt1011_din_source_select[] = {
985 "Left", 982 "Left",
986 "Right", 983 "Right",
@@ -1029,6 +1026,8 @@ static const char * const rt1011_tdm_adc_swap_select[] = {
1029 1026
1030static SOC_ENUM_SINGLE_DECL(rt1011_tdm_adc1_1_enum, RT1011_TDM1_SET_3, 6, 1027static SOC_ENUM_SINGLE_DECL(rt1011_tdm_adc1_1_enum, RT1011_TDM1_SET_3, 6,
1031 rt1011_tdm_adc_swap_select); 1028 rt1011_tdm_adc_swap_select);
1029static SOC_ENUM_SINGLE_DECL(rt1011_tdm_adc2_1_enum, RT1011_TDM1_SET_3, 4,
1030 rt1011_tdm_adc_swap_select);
1032 1031
1033static void rt1011_reset(struct regmap *regmap) 1032static void rt1011_reset(struct regmap *regmap)
1034{ 1033{
@@ -1223,7 +1222,10 @@ static int rt1011_bq_drc_info(struct snd_kcontrol *kcontrol,
1223static int rt1011_r0_cali_get(struct snd_kcontrol *kcontrol, 1222static int rt1011_r0_cali_get(struct snd_kcontrol *kcontrol,
1224 struct snd_ctl_elem_value *ucontrol) 1223 struct snd_ctl_elem_value *ucontrol)
1225{ 1224{
1226 ucontrol->value.integer.value[0] = 0; 1225 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1226 struct rt1011_priv *rt1011 = snd_soc_component_get_drvdata(component);
1227
1228 ucontrol->value.integer.value[0] = rt1011->cali_done;
1227 1229
1228 return 0; 1230 return 0;
1229} 1231}
@@ -1237,6 +1239,7 @@ static int rt1011_r0_cali_put(struct snd_kcontrol *kcontrol,
1237 if (!component->card->instantiated) 1239 if (!component->card->instantiated)
1238 return 0; 1240 return 0;
1239 1241
1242 rt1011->cali_done = 0;
1240 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF && 1243 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF &&
1241 ucontrol->value.integer.value[0]) 1244 ucontrol->value.integer.value[0])
1242 rt1011_calibrate(rt1011, 1); 1245 rt1011_calibrate(rt1011, 1);
@@ -1333,7 +1336,8 @@ static const struct snd_kcontrol_new rt1011_snd_controls[] = {
1333 /* TDM1 Data Out Selection */ 1336 /* TDM1 Data Out Selection */
1334 SOC_ENUM("TDM1 DOUT Source", rt1011_tdm1_adc1_dat_enum), 1337 SOC_ENUM("TDM1 DOUT Source", rt1011_tdm1_adc1_dat_enum),
1335 SOC_ENUM("TDM1 DOUT Location", rt1011_tdm1_adc1_loc_enum), 1338 SOC_ENUM("TDM1 DOUT Location", rt1011_tdm1_adc1_loc_enum),
1336 SOC_ENUM("TDM1 ADCDAT Swap Select", rt1011_tdm_adc1_1_enum), 1339 SOC_ENUM("TDM1 ADC1DAT Swap Select", rt1011_tdm_adc1_1_enum),
1340 SOC_ENUM("TDM1 ADC2DAT Swap Select", rt1011_tdm_adc2_1_enum),
1337 1341
1338 /* Data Out Mode */ 1342 /* Data Out Mode */
1339 SOC_ENUM("I2S ADC DOUT Mode", rt1011_adc_dout_mode_enum), 1343 SOC_ENUM("I2S ADC DOUT Mode", rt1011_adc_dout_mode_enum),
@@ -1355,6 +1359,10 @@ static const struct snd_kcontrol_new rt1011_snd_controls[] = {
1355 SOC_SINGLE_EXT("R0 Calibration", SND_SOC_NOPM, 0, 1, 0, 1359 SOC_SINGLE_EXT("R0 Calibration", SND_SOC_NOPM, 0, 1, 0,
1356 rt1011_r0_cali_get, rt1011_r0_cali_put), 1360 rt1011_r0_cali_get, rt1011_r0_cali_put),
1357 RT1011_R0_LOAD("R0 Load Mode"), 1361 RT1011_R0_LOAD("R0 Load Mode"),
1362
1363 /* R0 temperature */
1364 SOC_SINGLE("R0 Temperature", RT1011_STP_INITIAL_RESISTANCE_TEMP,
1365 2, 255, 0),
1358}; 1366};
1359 1367
1360static int rt1011_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, 1368static int rt1011_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
@@ -1511,7 +1519,8 @@ static const struct snd_soc_dapm_route rt1011_dapm_routes[] = {
1511 1519
1512static int rt1011_get_clk_info(int sclk, int rate) 1520static int rt1011_get_clk_info(int sclk, int rate)
1513{ 1521{
1514 int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; 1522 int i;
1523 static const int pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
1515 1524
1516 if (sclk <= 0 || rate <= 0) 1525 if (sclk <= 0 || rate <= 0)
1517 return -EINVAL; 1526 return -EINVAL;
@@ -2139,6 +2148,7 @@ static int rt1011_calibrate(struct rt1011_priv *rt1011, unsigned char cali_flag)
2139 r0_factor = ((format / r0[0] * 100) / 128) 2148 r0_factor = ((format / r0[0] * 100) / 128)
2140 - (r0_integer * 100); 2149 - (r0_integer * 100);
2141 rt1011->r0_reg = r0[0]; 2150 rt1011->r0_reg = r0[0];
2151 rt1011->cali_done = 1;
2142 dev_info(dev, "r0 resistance about %d.%02d ohm, reg=0x%X\n", 2152 dev_info(dev, "r0 resistance about %d.%02d ohm, reg=0x%X\n",
2143 r0_integer, r0_factor, r0[0]); 2153 r0_integer, r0_factor, r0[0]);
2144 } 2154 }
@@ -2189,6 +2199,13 @@ static void rt1011_calibration_work(struct work_struct *work)
2189 2199
2190 rt1011_calibrate(rt1011, 1); 2200 rt1011_calibrate(rt1011, 1);
2191 2201
2202 /*
2203 * This flag should reset after booting.
2204 * The factory test will do calibration again and use this flag to check
2205 * whether the calibration completed
2206 */
2207 rt1011->cali_done = 0;
2208
2192 /* initial */ 2209 /* initial */
2193 rt1011_reg_init(component); 2210 rt1011_reg_init(component);
2194} 2211}
diff --git a/sound/soc/codecs/rt1011.h b/sound/soc/codecs/rt1011.h
index 98a38800c4df..2d65983f3d0f 100644
--- a/sound/soc/codecs/rt1011.h
+++ b/sound/soc/codecs/rt1011.h
@@ -227,6 +227,7 @@
227#define RT1011_STP_CALIB_RS_TEMP 0x152a 227#define RT1011_STP_CALIB_RS_TEMP 0x152a
228#define RT1011_INIT_RECIPROCAL_REG_24_16 0x1538 228#define RT1011_INIT_RECIPROCAL_REG_24_16 0x1538
229#define RT1011_INIT_RECIPROCAL_REG_15_0 0x1539 229#define RT1011_INIT_RECIPROCAL_REG_15_0 0x1539
230#define RT1011_STP_INITIAL_RESISTANCE_TEMP 0x153c
230#define RT1011_STP_ALPHA_RECIPROCAL_MSB 0x153e 231#define RT1011_STP_ALPHA_RECIPROCAL_MSB 0x153e
231#define RT1011_SPK_RESISTANCE_1 0x1544 232#define RT1011_SPK_RESISTANCE_1 0x1544
232#define RT1011_SPK_RESISTANCE_2 0x1546 233#define RT1011_SPK_RESISTANCE_2 0x1546
@@ -665,7 +666,7 @@ struct rt1011_priv {
665 int pll_out; 666 int pll_out;
666 667
667 int bq_drc_set; 668 int bq_drc_set;
668 unsigned int r0_reg; 669 unsigned int r0_reg, cali_done;
669 int recv_spk_mode; 670 int recv_spk_mode;
670}; 671};
671 672
diff --git a/sound/soc/codecs/rt1305.c b/sound/soc/codecs/rt1305.c
index 9909369483f0..e27742abfa76 100644
--- a/sound/soc/codecs/rt1305.c
+++ b/sound/soc/codecs/rt1305.c
@@ -608,7 +608,8 @@ static const struct snd_soc_dapm_route rt1305_dapm_routes[] = {
608 608
609static int rt1305_get_clk_info(int sclk, int rate) 609static int rt1305_get_clk_info(int sclk, int rate)
610{ 610{
611 int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; 611 int i;
612 static const int pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
612 613
613 if (sclk <= 0 || rate <= 0) 614 if (sclk <= 0 || rate <= 0)
614 return -EINVAL; 615 return -EINVAL;
diff --git a/sound/soc/codecs/rt1308.c b/sound/soc/codecs/rt1308.c
index d673506c7c39..b75931a69a1c 100644
--- a/sound/soc/codecs/rt1308.c
+++ b/sound/soc/codecs/rt1308.c
@@ -1,13 +1,10 @@
1/* 1// SPDX-License-Identifier: GPL-2.0
2 * rt1308.c -- RT1308 ALSA SoC amplifier component driver 2//
3 * 3// rt1308.c -- RT1308 ALSA SoC amplifier component driver
4 * Copyright 2019 Realtek Semiconductor Corp. 4//
5 * Author: Derek Fang <derek.fang@realtek.com> 5// Copyright 2019 Realtek Semiconductor Corp.
6 * 6// Author: Derek Fang <derek.fang@realtek.com>
7 * This program is free software; you can redistribute it and/or modify 7//
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11 8
12#include <linux/module.h> 9#include <linux/module.h>
13#include <linux/moduleparam.h> 10#include <linux/moduleparam.h>
@@ -40,10 +37,10 @@ static const struct reg_sequence init_list[] = {
40 { RT1308_VREF, 0x18100000 }, 37 { RT1308_VREF, 0x18100000 },
41 { RT1308_IV_SENSE, 0x87010000 }, 38 { RT1308_IV_SENSE, 0x87010000 },
42 { RT1308_DUMMY_REG, 0x00000200 }, 39 { RT1308_DUMMY_REG, 0x00000200 },
43 { RT1308_SIL_DET, 0x61c30000 }, 40 { RT1308_SIL_DET, 0xe1c30000 },
44 { RT1308_DC_CAL_2, 0x00ffff00 }, 41 { RT1308_DC_CAL_2, 0x00ffff00 },
45 { RT1308_CLK_DET, 0x01000000 }, 42 { RT1308_CLK_DET, 0x01000000 },
46 { RT1308_POWER_STATUS, 0x00800000 }, 43 { RT1308_POWER_STATUS, 0x08800000 },
47 { RT1308_DAC_SET, 0xafaf0700 }, 44 { RT1308_DAC_SET, 0xafaf0700 },
48 45
49}; 46};
@@ -308,12 +305,13 @@ static int rt1308_classd_event(struct snd_soc_dapm_widget *w,
308 case SND_SOC_DAPM_POST_PMU: 305 case SND_SOC_DAPM_POST_PMU:
309 msleep(30); 306 msleep(30);
310 snd_soc_component_update_bits(component, RT1308_POWER_STATUS, 307 snd_soc_component_update_bits(component, RT1308_POWER_STATUS,
311 RT1308_POW_PDB_REG_BIT, RT1308_POW_PDB_REG_BIT); 308 RT1308_POW_PDB_REG_BIT | RT1308_POW_PDB_MN_BIT,
309 RT1308_POW_PDB_REG_BIT | RT1308_POW_PDB_MN_BIT);
312 msleep(40); 310 msleep(40);
313 break; 311 break;
314 case SND_SOC_DAPM_PRE_PMD: 312 case SND_SOC_DAPM_PRE_PMD:
315 snd_soc_component_update_bits(component, RT1308_POWER_STATUS, 313 snd_soc_component_update_bits(component, RT1308_POWER_STATUS,
316 RT1308_POW_PDB_REG_BIT, 0); 314 RT1308_POW_PDB_REG_BIT | RT1308_POW_PDB_MN_BIT, 0);
317 usleep_range(150000, 200000); 315 usleep_range(150000, 200000);
318 break; 316 break;
319 317
@@ -438,7 +436,8 @@ static const struct snd_soc_dapm_route rt1308_dapm_routes[] = {
438 436
439static int rt1308_get_clk_info(int sclk, int rate) 437static int rt1308_get_clk_info(int sclk, int rate)
440{ 438{
441 int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; 439 int i;
440 static const int pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
442 441
443 if (sclk <= 0 || rate <= 0) 442 if (sclk <= 0 || rate <= 0)
444 return -EINVAL; 443 return -EINVAL;
@@ -808,33 +807,11 @@ static void rt1308_efuse(struct rt1308_priv *rt1308)
808{ 807{
809 regmap_write(rt1308->regmap, RT1308_RESET, 0); 808 regmap_write(rt1308->regmap, RT1308_RESET, 0);
810 809
811 regmap_write(rt1308->regmap, RT1308_POWER, 0xff371600);
812 regmap_write(rt1308->regmap, RT1308_CLK_1, 0x52100000);
813 regmap_write(rt1308->regmap, RT1308_I2C_I2S_SDW_SET, 0x01014005);
814 regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x227f5501);
815 regmap_write(rt1308->regmap, RT1308_PADS_1, 0x50150505);
816 regmap_write(rt1308->regmap, RT1308_VREF, 0x18100000);
817 regmap_write(rt1308->regmap, RT1308_IV_SENSE, 0x87010000);
818 regmap_write(rt1308->regmap, RT1308_DUMMY_REG, 0x00000200);
819 regmap_write(rt1308->regmap, RT1308_SIL_DET, 0x61c30000);
820 regmap_write(rt1308->regmap, RT1308_CLK_DET, 0x03700000);
821 regmap_write(rt1308->regmap, RT1308_SINE_TONE_GEN_1, 0x50022f00);
822 regmap_write(rt1308->regmap, RT1308_POWER_STATUS, 0x01800000); 810 regmap_write(rt1308->regmap, RT1308_POWER_STATUS, 0x01800000);
823 regmap_write(rt1308->regmap, RT1308_DC_CAL_2, 0x00ffff00);
824 regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x607e5501);
825
826 regmap_write(rt1308->regmap, RT1308_CLK_2, 0x0060e000);
827 regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x04fe0f00);
828 msleep(100); 811 msleep(100);
829 regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x44fe0f00); 812 regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x44fe0f00);
830 msleep(20); 813 msleep(20);
831 regmap_write(rt1308->regmap, RT1308_PVDD_OFFSET_CTL, 0x10000000); 814 regmap_write(rt1308->regmap, RT1308_PVDD_OFFSET_CTL, 0x10000000);
832
833 regmap_write(rt1308->regmap, RT1308_POWER_STATUS, 0x00800000);
834 regmap_write(rt1308->regmap, RT1308_POWER, 0x0);
835 regmap_write(rt1308->regmap, RT1308_CLK_1, 0x52000000);
836 regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x227f5501);
837 regmap_write(rt1308->regmap, RT1308_SINE_TONE_GEN_1, 0x10022f00);
838} 815}
839 816
840static int rt1308_i2c_probe(struct i2c_client *i2c, 817static int rt1308_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/rt1308.h b/sound/soc/codecs/rt1308.h
index c330aae1d527..ff7c423e879e 100644
--- a/sound/soc/codecs/rt1308.h
+++ b/sound/soc/codecs/rt1308.h
@@ -1,12 +1,10 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * RT1308.h -- RT1308 ALSA SoC amplifier component driver 3 * rt1308.h -- RT1308 ALSA SoC amplifier component driver
3 * 4 *
4 * Copyright 2019 Realtek Semiconductor Corp. 5 * Copyright 2019 Realtek Semiconductor Corp.
5 * Author: Derek Fang <derek.fang@realtek.com> 6 * Author: Derek Fang <derek.fang@realtek.com>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */ 8 */
11 9
12#ifndef _RT1308_H_ 10#ifndef _RT1308_H_
diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c
index c050d84a6916..68299ce26d3e 100644
--- a/sound/soc/codecs/rt5665.c
+++ b/sound/soc/codecs/rt5665.c
@@ -2566,7 +2566,7 @@ static int set_dmic_power(struct snd_soc_dapm_widget *w,
2566 return 0; 2566 return 0;
2567} 2567}
2568 2568
2569static int rt5655_set_verf(struct snd_soc_dapm_widget *w, 2569static int rt5665_set_verf(struct snd_soc_dapm_widget *w,
2570 struct snd_kcontrol *kcontrol, int event) 2570 struct snd_kcontrol *kcontrol, int event)
2571{ 2571{
2572 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 2572 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
@@ -2686,11 +2686,11 @@ static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = {
2686 SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5665_PWR_VOL, 2686 SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5665_PWR_VOL,
2687 RT5665_PWR_MIC_DET_BIT, 0, NULL, 0), 2687 RT5665_PWR_MIC_DET_BIT, 0, NULL, 0),
2688 SND_SOC_DAPM_SUPPLY("Vref1", RT5665_PWR_ANLG_1, RT5665_PWR_VREF1_BIT, 0, 2688 SND_SOC_DAPM_SUPPLY("Vref1", RT5665_PWR_ANLG_1, RT5665_PWR_VREF1_BIT, 0,
2689 rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 2689 rt5665_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2690 SND_SOC_DAPM_SUPPLY("Vref2", RT5665_PWR_ANLG_1, RT5665_PWR_VREF2_BIT, 0, 2690 SND_SOC_DAPM_SUPPLY("Vref2", RT5665_PWR_ANLG_1, RT5665_PWR_VREF2_BIT, 0,
2691 rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 2691 rt5665_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2692 SND_SOC_DAPM_SUPPLY("Vref3", RT5665_PWR_ANLG_1, RT5665_PWR_VREF3_BIT, 0, 2692 SND_SOC_DAPM_SUPPLY("Vref3", RT5665_PWR_ANLG_1, RT5665_PWR_VREF3_BIT, 0,
2693 rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 2693 rt5665_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2694 2694
2695 /* ASRC */ 2695 /* ASRC */
2696 SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5665_ASRC_1, 2696 SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5665_ASRC_1,
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index c779dc3474f9..315a3d39bc09 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -691,10 +691,12 @@ static void rt5677_set_dsp_mode(struct snd_soc_component *component, bool on)
691 struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); 691 struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
692 692
693 if (on) { 693 if (on) {
694 regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x2, 0x2); 694 regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1,
695 RT5677_PWR_DSP, RT5677_PWR_DSP);
695 rt5677->is_dsp_mode = true; 696 rt5677->is_dsp_mode = true;
696 } else { 697 } else {
697 regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x2, 0x0); 698 regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1,
699 RT5677_PWR_DSP, 0x0);
698 rt5677->is_dsp_mode = false; 700 rt5677->is_dsp_mode = false;
699 } 701 }
700} 702}
@@ -4466,7 +4468,8 @@ static int rt5677_set_bias_level(struct snd_soc_component *component,
4466 4468
4467 regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, 4469 regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1,
4468 RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK, 4470 RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK,
4469 0x0055); 4471 5 << RT5677_LDO1_SEL_SFT |
4472 5 << RT5677_LDO2_SEL_SFT);
4470 regmap_update_bits(rt5677->regmap, 4473 regmap_update_bits(rt5677->regmap,
4471 RT5677_PR_BASE + RT5677_BIAS_CUR4, 4474 RT5677_PR_BASE + RT5677_BIAS_CUR4,
4472 0x0f00, 0x0f00); 4475 0x0f00, 0x0f00);
@@ -4490,9 +4493,11 @@ static int rt5677_set_bias_level(struct snd_soc_component *component,
4490 case SND_SOC_BIAS_OFF: 4493 case SND_SOC_BIAS_OFF:
4491 regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x0); 4494 regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x0);
4492 regmap_write(rt5677->regmap, RT5677_PWR_DIG1, 0x0000); 4495 regmap_write(rt5677->regmap, RT5677_PWR_DIG1, 0x0000);
4493 regmap_write(rt5677->regmap, RT5677_PWR_DIG2, 0x0000); 4496 regmap_write(rt5677->regmap, RT5677_PWR_ANLG1,
4494 regmap_write(rt5677->regmap, RT5677_PWR_ANLG1, 0x0022); 4497 2 << RT5677_LDO1_SEL_SFT |
4495 regmap_write(rt5677->regmap, RT5677_PWR_ANLG2, 0x0000); 4498 2 << RT5677_LDO2_SEL_SFT);
4499 regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2,
4500 RT5677_PWR_CORE, 0);
4496 regmap_update_bits(rt5677->regmap, 4501 regmap_update_bits(rt5677->regmap,
4497 RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000); 4502 RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000);
4498 4503
@@ -4719,7 +4724,8 @@ static int rt5677_probe(struct snd_soc_component *component)
4719 4724
4720 regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 4725 regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC,
4721 ~RT5677_IRQ_DEBOUNCE_SEL_MASK, 0x0020); 4726 ~RT5677_IRQ_DEBOUNCE_SEL_MASK, 0x0020);
4722 regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x0c00); 4727 regmap_write(rt5677->regmap, RT5677_PWR_DSP2,
4728 RT5677_PWR_SLIM_ISO | RT5677_PWR_CORE_ISO);
4723 4729
4724 for (i = 0; i < RT5677_GPIO_NUM; i++) 4730 for (i = 0; i < RT5677_GPIO_NUM; i++)
4725 rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]); 4731 rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]);
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index a6a4748c97f9..aa1f9637d895 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -31,6 +31,13 @@
31#define SGTL5000_DAP_REG_OFFSET 0x0100 31#define SGTL5000_DAP_REG_OFFSET 0x0100
32#define SGTL5000_MAX_REG_OFFSET 0x013A 32#define SGTL5000_MAX_REG_OFFSET 0x013A
33 33
34/* Delay for the VAG ramp up */
35#define SGTL5000_VAG_POWERUP_DELAY 500 /* ms */
36/* Delay for the VAG ramp down */
37#define SGTL5000_VAG_POWERDOWN_DELAY 500 /* ms */
38
39#define SGTL5000_OUTPUTS_MUTE (SGTL5000_HP_MUTE | SGTL5000_LINE_OUT_MUTE)
40
34/* default value of sgtl5000 registers */ 41/* default value of sgtl5000 registers */
35static const struct reg_default sgtl5000_reg_defaults[] = { 42static const struct reg_default sgtl5000_reg_defaults[] = {
36 { SGTL5000_CHIP_DIG_POWER, 0x0000 }, 43 { SGTL5000_CHIP_DIG_POWER, 0x0000 },
@@ -123,6 +130,13 @@ enum {
123 I2S_SCLK_STRENGTH_HIGH, 130 I2S_SCLK_STRENGTH_HIGH,
124}; 131};
125 132
133enum {
134 HP_POWER_EVENT,
135 DAC_POWER_EVENT,
136 ADC_POWER_EVENT,
137 LAST_POWER_EVENT = ADC_POWER_EVENT
138};
139
126/* sgtl5000 private structure in codec */ 140/* sgtl5000 private structure in codec */
127struct sgtl5000_priv { 141struct sgtl5000_priv {
128 int sysclk; /* sysclk rate */ 142 int sysclk; /* sysclk rate */
@@ -137,8 +151,109 @@ struct sgtl5000_priv {
137 u8 micbias_voltage; 151 u8 micbias_voltage;
138 u8 lrclk_strength; 152 u8 lrclk_strength;
139 u8 sclk_strength; 153 u8 sclk_strength;
154 u16 mute_state[LAST_POWER_EVENT + 1];
140}; 155};
141 156
157static inline int hp_sel_input(struct snd_soc_component *component)
158{
159 return (snd_soc_component_read32(component, SGTL5000_CHIP_ANA_CTRL) &
160 SGTL5000_HP_SEL_MASK) >> SGTL5000_HP_SEL_SHIFT;
161}
162
163static inline u16 mute_output(struct snd_soc_component *component,
164 u16 mute_mask)
165{
166 u16 mute_reg = snd_soc_component_read32(component,
167 SGTL5000_CHIP_ANA_CTRL);
168
169 snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL,
170 mute_mask, mute_mask);
171 return mute_reg;
172}
173
174static inline void restore_output(struct snd_soc_component *component,
175 u16 mute_mask, u16 mute_reg)
176{
177 snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL,
178 mute_mask, mute_reg);
179}
180
181static void vag_power_on(struct snd_soc_component *component, u32 source)
182{
183 if (snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER) &
184 SGTL5000_VAG_POWERUP)
185 return;
186
187 snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
188 SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
189
190 /* When VAG powering on to get local loop from Line-In, the sleep
191 * is required to avoid loud pop.
192 */
193 if (hp_sel_input(component) == SGTL5000_HP_SEL_LINE_IN &&
194 source == HP_POWER_EVENT)
195 msleep(SGTL5000_VAG_POWERUP_DELAY);
196}
197
198static int vag_power_consumers(struct snd_soc_component *component,
199 u16 ana_pwr_reg, u32 source)
200{
201 int consumers = 0;
202
203 /* count dac/adc consumers unconditional */
204 if (ana_pwr_reg & SGTL5000_DAC_POWERUP)
205 consumers++;
206 if (ana_pwr_reg & SGTL5000_ADC_POWERUP)
207 consumers++;
208
209 /*
210 * If the event comes from HP and Line-In is selected,
211 * current action is 'DAC to be powered down'.
212 * As HP_POWERUP is not set when HP muxed to line-in,
213 * we need to keep VAG power ON.
214 */
215 if (source == HP_POWER_EVENT) {
216 if (hp_sel_input(component) == SGTL5000_HP_SEL_LINE_IN)
217 consumers++;
218 } else {
219 if (ana_pwr_reg & SGTL5000_HP_POWERUP)
220 consumers++;
221 }
222
223 return consumers;
224}
225
226static void vag_power_off(struct snd_soc_component *component, u32 source)
227{
228 u16 ana_pwr = snd_soc_component_read32(component,
229 SGTL5000_CHIP_ANA_POWER);
230
231 if (!(ana_pwr & SGTL5000_VAG_POWERUP))
232 return;
233
234 /*
235 * This function calls when any of VAG power consumers is disappearing.
236 * Thus, if there is more than one consumer at the moment, as minimum
237 * one consumer will definitely stay after the end of the current
238 * event.
239 * Don't clear VAG_POWERUP if 2 or more consumers of VAG present:
240 * - LINE_IN (for HP events) / HP (for DAC/ADC events)
241 * - DAC
242 * - ADC
243 * (the current consumer is disappearing right now)
244 */
245 if (vag_power_consumers(component, ana_pwr, source) >= 2)
246 return;
247
248 snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
249 SGTL5000_VAG_POWERUP, 0);
250 /* In power down case, we need wait 400-1000 ms
251 * when VAG fully ramped down.
252 * As longer we wait, as smaller pop we've got.
253 */
254 msleep(SGTL5000_VAG_POWERDOWN_DELAY);
255}
256
142/* 257/*
143 * mic_bias power on/off share the same register bits with 258 * mic_bias power on/off share the same register bits with
144 * output impedance of mic bias, when power on mic bias, we 259 * output impedance of mic bias, when power on mic bias, we
@@ -170,36 +285,46 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w,
170 return 0; 285 return 0;
171} 286}
172 287
173/* 288static int vag_and_mute_control(struct snd_soc_component *component,
174 * As manual described, ADC/DAC only works when VAG powerup, 289 int event, int event_source)
175 * So enabled VAG before ADC/DAC up.
176 * In power down case, we need wait 400ms when vag fully ramped down.
177 */
178static int power_vag_event(struct snd_soc_dapm_widget *w,
179 struct snd_kcontrol *kcontrol, int event)
180{ 290{
181 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 291 static const u16 mute_mask[] = {
182 const u32 mask = SGTL5000_DAC_POWERUP | SGTL5000_ADC_POWERUP; 292 /*
293 * Mask for HP_POWER_EVENT.
294 * Muxing Headphones have to be wrapped with mute/unmute
295 * headphones only.
296 */
297 SGTL5000_HP_MUTE,
298 /*
299 * Masks for DAC_POWER_EVENT/ADC_POWER_EVENT.
300 * Muxing DAC or ADC block have to wrapped with mute/unmute
301 * both headphones and line-out.
302 */
303 SGTL5000_OUTPUTS_MUTE,
304 SGTL5000_OUTPUTS_MUTE
305 };
306
307 struct sgtl5000_priv *sgtl5000 =
308 snd_soc_component_get_drvdata(component);
183 309
184 switch (event) { 310 switch (event) {
311 case SND_SOC_DAPM_PRE_PMU:
312 sgtl5000->mute_state[event_source] =
313 mute_output(component, mute_mask[event_source]);
314 break;
185 case SND_SOC_DAPM_POST_PMU: 315 case SND_SOC_DAPM_POST_PMU:
186 snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER, 316 vag_power_on(component, event_source);
187 SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP); 317 restore_output(component, mute_mask[event_source],
188 msleep(400); 318 sgtl5000->mute_state[event_source]);
189 break; 319 break;
190
191 case SND_SOC_DAPM_PRE_PMD: 320 case SND_SOC_DAPM_PRE_PMD:
192 /* 321 sgtl5000->mute_state[event_source] =
193 * Don't clear VAG_POWERUP, when both DAC and ADC are 322 mute_output(component, mute_mask[event_source]);
194 * operational to prevent inadvertently starving the 323 vag_power_off(component, event_source);
195 * other one of them. 324 break;
196 */ 325 case SND_SOC_DAPM_POST_PMD:
197 if ((snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER) & 326 restore_output(component, mute_mask[event_source],
198 mask) != mask) { 327 sgtl5000->mute_state[event_source]);
199 snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
200 SGTL5000_VAG_POWERUP, 0);
201 msleep(400);
202 }
203 break; 328 break;
204 default: 329 default:
205 break; 330 break;
@@ -208,6 +333,41 @@ static int power_vag_event(struct snd_soc_dapm_widget *w,
208 return 0; 333 return 0;
209} 334}
210 335
336/*
337 * Mute Headphone when power it up/down.
338 * Control VAG power on HP power path.
339 */
340static int headphone_pga_event(struct snd_soc_dapm_widget *w,
341 struct snd_kcontrol *kcontrol, int event)
342{
343 struct snd_soc_component *component =
344 snd_soc_dapm_to_component(w->dapm);
345
346 return vag_and_mute_control(component, event, HP_POWER_EVENT);
347}
348
349/* As manual describes, ADC/DAC powering up/down requires
350 * to mute outputs to avoid pops.
351 * Control VAG power on ADC/DAC power path.
352 */
353static int adc_updown_depop(struct snd_soc_dapm_widget *w,
354 struct snd_kcontrol *kcontrol, int event)
355{
356 struct snd_soc_component *component =
357 snd_soc_dapm_to_component(w->dapm);
358
359 return vag_and_mute_control(component, event, ADC_POWER_EVENT);
360}
361
362static int dac_updown_depop(struct snd_soc_dapm_widget *w,
363 struct snd_kcontrol *kcontrol, int event)
364{
365 struct snd_soc_component *component =
366 snd_soc_dapm_to_component(w->dapm);
367
368 return vag_and_mute_control(component, event, DAC_POWER_EVENT);
369}
370
211/* input sources for ADC */ 371/* input sources for ADC */
212static const char *adc_mux_text[] = { 372static const char *adc_mux_text[] = {
213 "MIC_IN", "LINE_IN" 373 "MIC_IN", "LINE_IN"
@@ -280,7 +440,10 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
280 mic_bias_event, 440 mic_bias_event,
281 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 441 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
282 442
283 SND_SOC_DAPM_PGA("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0), 443 SND_SOC_DAPM_PGA_E("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0,
444 headphone_pga_event,
445 SND_SOC_DAPM_PRE_POST_PMU |
446 SND_SOC_DAPM_PRE_POST_PMD),
284 SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0), 447 SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0),
285 448
286 SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux), 449 SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux),
@@ -301,11 +464,12 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
301 0, SGTL5000_CHIP_DIG_POWER, 464 0, SGTL5000_CHIP_DIG_POWER,
302 1, 0), 465 1, 0),
303 466
304 SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0), 467 SND_SOC_DAPM_ADC_E("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0,
305 SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0), 468 adc_updown_depop, SND_SOC_DAPM_PRE_POST_PMU |
306 469 SND_SOC_DAPM_PRE_POST_PMD),
307 SND_SOC_DAPM_PRE("VAG_POWER_PRE", power_vag_event), 470 SND_SOC_DAPM_DAC_E("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0,
308 SND_SOC_DAPM_POST("VAG_POWER_POST", power_vag_event), 471 dac_updown_depop, SND_SOC_DAPM_PRE_POST_PMU |
472 SND_SOC_DAPM_PRE_POST_PMD),
309}; 473};
310 474
311/* routes for sgtl5000 */ 475/* routes for sgtl5000 */
@@ -556,6 +720,7 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
556 SGTL5000_CHIP_ANA_ADC_CTRL, 720 SGTL5000_CHIP_ANA_ADC_CTRL,
557 8, 1, 0, capture_6db_attenuate), 721 8, 1, 0, capture_6db_attenuate),
558 SOC_SINGLE("Capture ZC Switch", SGTL5000_CHIP_ANA_CTRL, 1, 1, 0), 722 SOC_SINGLE("Capture ZC Switch", SGTL5000_CHIP_ANA_CTRL, 1, 1, 0),
723 SOC_SINGLE("Capture Switch", SGTL5000_CHIP_ANA_CTRL, 0, 1, 1),
559 724
560 SOC_DOUBLE_TLV("Headphone Playback Volume", 725 SOC_DOUBLE_TLV("Headphone Playback Volume",
561 SGTL5000_CHIP_ANA_HP_CTRL, 726 SGTL5000_CHIP_ANA_HP_CTRL,
@@ -1173,12 +1338,17 @@ static int sgtl5000_set_power_regs(struct snd_soc_component *component)
1173 SGTL5000_INT_OSC_EN); 1338 SGTL5000_INT_OSC_EN);
1174 /* Enable VDDC charge pump */ 1339 /* Enable VDDC charge pump */
1175 ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP; 1340 ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP;
1176 } else if (vddio >= 3100 && vdda >= 3100) { 1341 } else {
1177 ana_pwr &= ~SGTL5000_VDDC_CHRGPMP_POWERUP; 1342 ana_pwr &= ~SGTL5000_VDDC_CHRGPMP_POWERUP;
1178 /* VDDC use VDDIO rail */ 1343 /*
1179 lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD; 1344 * if vddio == vdda the source of charge pump should be
1180 lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO << 1345 * assigned manually to VDDIO
1181 SGTL5000_VDDC_MAN_ASSN_SHIFT; 1346 */
1347 if (vddio == vdda) {
1348 lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
1349 lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO <<
1350 SGTL5000_VDDC_MAN_ASSN_SHIFT;
1351 }
1182 } 1352 }
1183 1353
1184 snd_soc_component_write(component, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl); 1354 snd_soc_component_write(component, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl);
@@ -1288,6 +1458,7 @@ static int sgtl5000_probe(struct snd_soc_component *component)
1288 int ret; 1458 int ret;
1289 u16 reg; 1459 u16 reg;
1290 struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component); 1460 struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
1461 unsigned int zcd_mask = SGTL5000_HP_ZCD_EN | SGTL5000_ADC_ZCD_EN;
1291 1462
1292 /* power up sgtl5000 */ 1463 /* power up sgtl5000 */
1293 ret = sgtl5000_set_power_regs(component); 1464 ret = sgtl5000_set_power_regs(component);
@@ -1296,7 +1467,7 @@ static int sgtl5000_probe(struct snd_soc_component *component)
1296 1467
1297 /* enable small pop, introduce 400ms delay in turning off */ 1468 /* enable small pop, introduce 400ms delay in turning off */
1298 snd_soc_component_update_bits(component, SGTL5000_CHIP_REF_CTRL, 1469 snd_soc_component_update_bits(component, SGTL5000_CHIP_REF_CTRL,
1299 SGTL5000_SMALL_POP, 1); 1470 SGTL5000_SMALL_POP, SGTL5000_SMALL_POP);
1300 1471
1301 /* disable short cut detector */ 1472 /* disable short cut detector */
1302 snd_soc_component_write(component, SGTL5000_CHIP_SHORT_CTRL, 0); 1473 snd_soc_component_write(component, SGTL5000_CHIP_SHORT_CTRL, 0);
@@ -1315,9 +1486,8 @@ static int sgtl5000_probe(struct snd_soc_component *component)
1315 0x1f); 1486 0x1f);
1316 snd_soc_component_write(component, SGTL5000_CHIP_PAD_STRENGTH, reg); 1487 snd_soc_component_write(component, SGTL5000_CHIP_PAD_STRENGTH, reg);
1317 1488
1318 snd_soc_component_write(component, SGTL5000_CHIP_ANA_CTRL, 1489 snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL,
1319 SGTL5000_HP_ZCD_EN | 1490 zcd_mask, zcd_mask);
1320 SGTL5000_ADC_ZCD_EN);
1321 1491
1322 snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL, 1492 snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL,
1323 SGTL5000_BIAS_R_MASK, 1493 SGTL5000_BIAS_R_MASK,
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
index 18cae08bbd3a..a4bf4bca95bf 100644
--- a/sound/soc/codecs/sgtl5000.h
+++ b/sound/soc/codecs/sgtl5000.h
@@ -273,7 +273,7 @@
273#define SGTL5000_BIAS_CTRL_MASK 0x000e 273#define SGTL5000_BIAS_CTRL_MASK 0x000e
274#define SGTL5000_BIAS_CTRL_SHIFT 1 274#define SGTL5000_BIAS_CTRL_SHIFT 1
275#define SGTL5000_BIAS_CTRL_WIDTH 3 275#define SGTL5000_BIAS_CTRL_WIDTH 3
276#define SGTL5000_SMALL_POP 1 276#define SGTL5000_SMALL_POP 0x0001
277 277
278/* 278/*
279 * SGTL5000_CHIP_MIC_CTRL 279 * SGTL5000_CHIP_MIC_CTRL
diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c
index 9009a7407b7a..a061d78473ac 100644
--- a/sound/soc/codecs/sirf-audio-codec.c
+++ b/sound/soc/codecs/sirf-audio-codec.c
@@ -459,7 +459,6 @@ static int sirf_audio_codec_driver_probe(struct platform_device *pdev)
459 int ret; 459 int ret;
460 struct sirf_audio_codec *sirf_audio_codec; 460 struct sirf_audio_codec *sirf_audio_codec;
461 void __iomem *base; 461 void __iomem *base;
462 struct resource *mem_res;
463 462
464 sirf_audio_codec = devm_kzalloc(&pdev->dev, 463 sirf_audio_codec = devm_kzalloc(&pdev->dev,
465 sizeof(struct sirf_audio_codec), GFP_KERNEL); 464 sizeof(struct sirf_audio_codec), GFP_KERNEL);
@@ -468,8 +467,7 @@ static int sirf_audio_codec_driver_probe(struct platform_device *pdev)
468 467
469 platform_set_drvdata(pdev, sirf_audio_codec); 468 platform_set_drvdata(pdev, sirf_audio_codec);
470 469
471 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 470 base = devm_platform_ioremap_resource(pdev, 0);
472 base = devm_ioremap_resource(&pdev->dev, mem_res);
473 if (IS_ERR(base)) 471 if (IS_ERR(base))
474 return PTR_ERR(base); 472 return PTR_ERR(base);
475 473
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 080a840c987a..f8e2f4b74db3 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -67,8 +67,6 @@ static SOC_ENUM_SINGLE_DECL(rec_src_enum,
67static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls = 67static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
68SOC_DAPM_ENUM("Input Select", rec_src_enum); 68SOC_DAPM_ENUM("Input Select", rec_src_enum);
69 69
70static SOC_ENUM_SINGLE_DECL(tlv320aic23_rec_src,
71 TLV320AIC23_ANLG, 2, rec_src_text);
72static SOC_ENUM_SINGLE_DECL(tlv320aic23_deemph, 70static SOC_ENUM_SINGLE_DECL(tlv320aic23_deemph,
73 TLV320AIC23_DIGT, 1, deemph_text); 71 TLV320AIC23_DIGT, 1, deemph_text);
74 72
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index 9b37e98da0db..df627a08def9 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -258,7 +258,6 @@ static SOC_ENUM_SINGLE_DECL(mic1rp_p_enum, AIC31XX_MICPGAPI, 4,
258static SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2, 258static SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2,
259 mic_select_text); 259 mic_select_text);
260 260
261static SOC_ENUM_SINGLE_DECL(cm_m_enum, AIC31XX_MICPGAMI, 6, mic_select_text);
262static SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4, 261static SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4,
263 mic_select_text); 262 mic_select_text);
264 263
@@ -1553,7 +1552,8 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
1553 aic31xx->gpio_reset = devm_gpiod_get_optional(aic31xx->dev, "reset", 1552 aic31xx->gpio_reset = devm_gpiod_get_optional(aic31xx->dev, "reset",
1554 GPIOD_OUT_LOW); 1553 GPIOD_OUT_LOW);
1555 if (IS_ERR(aic31xx->gpio_reset)) { 1554 if (IS_ERR(aic31xx->gpio_reset)) {
1556 dev_err(aic31xx->dev, "not able to acquire gpio\n"); 1555 if (PTR_ERR(aic31xx->gpio_reset) != -EPROBE_DEFER)
1556 dev_err(aic31xx->dev, "not able to acquire gpio\n");
1557 return PTR_ERR(aic31xx->gpio_reset); 1557 return PTR_ERR(aic31xx->gpio_reset);
1558 } 1558 }
1559 1559
@@ -1564,7 +1564,9 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
1564 ARRAY_SIZE(aic31xx->supplies), 1564 ARRAY_SIZE(aic31xx->supplies),
1565 aic31xx->supplies); 1565 aic31xx->supplies);
1566 if (ret) { 1566 if (ret) {
1567 dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret); 1567 if (ret != -EPROBE_DEFER)
1568 dev_err(aic31xx->dev,
1569 "Failed to request supplies: %d\n", ret);
1568 return ret; 1570 return ret;
1569 } 1571 }
1570 1572
diff --git a/sound/soc/codecs/tscs454.c b/sound/soc/codecs/tscs454.c
index 93d84e5ae2d5..c3587af9985c 100644
--- a/sound/soc/codecs/tscs454.c
+++ b/sound/soc/codecs/tscs454.c
@@ -22,7 +22,6 @@
22 22
23#include "tscs454.h" 23#include "tscs454.h"
24 24
25static const unsigned int PLL_48K_RATE = (48000 * 256);
26static const unsigned int PLL_44_1K_RATE = (44100 * 256); 25static const unsigned int PLL_44_1K_RATE = (44100 * 256);
27 26
28#define COEFF_SIZE 3 27#define COEFF_SIZE 3
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 472c2fff34a8..f34637afee51 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -1108,10 +1108,8 @@ static int twl6040_probe(struct snd_soc_component *component)
1108 priv->component = component; 1108 priv->component = component;
1109 1109
1110 priv->plug_irq = platform_get_irq(pdev, 0); 1110 priv->plug_irq = platform_get_irq(pdev, 0);
1111 if (priv->plug_irq < 0) { 1111 if (priv->plug_irq < 0)
1112 dev_err(component->dev, "invalid irq: %d\n", priv->plug_irq);
1113 return priv->plug_irq; 1112 return priv->plug_irq;
1114 }
1115 1113
1116 INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); 1114 INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work);
1117 1115
diff --git a/sound/soc/codecs/uda1334.c b/sound/soc/codecs/uda1334.c
new file mode 100644
index 000000000000..21ab8c5487ba
--- /dev/null
+++ b/sound/soc/codecs/uda1334.c
@@ -0,0 +1,295 @@
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// uda1334.c -- UDA1334 ALSA SoC Audio driver
4//
5// Based on WM8523 ALSA SoC Audio driver written by Mark Brown
6
7#include <linux/module.h>
8#include <linux/moduleparam.h>
9#include <linux/init.h>
10#include <linux/delay.h>
11#include <linux/slab.h>
12#include <linux/gpio/consumer.h>
13#include <linux/of_device.h>
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/pcm_params.h>
17#include <sound/soc.h>
18#include <sound/initval.h>
19
20#define UDA1334_NUM_RATES 6
21
22/* codec private data */
23struct uda1334_priv {
24 struct gpio_desc *mute;
25 struct gpio_desc *deemph;
26 unsigned int sysclk;
27 unsigned int rate_constraint_list[UDA1334_NUM_RATES];
28 struct snd_pcm_hw_constraint_list rate_constraint;
29};
30
31static const struct snd_soc_dapm_widget uda1334_dapm_widgets[] = {
32SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
33SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
34SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
35};
36
37static const struct snd_soc_dapm_route uda1334_dapm_routes[] = {
38 { "LINEVOUTL", NULL, "DAC" },
39 { "LINEVOUTR", NULL, "DAC" },
40};
41
42static int uda1334_put_deemph(struct snd_kcontrol *kcontrol,
43 struct snd_ctl_elem_value *ucontrol)
44{
45 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
46 struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
47 int deemph = ucontrol->value.integer.value[0];
48
49 if (deemph > 1)
50 return -EINVAL;
51
52 gpiod_set_value_cansleep(uda1334->deemph, deemph);
53
54 return 0;
55};
56
57static int uda1334_get_deemph(struct snd_kcontrol *kcontrol,
58 struct snd_ctl_elem_value *ucontrol)
59{
60 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
61 struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
62 int ret;
63
64 ret = gpiod_get_value_cansleep(uda1334->deemph);
65 if (ret < 0)
66 return -EINVAL;
67
68 ucontrol->value.integer.value[0] = ret;
69
70 return 0;
71};
72
73static const struct snd_kcontrol_new uda1334_snd_controls[] = {
74 SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
75 uda1334_get_deemph, uda1334_put_deemph),
76};
77
78static const struct {
79 int value;
80 int ratio;
81} lrclk_ratios[UDA1334_NUM_RATES] = {
82 { 1, 128 },
83 { 2, 192 },
84 { 3, 256 },
85 { 4, 384 },
86 { 5, 512 },
87 { 6, 768 },
88};
89
90static int uda1334_startup(struct snd_pcm_substream *substream,
91 struct snd_soc_dai *dai)
92{
93 struct snd_soc_component *component = dai->component;
94 struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
95
96 /*
97 * The set of sample rates that can be supported depends on the
98 * MCLK supplied to the CODEC - enforce this.
99 */
100 if (!uda1334->sysclk) {
101 dev_err(component->dev,
102 "No MCLK configured, call set_sysclk() on init\n");
103 return -EINVAL;
104 }
105
106 snd_pcm_hw_constraint_list(substream->runtime, 0,
107 SNDRV_PCM_HW_PARAM_RATE,
108 &uda1334->rate_constraint);
109
110 gpiod_set_value_cansleep(uda1334->mute, 1);
111
112 return 0;
113}
114
115static void uda1334_shutdown(struct snd_pcm_substream *substream,
116 struct snd_soc_dai *dai)
117{
118 struct snd_soc_component *component = dai->component;
119 struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
120
121 gpiod_set_value_cansleep(uda1334->mute, 0);
122}
123
124static int uda1334_set_dai_sysclk(struct snd_soc_dai *codec_dai,
125 int clk_id, unsigned int freq, int dir)
126{
127 struct snd_soc_component *component = codec_dai->component;
128 struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
129 unsigned int val;
130 int i, j = 0;
131
132 uda1334->sysclk = freq;
133
134 uda1334->rate_constraint.count = 0;
135 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
136 val = freq / lrclk_ratios[i].ratio;
137 /*
138 * Check that it's a standard rate since core can't
139 * cope with others and having the odd rates confuses
140 * constraint matching.
141 */
142
143 switch (val) {
144 case 8000:
145 case 32000:
146 case 44100:
147 case 48000:
148 case 64000:
149 case 88200:
150 case 96000:
151 dev_dbg(component->dev, "Supported sample rate: %dHz\n",
152 val);
153 uda1334->rate_constraint_list[j++] = val;
154 uda1334->rate_constraint.count++;
155 break;
156 default:
157 dev_dbg(component->dev, "Skipping sample rate: %dHz\n",
158 val);
159 }
160 }
161
162 /* Need at least one supported rate... */
163 if (uda1334->rate_constraint.count == 0)
164 return -EINVAL;
165
166 return 0;
167}
168
169static int uda1334_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
170{
171 fmt &= (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK |
172 SND_SOC_DAIFMT_MASTER_MASK);
173
174 if (fmt != (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
175 SND_SOC_DAIFMT_CBS_CFS)) {
176 dev_err(codec_dai->dev, "Invalid DAI format\n");
177 return -EINVAL;
178 }
179
180 return 0;
181}
182
183static int uda1334_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
184{
185 struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(dai->component);
186
187 if (uda1334->mute)
188 gpiod_set_value_cansleep(uda1334->mute, mute);
189
190 return 0;
191}
192
193#define UDA1334_RATES SNDRV_PCM_RATE_8000_96000
194
195#define UDA1334_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
196
197static const struct snd_soc_dai_ops uda1334_dai_ops = {
198 .startup = uda1334_startup,
199 .shutdown = uda1334_shutdown,
200 .set_sysclk = uda1334_set_dai_sysclk,
201 .set_fmt = uda1334_set_fmt,
202 .mute_stream = uda1334_mute_stream,
203};
204
205static struct snd_soc_dai_driver uda1334_dai = {
206 .name = "uda1334-hifi",
207 .playback = {
208 .stream_name = "Playback",
209 .channels_min = 2,
210 .channels_max = 2,
211 .rates = UDA1334_RATES,
212 .formats = UDA1334_FORMATS,
213 },
214 .ops = &uda1334_dai_ops,
215};
216
217static int uda1334_probe(struct snd_soc_component *component)
218{
219 struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
220
221 uda1334->rate_constraint.list = &uda1334->rate_constraint_list[0];
222 uda1334->rate_constraint.count =
223 ARRAY_SIZE(uda1334->rate_constraint_list);
224
225 return 0;
226}
227
228static const struct snd_soc_component_driver soc_component_dev_uda1334 = {
229 .probe = uda1334_probe,
230 .controls = uda1334_snd_controls,
231 .num_controls = ARRAY_SIZE(uda1334_snd_controls),
232 .dapm_widgets = uda1334_dapm_widgets,
233 .num_dapm_widgets = ARRAY_SIZE(uda1334_dapm_widgets),
234 .dapm_routes = uda1334_dapm_routes,
235 .num_dapm_routes = ARRAY_SIZE(uda1334_dapm_routes),
236 .idle_bias_on = 1,
237 .use_pmdown_time = 1,
238 .endianness = 1,
239 .non_legacy_dai_naming = 1,
240};
241
242static const struct of_device_id uda1334_of_match[] = {
243 { .compatible = "nxp,uda1334" },
244 { /* sentinel*/ }
245};
246MODULE_DEVICE_TABLE(of, uda1334_of_match);
247
248static int uda1334_codec_probe(struct platform_device *pdev)
249{
250 struct uda1334_priv *uda1334;
251 int ret;
252
253 uda1334 = devm_kzalloc(&pdev->dev, sizeof(struct uda1334_priv),
254 GFP_KERNEL);
255 if (!uda1334)
256 return -ENOMEM;
257
258 platform_set_drvdata(pdev, uda1334);
259
260 uda1334->mute = devm_gpiod_get(&pdev->dev, "nxp,mute", GPIOD_OUT_LOW);
261 if (IS_ERR(uda1334->mute)) {
262 ret = PTR_ERR(uda1334->mute);
263 dev_err(&pdev->dev, "Failed to get mute line: %d\n", ret);
264 return ret;
265 }
266
267 uda1334->deemph = devm_gpiod_get(&pdev->dev, "nxp,deemph", GPIOD_OUT_LOW);
268 if (IS_ERR(uda1334->deemph)) {
269 ret = PTR_ERR(uda1334->deemph);
270 dev_err(&pdev->dev, "Failed to get deemph line: %d\n", ret);
271 return ret;
272 }
273
274 ret = devm_snd_soc_register_component(&pdev->dev,
275 &soc_component_dev_uda1334,
276 &uda1334_dai, 1);
277 if (ret < 0)
278 dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
279
280 return ret;
281}
282
283static struct platform_driver uda1334_codec_driver = {
284 .probe = uda1334_codec_probe,
285 .driver = {
286 .name = "uda1334-codec",
287 .of_match_table = uda1334_of_match,
288 },
289};
290module_platform_driver(uda1334_codec_driver);
291
292MODULE_DESCRIPTION("ASoC UDA1334 driver");
293MODULE_AUTHOR("Andra Danciu <andradanciu1997@gmail.com>");
294MODULE_ALIAS("platform:uda1334-codec");
295MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/wcd-clsh-v2.c b/sound/soc/codecs/wcd-clsh-v2.c
index c397d713f01a..cc5a9c9b918b 100644
--- a/sound/soc/codecs/wcd-clsh-v2.c
+++ b/sound/soc/codecs/wcd-clsh-v2.c
@@ -65,7 +65,7 @@ struct wcd_clsh_ctrl {
65#define WCD9XXX_FLYBACK_EN_PWDN_WITH_DELAY 0 65#define WCD9XXX_FLYBACK_EN_PWDN_WITH_DELAY 0
66#define WCD9XXX_RX_BIAS_FLYB_BUFF WCD9335_REG(0x6, 0xC7) 66#define WCD9XXX_RX_BIAS_FLYB_BUFF WCD9335_REG(0x6, 0xC7)
67#define WCD9XXX_RX_BIAS_FLYB_VNEG_5_UA_MASK GENMASK(7, 4) 67#define WCD9XXX_RX_BIAS_FLYB_VNEG_5_UA_MASK GENMASK(7, 4)
68#define WCD9XXX_RX_BIAS_FLYB_VPOS_5_UA_MASK GENMASK(0, 3) 68#define WCD9XXX_RX_BIAS_FLYB_VPOS_5_UA_MASK GENMASK(3, 0)
69#define WCD9XXX_HPH_L_EN WCD9335_REG(0x6, 0xD3) 69#define WCD9XXX_HPH_L_EN WCD9335_REG(0x6, 0xD3)
70#define WCD9XXX_HPH_CONST_SEL_L_MASK GENMASK(7, 3) 70#define WCD9XXX_HPH_CONST_SEL_L_MASK GENMASK(7, 3)
71#define WCD9XXX_HPH_CONST_SEL_BYPASS 0 71#define WCD9XXX_HPH_CONST_SEL_BYPASS 0
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index 1bbbe421b999..03f8a94bba2f 100644
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -2071,9 +2071,10 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = {
2071 .id = AIF1_PB, 2071 .id = AIF1_PB,
2072 .playback = { 2072 .playback = {
2073 .stream_name = "AIF1 Playback", 2073 .stream_name = "AIF1 Playback",
2074 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, 2074 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
2075 SNDRV_PCM_RATE_384000,
2075 .formats = WCD9335_FORMATS_S16_S24_LE, 2076 .formats = WCD9335_FORMATS_S16_S24_LE,
2076 .rate_max = 192000, 2077 .rate_max = 384000,
2077 .rate_min = 8000, 2078 .rate_min = 8000,
2078 .channels_min = 1, 2079 .channels_min = 1,
2079 .channels_max = 2, 2080 .channels_max = 2,
@@ -2099,10 +2100,11 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = {
2099 .id = AIF2_PB, 2100 .id = AIF2_PB,
2100 .playback = { 2101 .playback = {
2101 .stream_name = "AIF2 Playback", 2102 .stream_name = "AIF2 Playback",
2102 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, 2103 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
2104 SNDRV_PCM_RATE_384000,
2103 .formats = WCD9335_FORMATS_S16_S24_LE, 2105 .formats = WCD9335_FORMATS_S16_S24_LE,
2104 .rate_min = 8000, 2106 .rate_min = 8000,
2105 .rate_max = 192000, 2107 .rate_max = 384000,
2106 .channels_min = 1, 2108 .channels_min = 1,
2107 .channels_max = 2, 2109 .channels_max = 2,
2108 }, 2110 },
@@ -2127,10 +2129,11 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = {
2127 .id = AIF3_PB, 2129 .id = AIF3_PB,
2128 .playback = { 2130 .playback = {
2129 .stream_name = "AIF3 Playback", 2131 .stream_name = "AIF3 Playback",
2130 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, 2132 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
2133 SNDRV_PCM_RATE_384000,
2131 .formats = WCD9335_FORMATS_S16_S24_LE, 2134 .formats = WCD9335_FORMATS_S16_S24_LE,
2132 .rate_min = 8000, 2135 .rate_min = 8000,
2133 .rate_max = 192000, 2136 .rate_max = 384000,
2134 .channels_min = 1, 2137 .channels_min = 1,
2135 .channels_max = 2, 2138 .channels_max = 2,
2136 }, 2139 },
@@ -2155,10 +2158,11 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = {
2155 .id = AIF4_PB, 2158 .id = AIF4_PB,
2156 .playback = { 2159 .playback = {
2157 .stream_name = "AIF4 Playback", 2160 .stream_name = "AIF4 Playback",
2158 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, 2161 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
2162 SNDRV_PCM_RATE_384000,
2159 .formats = WCD9335_FORMATS_S16_S24_LE, 2163 .formats = WCD9335_FORMATS_S16_S24_LE,
2160 .rate_min = 8000, 2164 .rate_min = 8000,
2161 .rate_max = 192000, 2165 .rate_max = 384000,
2162 .channels_min = 1, 2166 .channels_min = 1,
2163 .channels_max = 2, 2167 .channels_max = 2,
2164 }, 2168 },
@@ -4062,7 +4066,8 @@ static int wcd9335_setup_irqs(struct wcd9335_codec *wcd)
4062 4066
4063 ret = devm_request_threaded_irq(wcd->dev, irq, NULL, 4067 ret = devm_request_threaded_irq(wcd->dev, irq, NULL,
4064 wcd9335_irqs[i].handler, 4068 wcd9335_irqs[i].handler,
4065 IRQF_TRIGGER_RISING, 4069 IRQF_TRIGGER_RISING |
4070 IRQF_ONESHOT,
4066 wcd9335_irqs[i].name, wcd); 4071 wcd9335_irqs[i].name, wcd);
4067 if (ret) { 4072 if (ret) {
4068 dev_err(wcd->dev, "Failed to request %s\n", 4073 dev_err(wcd->dev, "Failed to request %s\n",
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 66a5f1827aa9..9c7e2892c8cb 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -140,7 +140,7 @@ struct pll_factors {
140 * to allow rounding later */ 140 * to allow rounding later */
141#define FIXED_FLL_SIZE ((1 << 22) * 10) 141#define FIXED_FLL_SIZE ((1 << 22) * 10)
142 142
143static int wm8995_pll_factors(struct device *dev, 143static int wm8955_pll_factors(struct device *dev,
144 int Fref, int Fout, struct pll_factors *pll) 144 int Fref, int Fout, struct pll_factors *pll)
145{ 145{
146 u64 Kpart; 146 u64 Kpart;
@@ -279,7 +279,7 @@ static int wm8955_configure_clocking(struct snd_soc_component *component)
279 279
280 /* Use the last divider configuration we saw for the 280 /* Use the last divider configuration we saw for the
281 * sample rate. */ 281 * sample rate. */
282 ret = wm8995_pll_factors(component->dev, wm8955->mclk_rate, 282 ret = wm8955_pll_factors(component->dev, wm8955->mclk_rate,
283 clock_cfgs[sr].mclk, &pll); 283 clock_cfgs[sr].mclk, &pll);
284 if (ret != 0) { 284 if (ret != 0) {
285 dev_err(component->dev, 285 dev_err(component->dev,
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 25e74cf0666a..85bfd041d546 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -273,7 +273,7 @@ static const struct soc_enum wm8988_rline_enum =
273 wm8988_line_texts, 273 wm8988_line_texts,
274 wm8988_line_values); 274 wm8988_line_values);
275static const struct snd_kcontrol_new wm8988_right_line_controls = 275static const struct snd_kcontrol_new wm8988_right_line_controls =
276 SOC_DAPM_ENUM("Route", wm8988_lline_enum); 276 SOC_DAPM_ENUM("Route", wm8988_rline_enum);
277 277
278/* Left Mixer */ 278/* Left Mixer */
279static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = { 279static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = {
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index f5fbadc5e7e2..ae28d9907c30 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -4242,8 +4242,9 @@ static void wm_adsp_fatal_error(struct wm_adsp *dsp)
4242 } 4242 }
4243} 4243}
4244 4244
4245irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) 4245irqreturn_t wm_adsp2_bus_error(int irq, void *data)
4246{ 4246{
4247 struct wm_adsp *dsp = (struct wm_adsp *)data;
4247 unsigned int val; 4248 unsigned int val;
4248 struct regmap *regmap = dsp->regmap; 4249 struct regmap *regmap = dsp->regmap;
4249 int ret = 0; 4250 int ret = 0;
@@ -4307,8 +4308,9 @@ error:
4307} 4308}
4308EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); 4309EXPORT_SYMBOL_GPL(wm_adsp2_bus_error);
4309 4310
4310irqreturn_t wm_halo_bus_error(struct wm_adsp *dsp) 4311irqreturn_t wm_halo_bus_error(int irq, void *data)
4311{ 4312{
4313 struct wm_adsp *dsp = (struct wm_adsp *)data;
4312 struct regmap *regmap = dsp->regmap; 4314 struct regmap *regmap = dsp->regmap;
4313 unsigned int fault[6]; 4315 unsigned int fault[6];
4314 struct reg_sequence clear[] = { 4316 struct reg_sequence clear[] = {
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 3b03d1eb986f..aa634ef6c9f5 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -171,8 +171,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
171int wm_adsp_early_event(struct snd_soc_dapm_widget *w, 171int wm_adsp_early_event(struct snd_soc_dapm_widget *w,
172 struct snd_kcontrol *kcontrol, int event); 172 struct snd_kcontrol *kcontrol, int event);
173 173
174irqreturn_t wm_adsp2_bus_error(struct wm_adsp *adsp); 174irqreturn_t wm_adsp2_bus_error(int irq, void *data);
175irqreturn_t wm_halo_bus_error(struct wm_adsp *dsp); 175irqreturn_t wm_halo_bus_error(int irq, void *data);
176irqreturn_t wm_halo_wdt_expire(int irq, void *data); 176irqreturn_t wm_halo_wdt_expire(int irq, void *data);
177 177
178int wm_adsp_event(struct snd_soc_dapm_widget *w, 178int wm_adsp_event(struct snd_soc_dapm_widget *w,
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index cbbf6257f08a..cfa40ef6b1ca 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -885,10 +885,8 @@ static int fsl_asrc_probe(struct platform_device *pdev)
885 } 885 }
886 886
887 irq = platform_get_irq(pdev, 0); 887 irq = platform_get_irq(pdev, 0);
888 if (irq < 0) { 888 if (irq < 0)
889 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
890 return irq; 889 return irq;
891 }
892 890
893 ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0, 891 ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0,
894 dev_name(&pdev->dev), asrc_priv); 892 dev_name(&pdev->dev), asrc_priv);
diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
index 3897a54a11fe..c7e4e9757dce 100644
--- a/sound/soc/fsl/fsl_audmix.c
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -458,7 +458,6 @@ static int fsl_audmix_probe(struct platform_device *pdev)
458{ 458{
459 struct device *dev = &pdev->dev; 459 struct device *dev = &pdev->dev;
460 struct fsl_audmix *priv; 460 struct fsl_audmix *priv;
461 struct resource *res;
462 const char *mdrv; 461 const char *mdrv;
463 const struct of_device_id *of_id; 462 const struct of_device_id *of_id;
464 void __iomem *regs; 463 void __iomem *regs;
@@ -475,8 +474,7 @@ static int fsl_audmix_probe(struct platform_device *pdev)
475 return -ENOMEM; 474 return -ENOMEM;
476 475
477 /* Get the addresses */ 476 /* Get the addresses */
478 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 477 regs = devm_platform_ioremap_resource(pdev, 0);
479 regs = devm_ioremap_resource(dev, res);
480 if (IS_ERR(regs)) 478 if (IS_ERR(regs))
481 return PTR_ERR(regs); 479 return PTR_ERR(regs);
482 480
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 10d2210c91ef..a78e4ab478df 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -32,15 +32,18 @@
32 * @extalclk: esai clock source to derive HCK, SCK and FS 32 * @extalclk: esai clock source to derive HCK, SCK and FS
33 * @fsysclk: system clock source to derive HCK, SCK and FS 33 * @fsysclk: system clock source to derive HCK, SCK and FS
34 * @spbaclk: SPBA clock (optional, depending on SoC design) 34 * @spbaclk: SPBA clock (optional, depending on SoC design)
35 * @task: tasklet to handle the reset operation
35 * @fifo_depth: depth of tx/rx FIFO 36 * @fifo_depth: depth of tx/rx FIFO
36 * @slot_width: width of each DAI slot 37 * @slot_width: width of each DAI slot
37 * @slots: number of slots 38 * @slots: number of slots
39 * @channels: channel num for tx or rx
38 * @hck_rate: clock rate of desired HCKx clock 40 * @hck_rate: clock rate of desired HCKx clock
39 * @sck_rate: clock rate of desired SCKx clock 41 * @sck_rate: clock rate of desired SCKx clock
40 * @hck_dir: the direction of HCKx pads 42 * @hck_dir: the direction of HCKx pads
41 * @sck_div: if using PSR/PM dividers for SCKx clock 43 * @sck_div: if using PSR/PM dividers for SCKx clock
42 * @slave_mode: if fully using DAI slave mode 44 * @slave_mode: if fully using DAI slave mode
43 * @synchronous: if using tx/rx synchronous mode 45 * @synchronous: if using tx/rx synchronous mode
46 * @reset_at_xrun: flags for enable reset operaton
44 * @name: driver name 47 * @name: driver name
45 */ 48 */
46struct fsl_esai { 49struct fsl_esai {
@@ -52,17 +55,20 @@ struct fsl_esai {
52 struct clk *extalclk; 55 struct clk *extalclk;
53 struct clk *fsysclk; 56 struct clk *fsysclk;
54 struct clk *spbaclk; 57 struct clk *spbaclk;
58 struct tasklet_struct task;
55 u32 fifo_depth; 59 u32 fifo_depth;
56 u32 slot_width; 60 u32 slot_width;
57 u32 slots; 61 u32 slots;
58 u32 tx_mask; 62 u32 tx_mask;
59 u32 rx_mask; 63 u32 rx_mask;
64 u32 channels[2];
60 u32 hck_rate[2]; 65 u32 hck_rate[2];
61 u32 sck_rate[2]; 66 u32 sck_rate[2];
62 bool hck_dir[2]; 67 bool hck_dir[2];
63 bool sck_div[2]; 68 bool sck_div[2];
64 bool slave_mode; 69 bool slave_mode;
65 bool synchronous; 70 bool synchronous;
71 bool reset_at_xrun;
66 char name[32]; 72 char name[32];
67}; 73};
68 74
@@ -71,8 +77,16 @@ static irqreturn_t esai_isr(int irq, void *devid)
71 struct fsl_esai *esai_priv = (struct fsl_esai *)devid; 77 struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
72 struct platform_device *pdev = esai_priv->pdev; 78 struct platform_device *pdev = esai_priv->pdev;
73 u32 esr; 79 u32 esr;
80 u32 saisr;
74 81
75 regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr); 82 regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr);
83 regmap_read(esai_priv->regmap, REG_ESAI_SAISR, &saisr);
84
85 if ((saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE)) &&
86 esai_priv->reset_at_xrun) {
87 dev_dbg(&pdev->dev, "reset module for xrun\n");
88 tasklet_schedule(&esai_priv->task);
89 }
76 90
77 if (esr & ESAI_ESR_TINIT_MASK) 91 if (esr & ESAI_ESR_TINIT_MASK)
78 dev_dbg(&pdev->dev, "isr: Transmission Initialized\n"); 92 dev_dbg(&pdev->dev, "isr: Transmission Initialized\n");
@@ -543,64 +557,184 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
543 return 0; 557 return 0;
544} 558}
545 559
560static int fsl_esai_hw_init(struct fsl_esai *esai_priv)
561{
562 struct platform_device *pdev = esai_priv->pdev;
563 int ret;
564
565 /* Reset ESAI unit */
566 ret = regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
567 ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
568 ESAI_ECR_ESAIEN | ESAI_ECR_ERST);
569 if (ret) {
570 dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
571 return ret;
572 }
573
574 /*
575 * We need to enable ESAI so as to access some of its registers.
576 * Otherwise, we would fail to dump regmap from user space.
577 */
578 ret = regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
579 ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
580 ESAI_ECR_ESAIEN);
581 if (ret) {
582 dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret);
583 return ret;
584 }
585
586 regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
587 ESAI_PRRC_PDC_MASK, 0);
588 regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
589 ESAI_PCRC_PC_MASK, 0);
590
591 return 0;
592}
593
594static int fsl_esai_register_restore(struct fsl_esai *esai_priv)
595{
596 int ret;
597
598 /* FIFO reset for safety */
599 regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR,
600 ESAI_xFCR_xFR, ESAI_xFCR_xFR);
601 regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR,
602 ESAI_xFCR_xFR, ESAI_xFCR_xFR);
603
604 regcache_mark_dirty(esai_priv->regmap);
605 ret = regcache_sync(esai_priv->regmap);
606 if (ret)
607 return ret;
608
609 /* FIFO reset done */
610 regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
611 regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
612
613 return 0;
614}
615
616static void fsl_esai_trigger_start(struct fsl_esai *esai_priv, bool tx)
617{
618 u8 i, channels = esai_priv->channels[tx];
619 u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
620 u32 mask;
621
622 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
623 ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN);
624
625 /* Write initial words reqiured by ESAI as normal procedure */
626 for (i = 0; tx && i < channels; i++)
627 regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);
628
629 /*
630 * When set the TE/RE in the end of enablement flow, there
631 * will be channel swap issue for multi data line case.
632 * In order to workaround this issue, we switch the bit
633 * enablement sequence to below sequence
634 * 1) clear the xSMB & xSMA: which is done in probe and
635 * stop state.
636 * 2) set TE/RE
637 * 3) set xSMB
638 * 4) set xSMA: xSMA is the last one in this flow, which
639 * will trigger esai to start.
640 */
641 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
642 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
643 tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
644 mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask;
645
646 regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
647 ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask));
648 regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
649 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask));
650
651 /* Enable Exception interrupt */
652 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
653 ESAI_xCR_xEIE_MASK, ESAI_xCR_xEIE);
654}
655
656static void fsl_esai_trigger_stop(struct fsl_esai *esai_priv, bool tx)
657{
658 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
659 ESAI_xCR_xEIE_MASK, 0);
660
661 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
662 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
663 regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
664 ESAI_xSMA_xS_MASK, 0);
665 regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
666 ESAI_xSMB_xS_MASK, 0);
667
668 /* Disable and reset FIFO */
669 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
670 ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR);
671 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
672 ESAI_xFCR_xFR, 0);
673}
674
675static void fsl_esai_hw_reset(unsigned long arg)
676{
677 struct fsl_esai *esai_priv = (struct fsl_esai *)arg;
678 bool tx = true, rx = false, enabled[2];
679 u32 tfcr, rfcr;
680
681 /* Save the registers */
682 regmap_read(esai_priv->regmap, REG_ESAI_TFCR, &tfcr);
683 regmap_read(esai_priv->regmap, REG_ESAI_RFCR, &rfcr);
684 enabled[tx] = tfcr & ESAI_xFCR_xFEN;
685 enabled[rx] = rfcr & ESAI_xFCR_xFEN;
686
687 /* Stop the tx & rx */
688 fsl_esai_trigger_stop(esai_priv, tx);
689 fsl_esai_trigger_stop(esai_priv, rx);
690
691 /* Reset the esai, and ignore return value */
692 fsl_esai_hw_init(esai_priv);
693
694 /* Enforce ESAI personal resets for both TX and RX */
695 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
696 ESAI_xCR_xPR_MASK, ESAI_xCR_xPR);
697 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
698 ESAI_xCR_xPR_MASK, ESAI_xCR_xPR);
699
700 /* Restore registers by regcache_sync, and ignore return value */
701 fsl_esai_register_restore(esai_priv);
702
703 /* Remove ESAI personal resets by configuring PCRC and PRRC also */
704 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
705 ESAI_xCR_xPR_MASK, 0);
706 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
707 ESAI_xCR_xPR_MASK, 0);
708 regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
709 ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO));
710 regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
711 ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO));
712
713 /* Restart tx / rx, if they already enabled */
714 if (enabled[tx])
715 fsl_esai_trigger_start(esai_priv, tx);
716 if (enabled[rx])
717 fsl_esai_trigger_start(esai_priv, rx);
718}
719
546static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, 720static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
547 struct snd_soc_dai *dai) 721 struct snd_soc_dai *dai)
548{ 722{
549 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 723 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
550 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 724 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
551 u8 i, channels = substream->runtime->channels; 725
552 u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); 726 esai_priv->channels[tx] = substream->runtime->channels;
553 u32 mask;
554 727
555 switch (cmd) { 728 switch (cmd) {
556 case SNDRV_PCM_TRIGGER_START: 729 case SNDRV_PCM_TRIGGER_START:
557 case SNDRV_PCM_TRIGGER_RESUME: 730 case SNDRV_PCM_TRIGGER_RESUME:
558 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 731 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
559 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), 732 fsl_esai_trigger_start(esai_priv, tx);
560 ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN);
561
562 /* Write initial words reqiured by ESAI as normal procedure */
563 for (i = 0; tx && i < channels; i++)
564 regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);
565
566 /*
567 * When set the TE/RE in the end of enablement flow, there
568 * will be channel swap issue for multi data line case.
569 * In order to workaround this issue, we switch the bit
570 * enablement sequence to below sequence
571 * 1) clear the xSMB & xSMA: which is done in probe and
572 * stop state.
573 * 2) set TE/RE
574 * 3) set xSMB
575 * 4) set xSMA: xSMA is the last one in this flow, which
576 * will trigger esai to start.
577 */
578 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
579 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
580 tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
581 mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask;
582
583 regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
584 ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask));
585 regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
586 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask));
587
588 break; 733 break;
589 case SNDRV_PCM_TRIGGER_SUSPEND: 734 case SNDRV_PCM_TRIGGER_SUSPEND:
590 case SNDRV_PCM_TRIGGER_STOP: 735 case SNDRV_PCM_TRIGGER_STOP:
591 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 736 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
592 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), 737 fsl_esai_trigger_stop(esai_priv, tx);
593 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
594 regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
595 ESAI_xSMA_xS_MASK, 0);
596 regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
597 ESAI_xSMB_xS_MASK, 0);
598
599 /* Disable and reset FIFO */
600 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
601 ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR);
602 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
603 ESAI_xFCR_xFR, 0);
604 break; 738 break;
605 default: 739 default:
606 return -EINVAL; 740 return -EINVAL;
@@ -787,6 +921,10 @@ static int fsl_esai_probe(struct platform_device *pdev)
787 esai_priv->pdev = pdev; 921 esai_priv->pdev = pdev;
788 snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np); 922 snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np);
789 923
924 if (of_device_is_compatible(np, "fsl,vf610-esai") ||
925 of_device_is_compatible(np, "fsl,imx35-esai"))
926 esai_priv->reset_at_xrun = true;
927
790 /* Get the addresses and IRQ */ 928 /* Get the addresses and IRQ */
791 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 929 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
792 regs = devm_ioremap_resource(&pdev->dev, res); 930 regs = devm_ioremap_resource(&pdev->dev, res);
@@ -824,10 +962,8 @@ static int fsl_esai_probe(struct platform_device *pdev)
824 PTR_ERR(esai_priv->spbaclk)); 962 PTR_ERR(esai_priv->spbaclk));
825 963
826 irq = platform_get_irq(pdev, 0); 964 irq = platform_get_irq(pdev, 0);
827 if (irq < 0) { 965 if (irq < 0)
828 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
829 return irq; 966 return irq;
830 }
831 967
832 ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0, 968 ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0,
833 esai_priv->name, esai_priv); 969 esai_priv->name, esai_priv);
@@ -866,22 +1002,9 @@ static int fsl_esai_probe(struct platform_device *pdev)
866 1002
867 dev_set_drvdata(&pdev->dev, esai_priv); 1003 dev_set_drvdata(&pdev->dev, esai_priv);
868 1004
869 /* Reset ESAI unit */ 1005 ret = fsl_esai_hw_init(esai_priv);
870 ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ERST); 1006 if (ret)
871 if (ret) {
872 dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
873 return ret;
874 }
875
876 /*
877 * We need to enable ESAI so as to access some of its registers.
878 * Otherwise, we would fail to dump regmap from user space.
879 */
880 ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ESAIEN);
881 if (ret) {
882 dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret);
883 return ret; 1007 return ret;
884 }
885 1008
886 esai_priv->tx_mask = 0xFFFFFFFF; 1009 esai_priv->tx_mask = 0xFFFFFFFF;
887 esai_priv->rx_mask = 0xFFFFFFFF; 1010 esai_priv->rx_mask = 0xFFFFFFFF;
@@ -899,6 +1022,9 @@ static int fsl_esai_probe(struct platform_device *pdev)
899 return ret; 1022 return ret;
900 } 1023 }
901 1024
1025 tasklet_init(&esai_priv->task, fsl_esai_hw_reset,
1026 (unsigned long)esai_priv);
1027
902 pm_runtime_enable(&pdev->dev); 1028 pm_runtime_enable(&pdev->dev);
903 1029
904 regcache_cache_only(esai_priv->regmap, true); 1030 regcache_cache_only(esai_priv->regmap, true);
@@ -912,7 +1038,10 @@ static int fsl_esai_probe(struct platform_device *pdev)
912 1038
913static int fsl_esai_remove(struct platform_device *pdev) 1039static int fsl_esai_remove(struct platform_device *pdev)
914{ 1040{
1041 struct fsl_esai *esai_priv = platform_get_drvdata(pdev);
1042
915 pm_runtime_disable(&pdev->dev); 1043 pm_runtime_disable(&pdev->dev);
1044 tasklet_kill(&esai_priv->task);
916 1045
917 return 0; 1046 return 0;
918} 1047}
@@ -920,6 +1049,7 @@ static int fsl_esai_remove(struct platform_device *pdev)
920static const struct of_device_id fsl_esai_dt_ids[] = { 1049static const struct of_device_id fsl_esai_dt_ids[] = {
921 { .compatible = "fsl,imx35-esai", }, 1050 { .compatible = "fsl,imx35-esai", },
922 { .compatible = "fsl,vf610-esai", }, 1051 { .compatible = "fsl,vf610-esai", },
1052 { .compatible = "fsl,imx6ull-esai", },
923 {} 1053 {}
924}; 1054};
925MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); 1055MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
@@ -955,20 +1085,10 @@ static int fsl_esai_runtime_resume(struct device *dev)
955 1085
956 regcache_cache_only(esai->regmap, false); 1086 regcache_cache_only(esai->regmap, false);
957 1087
958 /* FIFO reset for safety */ 1088 ret = fsl_esai_register_restore(esai);
959 regmap_update_bits(esai->regmap, REG_ESAI_TFCR,
960 ESAI_xFCR_xFR, ESAI_xFCR_xFR);
961 regmap_update_bits(esai->regmap, REG_ESAI_RFCR,
962 ESAI_xFCR_xFR, ESAI_xFCR_xFR);
963
964 ret = regcache_sync(esai->regmap);
965 if (ret) 1089 if (ret)
966 goto err_regcache_sync; 1090 goto err_regcache_sync;
967 1091
968 /* FIFO reset done */
969 regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
970 regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
971
972 return 0; 1092 return 0;
973 1093
974err_regcache_sync: 1094err_regcache_sync:
@@ -991,7 +1111,6 @@ static int fsl_esai_runtime_suspend(struct device *dev)
991 struct fsl_esai *esai = dev_get_drvdata(dev); 1111 struct fsl_esai *esai = dev_get_drvdata(dev);
992 1112
993 regcache_cache_only(esai->regmap, true); 1113 regcache_cache_only(esai->regmap, true);
994 regcache_mark_dirty(esai->regmap);
995 1114
996 if (!IS_ERR(esai->fsysclk)) 1115 if (!IS_ERR(esai->fsysclk))
997 clk_disable_unprepare(esai->fsysclk); 1116 clk_disable_unprepare(esai->fsysclk);
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index d58cc3ae90d8..728307acab90 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -9,6 +9,7 @@
9#include <linux/dmaengine.h> 9#include <linux/dmaengine.h>
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/of_address.h> 11#include <linux/of_address.h>
12#include <linux/of_device.h>
12#include <linux/pm_runtime.h> 13#include <linux/pm_runtime.h>
13#include <linux/regmap.h> 14#include <linux/regmap.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
@@ -39,6 +40,7 @@ static const struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = {
39static irqreturn_t fsl_sai_isr(int irq, void *devid) 40static irqreturn_t fsl_sai_isr(int irq, void *devid)
40{ 41{
41 struct fsl_sai *sai = (struct fsl_sai *)devid; 42 struct fsl_sai *sai = (struct fsl_sai *)devid;
43 unsigned int ofs = sai->soc_data->reg_offset;
42 struct device *dev = &sai->pdev->dev; 44 struct device *dev = &sai->pdev->dev;
43 u32 flags, xcsr, mask; 45 u32 flags, xcsr, mask;
44 bool irq_none = true; 46 bool irq_none = true;
@@ -51,7 +53,7 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid)
51 mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT; 53 mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;
52 54
53 /* Tx IRQ */ 55 /* Tx IRQ */
54 regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr); 56 regmap_read(sai->regmap, FSL_SAI_TCSR(ofs), &xcsr);
55 flags = xcsr & mask; 57 flags = xcsr & mask;
56 58
57 if (flags) 59 if (flags)
@@ -81,11 +83,11 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid)
81 xcsr &= ~FSL_SAI_CSR_xF_MASK; 83 xcsr &= ~FSL_SAI_CSR_xF_MASK;
82 84
83 if (flags) 85 if (flags)
84 regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr); 86 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), flags | xcsr);
85 87
86irq_rx: 88irq_rx:
87 /* Rx IRQ */ 89 /* Rx IRQ */
88 regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr); 90 regmap_read(sai->regmap, FSL_SAI_RCSR(ofs), &xcsr);
89 flags = xcsr & mask; 91 flags = xcsr & mask;
90 92
91 if (flags) 93 if (flags)
@@ -115,7 +117,7 @@ irq_rx:
115 xcsr &= ~FSL_SAI_CSR_xF_MASK; 117 xcsr &= ~FSL_SAI_CSR_xF_MASK;
116 118
117 if (flags) 119 if (flags)
118 regmap_write(sai->regmap, FSL_SAI_RCSR, flags | xcsr); 120 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), flags | xcsr);
119 121
120out: 122out:
121 if (irq_none) 123 if (irq_none)
@@ -139,6 +141,7 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
139 int clk_id, unsigned int freq, int fsl_dir) 141 int clk_id, unsigned int freq, int fsl_dir)
140{ 142{
141 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 143 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
144 unsigned int ofs = sai->soc_data->reg_offset;
142 bool tx = fsl_dir == FSL_FMT_TRANSMITTER; 145 bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
143 u32 val_cr2 = 0; 146 u32 val_cr2 = 0;
144 147
@@ -159,7 +162,7 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
159 return -EINVAL; 162 return -EINVAL;
160 } 163 }
161 164
162 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), 165 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
163 FSL_SAI_CR2_MSEL_MASK, val_cr2); 166 FSL_SAI_CR2_MSEL_MASK, val_cr2);
164 167
165 return 0; 168 return 0;
@@ -192,6 +195,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
192 unsigned int fmt, int fsl_dir) 195 unsigned int fmt, int fsl_dir)
193{ 196{
194 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 197 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
198 unsigned int ofs = sai->soc_data->reg_offset;
195 bool tx = fsl_dir == FSL_FMT_TRANSMITTER; 199 bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
196 u32 val_cr2 = 0, val_cr4 = 0; 200 u32 val_cr2 = 0, val_cr4 = 0;
197 201
@@ -286,9 +290,9 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
286 return -EINVAL; 290 return -EINVAL;
287 } 291 }
288 292
289 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), 293 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
290 FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2); 294 FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2);
291 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), 295 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
292 FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE | 296 FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE |
293 FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4); 297 FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4);
294 298
@@ -315,6 +319,7 @@ static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
315static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) 319static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
316{ 320{
317 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); 321 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
322 unsigned int ofs = sai->soc_data->reg_offset;
318 unsigned long clk_rate; 323 unsigned long clk_rate;
319 u32 savediv = 0, ratio, savesub = freq; 324 u32 savediv = 0, ratio, savesub = freq;
320 u32 id; 325 u32 id;
@@ -377,17 +382,17 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
377 */ 382 */
378 if ((sai->synchronous[TX] && !sai->synchronous[RX]) || 383 if ((sai->synchronous[TX] && !sai->synchronous[RX]) ||
379 (!tx && !sai->synchronous[RX])) { 384 (!tx && !sai->synchronous[RX])) {
380 regmap_update_bits(sai->regmap, FSL_SAI_RCR2, 385 regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs),
381 FSL_SAI_CR2_MSEL_MASK, 386 FSL_SAI_CR2_MSEL_MASK,
382 FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); 387 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
383 regmap_update_bits(sai->regmap, FSL_SAI_RCR2, 388 regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs),
384 FSL_SAI_CR2_DIV_MASK, savediv - 1); 389 FSL_SAI_CR2_DIV_MASK, savediv - 1);
385 } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) || 390 } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) ||
386 (tx && !sai->synchronous[TX])) { 391 (tx && !sai->synchronous[TX])) {
387 regmap_update_bits(sai->regmap, FSL_SAI_TCR2, 392 regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs),
388 FSL_SAI_CR2_MSEL_MASK, 393 FSL_SAI_CR2_MSEL_MASK,
389 FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); 394 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
390 regmap_update_bits(sai->regmap, FSL_SAI_TCR2, 395 regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs),
391 FSL_SAI_CR2_DIV_MASK, savediv - 1); 396 FSL_SAI_CR2_DIV_MASK, savediv - 1);
392 } 397 }
393 398
@@ -402,6 +407,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
402 struct snd_soc_dai *cpu_dai) 407 struct snd_soc_dai *cpu_dai)
403{ 408{
404 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 409 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
410 unsigned int ofs = sai->soc_data->reg_offset;
405 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 411 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
406 unsigned int channels = params_channels(params); 412 unsigned int channels = params_channels(params);
407 u32 word_width = params_width(params); 413 u32 word_width = params_width(params);
@@ -454,19 +460,19 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
454 460
455 if (!sai->is_slave_mode) { 461 if (!sai->is_slave_mode) {
456 if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { 462 if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
457 regmap_update_bits(sai->regmap, FSL_SAI_TCR4, 463 regmap_update_bits(sai->regmap, FSL_SAI_TCR4(ofs),
458 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, 464 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
459 val_cr4); 465 val_cr4);
460 regmap_update_bits(sai->regmap, FSL_SAI_TCR5, 466 regmap_update_bits(sai->regmap, FSL_SAI_TCR5(ofs),
461 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | 467 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
462 FSL_SAI_CR5_FBT_MASK, val_cr5); 468 FSL_SAI_CR5_FBT_MASK, val_cr5);
463 regmap_write(sai->regmap, FSL_SAI_TMR, 469 regmap_write(sai->regmap, FSL_SAI_TMR,
464 ~0UL - ((1 << channels) - 1)); 470 ~0UL - ((1 << channels) - 1));
465 } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { 471 } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
466 regmap_update_bits(sai->regmap, FSL_SAI_RCR4, 472 regmap_update_bits(sai->regmap, FSL_SAI_RCR4(ofs),
467 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, 473 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
468 val_cr4); 474 val_cr4);
469 regmap_update_bits(sai->regmap, FSL_SAI_RCR5, 475 regmap_update_bits(sai->regmap, FSL_SAI_RCR5(ofs),
470 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | 476 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
471 FSL_SAI_CR5_FBT_MASK, val_cr5); 477 FSL_SAI_CR5_FBT_MASK, val_cr5);
472 regmap_write(sai->regmap, FSL_SAI_RMR, 478 regmap_write(sai->regmap, FSL_SAI_RMR,
@@ -474,10 +480,10 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
474 } 480 }
475 } 481 }
476 482
477 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), 483 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
478 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, 484 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
479 val_cr4); 485 val_cr4);
480 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx), 486 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs),
481 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | 487 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
482 FSL_SAI_CR5_FBT_MASK, val_cr5); 488 FSL_SAI_CR5_FBT_MASK, val_cr5);
483 regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1)); 489 regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1));
@@ -505,6 +511,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
505 struct snd_soc_dai *cpu_dai) 511 struct snd_soc_dai *cpu_dai)
506{ 512{
507 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 513 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
514 unsigned int ofs = sai->soc_data->reg_offset;
515
508 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 516 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
509 u32 xcsr, count = 100; 517 u32 xcsr, count = 100;
510 518
@@ -513,9 +521,9 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
513 * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. 521 * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx.
514 * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx. 522 * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx.
515 */ 523 */
516 regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, 524 regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), FSL_SAI_CR2_SYNC,
517 sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); 525 sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);
518 regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, 526 regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), FSL_SAI_CR2_SYNC,
519 sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0); 527 sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
520 528
521 /* 529 /*
@@ -526,43 +534,44 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
526 case SNDRV_PCM_TRIGGER_START: 534 case SNDRV_PCM_TRIGGER_START:
527 case SNDRV_PCM_TRIGGER_RESUME: 535 case SNDRV_PCM_TRIGGER_RESUME:
528 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 536 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
529 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), 537 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
530 FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); 538 FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);
531 539
532 regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 540 regmap_update_bits(sai->regmap, FSL_SAI_RCSR(ofs),
533 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); 541 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
534 regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 542 regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs),
535 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); 543 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
536 544
537 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), 545 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
538 FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); 546 FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
539 break; 547 break;
540 case SNDRV_PCM_TRIGGER_STOP: 548 case SNDRV_PCM_TRIGGER_STOP:
541 case SNDRV_PCM_TRIGGER_SUSPEND: 549 case SNDRV_PCM_TRIGGER_SUSPEND:
542 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 550 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
543 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), 551 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
544 FSL_SAI_CSR_FRDE, 0); 552 FSL_SAI_CSR_FRDE, 0);
545 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), 553 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
546 FSL_SAI_CSR_xIE_MASK, 0); 554 FSL_SAI_CSR_xIE_MASK, 0);
547 555
548 /* Check if the opposite FRDE is also disabled */ 556 /* Check if the opposite FRDE is also disabled */
549 regmap_read(sai->regmap, FSL_SAI_xCSR(!tx), &xcsr); 557 regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, ofs), &xcsr);
550 if (!(xcsr & FSL_SAI_CSR_FRDE)) { 558 if (!(xcsr & FSL_SAI_CSR_FRDE)) {
551 /* Disable both directions and reset their FIFOs */ 559 /* Disable both directions and reset their FIFOs */
552 regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 560 regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs),
553 FSL_SAI_CSR_TERE, 0); 561 FSL_SAI_CSR_TERE, 0);
554 regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 562 regmap_update_bits(sai->regmap, FSL_SAI_RCSR(ofs),
555 FSL_SAI_CSR_TERE, 0); 563 FSL_SAI_CSR_TERE, 0);
556 564
557 /* TERE will remain set till the end of current frame */ 565 /* TERE will remain set till the end of current frame */
558 do { 566 do {
559 udelay(10); 567 udelay(10);
560 regmap_read(sai->regmap, FSL_SAI_xCSR(tx), &xcsr); 568 regmap_read(sai->regmap,
569 FSL_SAI_xCSR(tx, ofs), &xcsr);
561 } while (--count && xcsr & FSL_SAI_CSR_TERE); 570 } while (--count && xcsr & FSL_SAI_CSR_TERE);
562 571
563 regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 572 regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs),
564 FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); 573 FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
565 regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 574 regmap_update_bits(sai->regmap, FSL_SAI_RCSR(ofs),
566 FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); 575 FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
567 576
568 /* 577 /*
@@ -574,13 +583,13 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
574 */ 583 */
575 if (!sai->is_slave_mode) { 584 if (!sai->is_slave_mode) {
576 /* Software Reset for both Tx and Rx */ 585 /* Software Reset for both Tx and Rx */
577 regmap_write(sai->regmap, 586 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs),
578 FSL_SAI_TCSR, FSL_SAI_CSR_SR); 587 FSL_SAI_CSR_SR);
579 regmap_write(sai->regmap, 588 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs),
580 FSL_SAI_RCSR, FSL_SAI_CSR_SR); 589 FSL_SAI_CSR_SR);
581 /* Clear SR bit to finish the reset */ 590 /* Clear SR bit to finish the reset */
582 regmap_write(sai->regmap, FSL_SAI_TCSR, 0); 591 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
583 regmap_write(sai->regmap, FSL_SAI_RCSR, 0); 592 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
584 } 593 }
585 } 594 }
586 break; 595 break;
@@ -595,10 +604,12 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
595 struct snd_soc_dai *cpu_dai) 604 struct snd_soc_dai *cpu_dai)
596{ 605{
597 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 606 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
607 unsigned int ofs = sai->soc_data->reg_offset;
598 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 608 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
599 int ret; 609 int ret;
600 610
601 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 611 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
612 FSL_SAI_CR3_TRCE_MASK,
602 FSL_SAI_CR3_TRCE); 613 FSL_SAI_CR3_TRCE);
603 614
604 ret = snd_pcm_hw_constraint_list(substream->runtime, 0, 615 ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -611,9 +622,11 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
611 struct snd_soc_dai *cpu_dai) 622 struct snd_soc_dai *cpu_dai)
612{ 623{
613 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 624 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
625 unsigned int ofs = sai->soc_data->reg_offset;
614 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 626 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
615 627
616 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); 628 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
629 FSL_SAI_CR3_TRCE_MASK, 0);
617} 630}
618 631
619static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { 632static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
@@ -630,18 +643,20 @@ static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
630static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) 643static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
631{ 644{
632 struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); 645 struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
646 unsigned int ofs = sai->soc_data->reg_offset;
633 647
634 /* Software Reset for both Tx and Rx */ 648 /* Software Reset for both Tx and Rx */
635 regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); 649 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);
636 regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); 650 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);
637 /* Clear SR bit to finish the reset */ 651 /* Clear SR bit to finish the reset */
638 regmap_write(sai->regmap, FSL_SAI_TCSR, 0); 652 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
639 regmap_write(sai->regmap, FSL_SAI_RCSR, 0); 653 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
640 654
641 regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, 655 regmap_update_bits(sai->regmap, FSL_SAI_TCR1(ofs),
642 FSL_SAI_MAXBURST_TX * 2); 656 FSL_SAI_CR1_RFW_MASK,
643 regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, 657 sai->soc_data->fifo_depth - FSL_SAI_MAXBURST_TX);
644 FSL_SAI_MAXBURST_RX - 1); 658 regmap_update_bits(sai->regmap, FSL_SAI_RCR1(ofs),
659 FSL_SAI_CR1_RFW_MASK, FSL_SAI_MAXBURST_RX - 1);
645 660
646 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, 661 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
647 &sai->dma_params_rx); 662 &sai->dma_params_rx);
@@ -678,41 +693,89 @@ static const struct snd_soc_component_driver fsl_component = {
678 .name = "fsl-sai", 693 .name = "fsl-sai",
679}; 694};
680 695
681static struct reg_default fsl_sai_reg_defaults[] = { 696static struct reg_default fsl_sai_reg_defaults_ofs0[] = {
682 {FSL_SAI_TCR1, 0}, 697 {FSL_SAI_TCR1(0), 0},
683 {FSL_SAI_TCR2, 0}, 698 {FSL_SAI_TCR2(0), 0},
684 {FSL_SAI_TCR3, 0}, 699 {FSL_SAI_TCR3(0), 0},
685 {FSL_SAI_TCR4, 0}, 700 {FSL_SAI_TCR4(0), 0},
686 {FSL_SAI_TCR5, 0}, 701 {FSL_SAI_TCR5(0), 0},
687 {FSL_SAI_TDR, 0}, 702 {FSL_SAI_TDR0, 0},
688 {FSL_SAI_TMR, 0}, 703 {FSL_SAI_TDR1, 0},
689 {FSL_SAI_RCR1, 0}, 704 {FSL_SAI_TDR2, 0},
690 {FSL_SAI_RCR2, 0}, 705 {FSL_SAI_TDR3, 0},
691 {FSL_SAI_RCR3, 0}, 706 {FSL_SAI_TDR4, 0},
692 {FSL_SAI_RCR4, 0}, 707 {FSL_SAI_TDR5, 0},
693 {FSL_SAI_RCR5, 0}, 708 {FSL_SAI_TDR6, 0},
694 {FSL_SAI_RMR, 0}, 709 {FSL_SAI_TDR7, 0},
710 {FSL_SAI_TMR, 0},
711 {FSL_SAI_RCR1(0), 0},
712 {FSL_SAI_RCR2(0), 0},
713 {FSL_SAI_RCR3(0), 0},
714 {FSL_SAI_RCR4(0), 0},
715 {FSL_SAI_RCR5(0), 0},
716 {FSL_SAI_RMR, 0},
717};
718
719static struct reg_default fsl_sai_reg_defaults_ofs8[] = {
720 {FSL_SAI_TCR1(8), 0},
721 {FSL_SAI_TCR2(8), 0},
722 {FSL_SAI_TCR3(8), 0},
723 {FSL_SAI_TCR4(8), 0},
724 {FSL_SAI_TCR5(8), 0},
725 {FSL_SAI_TDR0, 0},
726 {FSL_SAI_TDR1, 0},
727 {FSL_SAI_TDR2, 0},
728 {FSL_SAI_TDR3, 0},
729 {FSL_SAI_TDR4, 0},
730 {FSL_SAI_TDR5, 0},
731 {FSL_SAI_TDR6, 0},
732 {FSL_SAI_TDR7, 0},
733 {FSL_SAI_TMR, 0},
734 {FSL_SAI_RCR1(8), 0},
735 {FSL_SAI_RCR2(8), 0},
736 {FSL_SAI_RCR3(8), 0},
737 {FSL_SAI_RCR4(8), 0},
738 {FSL_SAI_RCR5(8), 0},
739 {FSL_SAI_RMR, 0},
695}; 740};
696 741
697static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) 742static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
698{ 743{
744 struct fsl_sai *sai = dev_get_drvdata(dev);
745 unsigned int ofs = sai->soc_data->reg_offset;
746
747 if (reg >= FSL_SAI_TCSR(ofs) && reg <= FSL_SAI_TCR5(ofs))
748 return true;
749
750 if (reg >= FSL_SAI_RCSR(ofs) && reg <= FSL_SAI_RCR5(ofs))
751 return true;
752
699 switch (reg) { 753 switch (reg) {
700 case FSL_SAI_TCSR: 754 case FSL_SAI_TFR0:
701 case FSL_SAI_TCR1: 755 case FSL_SAI_TFR1:
702 case FSL_SAI_TCR2: 756 case FSL_SAI_TFR2:
703 case FSL_SAI_TCR3: 757 case FSL_SAI_TFR3:
704 case FSL_SAI_TCR4: 758 case FSL_SAI_TFR4:
705 case FSL_SAI_TCR5: 759 case FSL_SAI_TFR5:
706 case FSL_SAI_TFR: 760 case FSL_SAI_TFR6:
761 case FSL_SAI_TFR7:
707 case FSL_SAI_TMR: 762 case FSL_SAI_TMR:
708 case FSL_SAI_RCSR: 763 case FSL_SAI_RDR0:
709 case FSL_SAI_RCR1: 764 case FSL_SAI_RDR1:
710 case FSL_SAI_RCR2: 765 case FSL_SAI_RDR2:
711 case FSL_SAI_RCR3: 766 case FSL_SAI_RDR3:
712 case FSL_SAI_RCR4: 767 case FSL_SAI_RDR4:
713 case FSL_SAI_RCR5: 768 case FSL_SAI_RDR5:
714 case FSL_SAI_RDR: 769 case FSL_SAI_RDR6:
715 case FSL_SAI_RFR: 770 case FSL_SAI_RDR7:
771 case FSL_SAI_RFR0:
772 case FSL_SAI_RFR1:
773 case FSL_SAI_RFR2:
774 case FSL_SAI_RFR3:
775 case FSL_SAI_RFR4:
776 case FSL_SAI_RFR5:
777 case FSL_SAI_RFR6:
778 case FSL_SAI_RFR7:
716 case FSL_SAI_RMR: 779 case FSL_SAI_RMR:
717 return true; 780 return true;
718 default: 781 default:
@@ -722,12 +785,37 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
722 785
723static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) 786static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
724{ 787{
788 struct fsl_sai *sai = dev_get_drvdata(dev);
789 unsigned int ofs = sai->soc_data->reg_offset;
790
791 if (reg == FSL_SAI_TCSR(ofs) || reg == FSL_SAI_RCSR(ofs))
792 return true;
793
725 switch (reg) { 794 switch (reg) {
726 case FSL_SAI_TCSR: 795 case FSL_SAI_TFR0:
727 case FSL_SAI_RCSR: 796 case FSL_SAI_TFR1:
728 case FSL_SAI_TFR: 797 case FSL_SAI_TFR2:
729 case FSL_SAI_RFR: 798 case FSL_SAI_TFR3:
730 case FSL_SAI_RDR: 799 case FSL_SAI_TFR4:
800 case FSL_SAI_TFR5:
801 case FSL_SAI_TFR6:
802 case FSL_SAI_TFR7:
803 case FSL_SAI_RFR0:
804 case FSL_SAI_RFR1:
805 case FSL_SAI_RFR2:
806 case FSL_SAI_RFR3:
807 case FSL_SAI_RFR4:
808 case FSL_SAI_RFR5:
809 case FSL_SAI_RFR6:
810 case FSL_SAI_RFR7:
811 case FSL_SAI_RDR0:
812 case FSL_SAI_RDR1:
813 case FSL_SAI_RDR2:
814 case FSL_SAI_RDR3:
815 case FSL_SAI_RDR4:
816 case FSL_SAI_RDR5:
817 case FSL_SAI_RDR6:
818 case FSL_SAI_RDR7:
731 return true; 819 return true;
732 default: 820 default:
733 return false; 821 return false;
@@ -736,21 +824,25 @@ static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
736 824
737static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg) 825static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
738{ 826{
827 struct fsl_sai *sai = dev_get_drvdata(dev);
828 unsigned int ofs = sai->soc_data->reg_offset;
829
830 if (reg >= FSL_SAI_TCSR(ofs) && reg <= FSL_SAI_TCR5(ofs))
831 return true;
832
833 if (reg >= FSL_SAI_RCSR(ofs) && reg <= FSL_SAI_RCR5(ofs))
834 return true;
835
739 switch (reg) { 836 switch (reg) {
740 case FSL_SAI_TCSR: 837 case FSL_SAI_TDR0:
741 case FSL_SAI_TCR1: 838 case FSL_SAI_TDR1:
742 case FSL_SAI_TCR2: 839 case FSL_SAI_TDR2:
743 case FSL_SAI_TCR3: 840 case FSL_SAI_TDR3:
744 case FSL_SAI_TCR4: 841 case FSL_SAI_TDR4:
745 case FSL_SAI_TCR5: 842 case FSL_SAI_TDR5:
746 case FSL_SAI_TDR: 843 case FSL_SAI_TDR6:
844 case FSL_SAI_TDR7:
747 case FSL_SAI_TMR: 845 case FSL_SAI_TMR:
748 case FSL_SAI_RCSR:
749 case FSL_SAI_RCR1:
750 case FSL_SAI_RCR2:
751 case FSL_SAI_RCR3:
752 case FSL_SAI_RCR4:
753 case FSL_SAI_RCR5:
754 case FSL_SAI_RMR: 846 case FSL_SAI_RMR:
755 return true; 847 return true;
756 default: 848 default:
@@ -758,14 +850,15 @@ static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
758 } 850 }
759} 851}
760 852
761static const struct regmap_config fsl_sai_regmap_config = { 853static struct regmap_config fsl_sai_regmap_config = {
762 .reg_bits = 32, 854 .reg_bits = 32,
763 .reg_stride = 4, 855 .reg_stride = 4,
764 .val_bits = 32, 856 .val_bits = 32,
857 .fast_io = true,
765 858
766 .max_register = FSL_SAI_RMR, 859 .max_register = FSL_SAI_RMR,
767 .reg_defaults = fsl_sai_reg_defaults, 860 .reg_defaults = fsl_sai_reg_defaults_ofs0,
768 .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults), 861 .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults_ofs0),
769 .readable_reg = fsl_sai_readable_reg, 862 .readable_reg = fsl_sai_readable_reg,
770 .volatile_reg = fsl_sai_volatile_reg, 863 .volatile_reg = fsl_sai_volatile_reg,
771 .writeable_reg = fsl_sai_writeable_reg, 864 .writeable_reg = fsl_sai_writeable_reg,
@@ -788,10 +881,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
788 return -ENOMEM; 881 return -ENOMEM;
789 882
790 sai->pdev = pdev; 883 sai->pdev = pdev;
791 884 sai->soc_data = of_device_get_match_data(&pdev->dev);
792 if (of_device_is_compatible(np, "fsl,imx6sx-sai") ||
793 of_device_is_compatible(np, "fsl,imx6ul-sai"))
794 sai->sai_on_imx = true;
795 885
796 sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); 886 sai->is_lsb_first = of_property_read_bool(np, "lsb-first");
797 887
@@ -800,6 +890,12 @@ static int fsl_sai_probe(struct platform_device *pdev)
800 if (IS_ERR(base)) 890 if (IS_ERR(base))
801 return PTR_ERR(base); 891 return PTR_ERR(base);
802 892
893 if (sai->soc_data->reg_offset == 8) {
894 fsl_sai_regmap_config.reg_defaults = fsl_sai_reg_defaults_ofs8;
895 fsl_sai_regmap_config.num_reg_defaults =
896 ARRAY_SIZE(fsl_sai_reg_defaults_ofs8);
897 }
898
803 sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, 899 sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
804 "bus", base, &fsl_sai_regmap_config); 900 "bus", base, &fsl_sai_regmap_config);
805 901
@@ -832,10 +928,8 @@ static int fsl_sai_probe(struct platform_device *pdev)
832 } 928 }
833 929
834 irq = platform_get_irq(pdev, 0); 930 irq = platform_get_irq(pdev, 0);
835 if (irq < 0) { 931 if (irq < 0)
836 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
837 return irq; 932 return irq;
838 }
839 933
840 ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, 0, np->name, sai); 934 ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, 0, np->name, sai);
841 if (ret) { 935 if (ret) {
@@ -886,8 +980,8 @@ static int fsl_sai_probe(struct platform_device *pdev)
886 MCLK_DIR(index)); 980 MCLK_DIR(index));
887 } 981 }
888 982
889 sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; 983 sai->dma_params_rx.addr = res->start + FSL_SAI_RDR0;
890 sai->dma_params_tx.addr = res->start + FSL_SAI_TDR; 984 sai->dma_params_tx.addr = res->start + FSL_SAI_TDR0;
891 sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; 985 sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
892 sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; 986 sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;
893 987
@@ -900,7 +994,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
900 if (ret) 994 if (ret)
901 return ret; 995 return ret;
902 996
903 if (sai->sai_on_imx) 997 if (sai->soc_data->use_imx_pcm)
904 return imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE); 998 return imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE);
905 else 999 else
906 return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 1000 return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
@@ -913,10 +1007,43 @@ static int fsl_sai_remove(struct platform_device *pdev)
913 return 0; 1007 return 0;
914} 1008}
915 1009
1010static const struct fsl_sai_soc_data fsl_sai_vf610_data = {
1011 .use_imx_pcm = false,
1012 .fifo_depth = 32,
1013 .reg_offset = 0,
1014};
1015
1016static const struct fsl_sai_soc_data fsl_sai_imx6sx_data = {
1017 .use_imx_pcm = true,
1018 .fifo_depth = 32,
1019 .reg_offset = 0,
1020};
1021
1022static const struct fsl_sai_soc_data fsl_sai_imx7ulp_data = {
1023 .use_imx_pcm = true,
1024 .fifo_depth = 16,
1025 .reg_offset = 8,
1026};
1027
1028static const struct fsl_sai_soc_data fsl_sai_imx8mq_data = {
1029 .use_imx_pcm = true,
1030 .fifo_depth = 128,
1031 .reg_offset = 8,
1032};
1033
1034static const struct fsl_sai_soc_data fsl_sai_imx8qm_data = {
1035 .use_imx_pcm = true,
1036 .fifo_depth = 64,
1037 .reg_offset = 0,
1038};
1039
916static const struct of_device_id fsl_sai_ids[] = { 1040static const struct of_device_id fsl_sai_ids[] = {
917 { .compatible = "fsl,vf610-sai", }, 1041 { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data },
918 { .compatible = "fsl,imx6sx-sai", }, 1042 { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data },
919 { .compatible = "fsl,imx6ul-sai", }, 1043 { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6sx_data },
1044 { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp_data },
1045 { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq_data },
1046 { .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm_data },
920 { /* sentinel */ } 1047 { /* sentinel */ }
921}; 1048};
922MODULE_DEVICE_TABLE(of, fsl_sai_ids); 1049MODULE_DEVICE_TABLE(of, fsl_sai_ids);
@@ -943,6 +1070,7 @@ static int fsl_sai_runtime_suspend(struct device *dev)
943static int fsl_sai_runtime_resume(struct device *dev) 1070static int fsl_sai_runtime_resume(struct device *dev)
944{ 1071{
945 struct fsl_sai *sai = dev_get_drvdata(dev); 1072 struct fsl_sai *sai = dev_get_drvdata(dev);
1073 unsigned int ofs = sai->soc_data->reg_offset;
946 int ret; 1074 int ret;
947 1075
948 ret = clk_prepare_enable(sai->bus_clk); 1076 ret = clk_prepare_enable(sai->bus_clk);
@@ -964,11 +1092,11 @@ static int fsl_sai_runtime_resume(struct device *dev)
964 } 1092 }
965 1093
966 regcache_cache_only(sai->regmap, false); 1094 regcache_cache_only(sai->regmap, false);
967 regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); 1095 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);
968 regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); 1096 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);
969 usleep_range(1000, 2000); 1097 usleep_range(1000, 2000);
970 regmap_write(sai->regmap, FSL_SAI_TCSR, 0); 1098 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
971 regmap_write(sai->regmap, FSL_SAI_RCSR, 0); 1099 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
972 1100
973 ret = regcache_sync(sai->regmap); 1101 ret = regcache_sync(sai->regmap);
974 if (ret) 1102 if (ret)
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index 24cb156bf995..b89b0ca26053 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -14,33 +14,61 @@
14 SNDRV_PCM_FMTBIT_S32_LE) 14 SNDRV_PCM_FMTBIT_S32_LE)
15 15
16/* SAI Register Map Register */ 16/* SAI Register Map Register */
17#define FSL_SAI_TCSR 0x00 /* SAI Transmit Control */ 17#define FSL_SAI_TCSR(ofs) (0x00 + ofs) /* SAI Transmit Control */
18#define FSL_SAI_TCR1 0x04 /* SAI Transmit Configuration 1 */ 18#define FSL_SAI_TCR1(ofs) (0x04 + ofs) /* SAI Transmit Configuration 1 */
19#define FSL_SAI_TCR2 0x08 /* SAI Transmit Configuration 2 */ 19#define FSL_SAI_TCR2(ofs) (0x08 + ofs) /* SAI Transmit Configuration 2 */
20#define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */ 20#define FSL_SAI_TCR3(ofs) (0x0c + ofs) /* SAI Transmit Configuration 3 */
21#define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */ 21#define FSL_SAI_TCR4(ofs) (0x10 + ofs) /* SAI Transmit Configuration 4 */
22#define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */ 22#define FSL_SAI_TCR5(ofs) (0x14 + ofs) /* SAI Transmit Configuration 5 */
23#define FSL_SAI_TDR 0x20 /* SAI Transmit Data */ 23#define FSL_SAI_TDR0 0x20 /* SAI Transmit Data 0 */
24#define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */ 24#define FSL_SAI_TDR1 0x24 /* SAI Transmit Data 1 */
25#define FSL_SAI_TDR2 0x28 /* SAI Transmit Data 2 */
26#define FSL_SAI_TDR3 0x2C /* SAI Transmit Data 3 */
27#define FSL_SAI_TDR4 0x30 /* SAI Transmit Data 4 */
28#define FSL_SAI_TDR5 0x34 /* SAI Transmit Data 5 */
29#define FSL_SAI_TDR6 0x38 /* SAI Transmit Data 6 */
30#define FSL_SAI_TDR7 0x3C /* SAI Transmit Data 7 */
31#define FSL_SAI_TFR0 0x40 /* SAI Transmit FIFO 0 */
32#define FSL_SAI_TFR1 0x44 /* SAI Transmit FIFO 1 */
33#define FSL_SAI_TFR2 0x48 /* SAI Transmit FIFO 2 */
34#define FSL_SAI_TFR3 0x4C /* SAI Transmit FIFO 3 */
35#define FSL_SAI_TFR4 0x50 /* SAI Transmit FIFO 4 */
36#define FSL_SAI_TFR5 0x54 /* SAI Transmit FIFO 5 */
37#define FSL_SAI_TFR6 0x58 /* SAI Transmit FIFO 6 */
38#define FSL_SAI_TFR7 0x5C /* SAI Transmit FIFO 7 */
25#define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */ 39#define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */
26#define FSL_SAI_RCSR 0x80 /* SAI Receive Control */ 40#define FSL_SAI_RCSR(ofs) (0x80 + ofs) /* SAI Receive Control */
27#define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */ 41#define FSL_SAI_RCR1(ofs) (0x84 + ofs)/* SAI Receive Configuration 1 */
28#define FSL_SAI_RCR2 0x88 /* SAI Receive Configuration 2 */ 42#define FSL_SAI_RCR2(ofs) (0x88 + ofs) /* SAI Receive Configuration 2 */
29#define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */ 43#define FSL_SAI_RCR3(ofs) (0x8c + ofs) /* SAI Receive Configuration 3 */
30#define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */ 44#define FSL_SAI_RCR4(ofs) (0x90 + ofs) /* SAI Receive Configuration 4 */
31#define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */ 45#define FSL_SAI_RCR5(ofs) (0x94 + ofs) /* SAI Receive Configuration 5 */
32#define FSL_SAI_RDR 0xa0 /* SAI Receive Data */ 46#define FSL_SAI_RDR0 0xa0 /* SAI Receive Data 0 */
33#define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */ 47#define FSL_SAI_RDR1 0xa4 /* SAI Receive Data 1 */
48#define FSL_SAI_RDR2 0xa8 /* SAI Receive Data 2 */
49#define FSL_SAI_RDR3 0xac /* SAI Receive Data 3 */
50#define FSL_SAI_RDR4 0xb0 /* SAI Receive Data 4 */
51#define FSL_SAI_RDR5 0xb4 /* SAI Receive Data 5 */
52#define FSL_SAI_RDR6 0xb8 /* SAI Receive Data 6 */
53#define FSL_SAI_RDR7 0xbc /* SAI Receive Data 7 */
54#define FSL_SAI_RFR0 0xc0 /* SAI Receive FIFO 0 */
55#define FSL_SAI_RFR1 0xc4 /* SAI Receive FIFO 1 */
56#define FSL_SAI_RFR2 0xc8 /* SAI Receive FIFO 2 */
57#define FSL_SAI_RFR3 0xcc /* SAI Receive FIFO 3 */
58#define FSL_SAI_RFR4 0xd0 /* SAI Receive FIFO 4 */
59#define FSL_SAI_RFR5 0xd4 /* SAI Receive FIFO 5 */
60#define FSL_SAI_RFR6 0xd8 /* SAI Receive FIFO 6 */
61#define FSL_SAI_RFR7 0xdc /* SAI Receive FIFO 7 */
34#define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ 62#define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */
35 63
36#define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR) 64#define FSL_SAI_xCSR(tx, ofs) (tx ? FSL_SAI_TCSR(ofs) : FSL_SAI_RCSR(ofs))
37#define FSL_SAI_xCR1(tx) (tx ? FSL_SAI_TCR1 : FSL_SAI_RCR1) 65#define FSL_SAI_xCR1(tx, ofs) (tx ? FSL_SAI_TCR1(ofs) : FSL_SAI_RCR1(ofs))
38#define FSL_SAI_xCR2(tx) (tx ? FSL_SAI_TCR2 : FSL_SAI_RCR2) 66#define FSL_SAI_xCR2(tx, ofs) (tx ? FSL_SAI_TCR2(ofs) : FSL_SAI_RCR2(ofs))
39#define FSL_SAI_xCR3(tx) (tx ? FSL_SAI_TCR3 : FSL_SAI_RCR3) 67#define FSL_SAI_xCR3(tx, ofs) (tx ? FSL_SAI_TCR3(ofs) : FSL_SAI_RCR3(ofs))
40#define FSL_SAI_xCR4(tx) (tx ? FSL_SAI_TCR4 : FSL_SAI_RCR4) 68#define FSL_SAI_xCR4(tx, ofs) (tx ? FSL_SAI_TCR4(ofs) : FSL_SAI_RCR4(ofs))
41#define FSL_SAI_xCR5(tx) (tx ? FSL_SAI_TCR5 : FSL_SAI_RCR5) 69#define FSL_SAI_xCR5(tx, ofs) (tx ? FSL_SAI_TCR5(ofs) : FSL_SAI_RCR5(ofs))
42#define FSL_SAI_xDR(tx) (tx ? FSL_SAI_TDR : FSL_SAI_RDR) 70#define FSL_SAI_xDR(tx, ofs) (tx ? FSL_SAI_TDR(ofs) : FSL_SAI_RDR(ofs))
43#define FSL_SAI_xFR(tx) (tx ? FSL_SAI_TFR : FSL_SAI_RFR) 71#define FSL_SAI_xFR(tx, ofs) (tx ? FSL_SAI_TFR(ofs) : FSL_SAI_RFR(ofs))
44#define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR) 72#define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR)
45 73
46/* SAI Transmit/Receive Control Register */ 74/* SAI Transmit/Receive Control Register */
@@ -82,6 +110,7 @@
82 110
83/* SAI Transmit and Receive Configuration 3 Register */ 111/* SAI Transmit and Receive Configuration 3 Register */
84#define FSL_SAI_CR3_TRCE BIT(16) 112#define FSL_SAI_CR3_TRCE BIT(16)
113#define FSL_SAI_CR3_TRCE_MASK GENMASK(23, 16)
85#define FSL_SAI_CR3_WDFL(x) (x) 114#define FSL_SAI_CR3_WDFL(x) (x)
86#define FSL_SAI_CR3_WDFL_MASK 0x1f 115#define FSL_SAI_CR3_WDFL_MASK 0x1f
87 116
@@ -126,6 +155,12 @@
126#define FSL_SAI_MAXBURST_TX 6 155#define FSL_SAI_MAXBURST_TX 6
127#define FSL_SAI_MAXBURST_RX 6 156#define FSL_SAI_MAXBURST_RX 6
128 157
158struct fsl_sai_soc_data {
159 bool use_imx_pcm;
160 unsigned int fifo_depth;
161 unsigned int reg_offset;
162};
163
129struct fsl_sai { 164struct fsl_sai {
130 struct platform_device *pdev; 165 struct platform_device *pdev;
131 struct regmap *regmap; 166 struct regmap *regmap;
@@ -135,7 +170,6 @@ struct fsl_sai {
135 bool is_slave_mode; 170 bool is_slave_mode;
136 bool is_lsb_first; 171 bool is_lsb_first;
137 bool is_dsp_mode; 172 bool is_dsp_mode;
138 bool sai_on_imx;
139 bool synchronous[2]; 173 bool synchronous[2];
140 174
141 unsigned int mclk_id[2]; 175 unsigned int mclk_id[2];
@@ -143,6 +177,7 @@ struct fsl_sai {
143 unsigned int slots; 177 unsigned int slots;
144 unsigned int slot_width; 178 unsigned int slot_width;
145 179
180 const struct fsl_sai_soc_data *soc_data;
146 struct snd_dmaengine_dai_dma_data dma_params_rx; 181 struct snd_dmaengine_dai_dma_data dma_params_rx;
147 struct snd_dmaengine_dai_dma_data dma_params_tx; 182 struct snd_dmaengine_dai_dma_data dma_params_tx;
148}; 183};
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 4842e6df9a2d..7858a5499ac5 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -1248,10 +1248,8 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1248 } 1248 }
1249 1249
1250 irq = platform_get_irq(pdev, 0); 1250 irq = platform_get_irq(pdev, 0);
1251 if (irq < 0) { 1251 if (irq < 0)
1252 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
1253 return irq; 1252 return irq;
1254 }
1255 1253
1256 ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0, 1254 ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0,
1257 dev_name(&pdev->dev), spdif_priv); 1255 dev_name(&pdev->dev), spdif_priv);
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 085855f9b08d..537dc69256f0 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1510,10 +1510,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1510 } 1510 }
1511 1511
1512 ssi->irq = platform_get_irq(pdev, 0); 1512 ssi->irq = platform_get_irq(pdev, 0);
1513 if (ssi->irq < 0) { 1513 if (ssi->irq < 0)
1514 dev_err(dev, "no irq for node %s\n", pdev->name);
1515 return ssi->irq; 1514 return ssi->irq;
1516 }
1517 1515
1518 /* Set software limitations for synchronous mode except AC97 */ 1516 /* Set software limitations for synchronous mode except AC97 */
1519 if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) { 1517 if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) {
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
index 9e1cb18859ce..71590ca6394b 100644
--- a/sound/soc/fsl/imx-audmix.c
+++ b/sound/soc/fsl/imx-audmix.c
@@ -325,14 +325,14 @@ static int imx_audmix_probe(struct platform_device *pdev)
325 priv->card.num_configs = priv->num_dai_conf; 325 priv->card.num_configs = priv->num_dai_conf;
326 priv->card.dapm_routes = priv->dapm_routes; 326 priv->card.dapm_routes = priv->dapm_routes;
327 priv->card.num_dapm_routes = priv->num_dapm_routes; 327 priv->card.num_dapm_routes = priv->num_dapm_routes;
328 priv->card.dev = pdev->dev.parent; 328 priv->card.dev = &pdev->dev;
329 priv->card.owner = THIS_MODULE; 329 priv->card.owner = THIS_MODULE;
330 priv->card.name = "imx-audmix"; 330 priv->card.name = "imx-audmix";
331 331
332 platform_set_drvdata(pdev, &priv->card); 332 platform_set_drvdata(pdev, &priv->card);
333 snd_soc_card_set_drvdata(&priv->card, priv); 333 snd_soc_card_set_drvdata(&priv->card, priv);
334 334
335 ret = devm_snd_soc_register_card(pdev->dev.parent, &priv->card); 335 ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
336 if (ret) { 336 if (ret) {
337 dev_err(&pdev->dev, "snd_soc_register_card failed\n"); 337 dev_err(&pdev->dev, "snd_soc_register_card failed\n");
338 return ret; 338 return ret;
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 16ede3b5cb32..3ce85a43e08f 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -300,12 +300,10 @@ static int imx_audmux_parse_dt_defaults(struct platform_device *pdev,
300 300
301static int imx_audmux_probe(struct platform_device *pdev) 301static int imx_audmux_probe(struct platform_device *pdev)
302{ 302{
303 struct resource *res;
304 const struct of_device_id *of_id = 303 const struct of_device_id *of_id =
305 of_match_device(imx_audmux_dt_ids, &pdev->dev); 304 of_match_device(imx_audmux_dt_ids, &pdev->dev);
306 305
307 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 306 audmux_base = devm_platform_ioremap_resource(pdev, 0);
308 audmux_base = devm_ioremap_resource(&pdev->dev, res);
309 if (IS_ERR(audmux_base)) 307 if (IS_ERR(audmux_base))
310 return PTR_ERR(audmux_base); 308 return PTR_ERR(audmux_base);
311 309
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index 9038b61317be..42031ba7da31 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -520,10 +520,8 @@ static int imx_ssi_probe(struct platform_device *pdev)
520 } 520 }
521 521
522 ssi->irq = platform_get_irq(pdev, 0); 522 ssi->irq = platform_get_irq(pdev, 0);
523 if (ssi->irq < 0) { 523 if (ssi->irq < 0)
524 dev_err(&pdev->dev, "Failed to get IRQ: %d\n", ssi->irq);
525 return ssi->irq; 524 return ssi->irq;
526 }
527 525
528 ssi->clk = devm_clk_get(&pdev->dev, NULL); 526 ssi->clk = devm_clk_get(&pdev->dev, NULL);
529 if (IS_ERR(ssi->clk)) { 527 if (IS_ERR(ssi->clk)) {
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index 288df245b2f0..6007e6305735 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -129,6 +129,25 @@ static int asoc_simple_parse_dai(struct device_node *ep,
129 args.args[0] = graph_get_dai_id(ep); 129 args.args[0] = graph_get_dai_id(ep);
130 args.args_count = (of_graph_get_endpoint_count(node) > 1); 130 args.args_count = (of_graph_get_endpoint_count(node) > 1);
131 131
132 /*
133 * FIXME
134 *
135 * Here, dlc->dai_name is pointer to CPU/Codec DAI name.
136 * If user unbinded CPU or Codec driver, but not for Sound Card,
137 * dlc->dai_name is keeping unbinded CPU or Codec
138 * driver's pointer.
139 *
140 * If user re-bind CPU or Codec driver again, ALSA SoC will try
141 * to rebind Card via snd_soc_try_rebind_card(), but because of
142 * above reason, it might can't bind Sound Card.
143 * Because Sound Card is pointing to released dai_name pointer.
144 *
145 * To avoid this rebind Card issue,
146 * 1) It needs to alloc memory to keep dai_name eventhough
147 * CPU or Codec driver was unbinded, or
148 * 2) user need to rebind Sound Card everytime
149 * if he unbinded CPU or Codec.
150 */
132 ret = snd_soc_get_dai_name(&args, &dlc->dai_name); 151 ret = snd_soc_get_dai_name(&args, &dlc->dai_name);
133 if (ret < 0) 152 if (ret < 0)
134 return ret; 153 return ret;
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 556b1a789629..9b794775df53 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -213,10 +213,17 @@ EXPORT_SYMBOL_GPL(asoc_simple_startup);
213void asoc_simple_shutdown(struct snd_pcm_substream *substream) 213void asoc_simple_shutdown(struct snd_pcm_substream *substream)
214{ 214{
215 struct snd_soc_pcm_runtime *rtd = substream->private_data; 215 struct snd_soc_pcm_runtime *rtd = substream->private_data;
216 struct snd_soc_dai *codec_dai = rtd->codec_dai;
217 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
216 struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); 218 struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
217 struct simple_dai_props *dai_props = 219 struct simple_dai_props *dai_props =
218 simple_priv_to_props(priv, rtd->num); 220 simple_priv_to_props(priv, rtd->num);
219 221
222 if (dai_props->mclk_fs) {
223 snd_soc_dai_set_sysclk(codec_dai, 0, 0, SND_SOC_CLOCK_IN);
224 snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT);
225 }
226
220 asoc_simple_clk_disable(dai_props->cpu_dai); 227 asoc_simple_clk_disable(dai_props->cpu_dai);
221 228
222 asoc_simple_clk_disable(dai_props->codec_dai); 229 asoc_simple_clk_disable(dai_props->codec_dai);
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index ef849151ba56..fc9c753db8dd 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -46,7 +46,25 @@ static int asoc_simple_parse_dai(struct device_node *node,
46 if (ret) 46 if (ret)
47 return ret; 47 return ret;
48 48
49 /* Get dai->name */ 49 /*
50 * FIXME
51 *
52 * Here, dlc->dai_name is pointer to CPU/Codec DAI name.
53 * If user unbinded CPU or Codec driver, but not for Sound Card,
54 * dlc->dai_name is keeping unbinded CPU or Codec
55 * driver's pointer.
56 *
57 * If user re-bind CPU or Codec driver again, ALSA SoC will try
58 * to rebind Card via snd_soc_try_rebind_card(), but because of
59 * above reason, it might can't bind Sound Card.
60 * Because Sound Card is pointing to released dai_name pointer.
61 *
62 * To avoid this rebind Card issue,
63 * 1) It needs to alloc memory to keep dai_name eventhough
64 * CPU or Codec driver was unbinded, or
65 * 2) user need to rebind Sound Card everytime
66 * if he unbinded CPU or Codec.
67 */
50 ret = snd_soc_of_get_dai_name(node, &dlc->dai_name); 68 ret = snd_soc_of_get_dai_name(node, &dlc->dai_name);
51 if (ret < 0) 69 if (ret < 0)
52 return ret; 70 return ret;
@@ -424,7 +442,7 @@ static int simple_parse_aux_devs(struct device_node *node,
424 aux_node = of_parse_phandle(node, PREFIX "aux-devs", i); 442 aux_node = of_parse_phandle(node, PREFIX "aux-devs", i);
425 if (!aux_node) 443 if (!aux_node)
426 return -EINVAL; 444 return -EINVAL;
427 card->aux_dev[i].codec_of_node = aux_node; 445 card->aux_dev[i].dlc.of_node = aux_node;
428 } 446 }
429 447
430 card->num_aux_devs = n; 448 card->num_aux_devs = n;
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 96a00a9d4cf8..01c99750212a 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -215,6 +215,7 @@ config SND_SOC_INTEL_SKYLAKE_COMMON
215 select SND_SOC_INTEL_SST 215 select SND_SOC_INTEL_SST
216 select SND_SOC_HDAC_HDA if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC 216 select SND_SOC_HDAC_HDA if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC
217 select SND_SOC_ACPI_INTEL_MATCH 217 select SND_SOC_ACPI_INTEL_MATCH
218 select SND_INTEL_NHLT if ACPI
218 help 219 help
219 If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/ 220 If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/
220 GeminiLake or CannonLake platform with the DSP enabled in the BIOS 221 GeminiLake or CannonLake platform with the DSP enabled in the BIOS
diff --git a/sound/soc/intel/baytrail/sst-baytrail-ipc.c b/sound/soc/intel/baytrail/sst-baytrail-ipc.c
index 8bd1eddcc091..74274bd38f7a 100644
--- a/sound/soc/intel/baytrail/sst-baytrail-ipc.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-ipc.c
@@ -211,7 +211,7 @@ static struct sst_byt_stream *sst_byt_get_stream(struct sst_byt *byt,
211static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg) 211static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg)
212{ 212{
213 struct sst_byt_stream *stream; 213 struct sst_byt_stream *stream;
214 u64 header = msg->header; 214 u64 header = msg->tx.header;
215 u8 stream_id = sst_byt_header_str_id(header); 215 u8 stream_id = sst_byt_header_str_id(header);
216 u8 stream_msg = sst_byt_header_msg_id(header); 216 u8 stream_msg = sst_byt_header_msg_id(header);
217 217
@@ -240,9 +240,10 @@ static int sst_byt_process_reply(struct sst_byt *byt, u64 header)
240 if (msg == NULL) 240 if (msg == NULL)
241 return 1; 241 return 1;
242 242
243 msg->rx.header = header;
243 if (header & IPC_HEADER_LARGE(true)) { 244 if (header & IPC_HEADER_LARGE(true)) {
244 msg->rx_size = sst_byt_header_data(header); 245 msg->rx.size = sst_byt_header_data(header);
245 sst_dsp_inbox_read(byt->dsp, msg->rx_data, msg->rx_size); 246 sst_dsp_inbox_read(byt->dsp, msg->rx.data, msg->rx.size);
246 } 247 }
247 248
248 /* update any stream states */ 249 /* update any stream states */
@@ -407,17 +408,18 @@ int sst_byt_stream_buffer(struct sst_byt *byt, struct sst_byt_stream *stream,
407 408
408int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream) 409int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream)
409{ 410{
410 struct sst_byt_alloc_params *str_req = &stream->request; 411 struct sst_ipc_message request, reply = {0};
411 struct sst_byt_alloc_response *reply = &stream->reply;
412 u64 header;
413 int ret; 412 int ret;
414 413
415 header = sst_byt_header(IPC_IA_ALLOC_STREAM, 414 request.header = sst_byt_header(IPC_IA_ALLOC_STREAM,
416 sizeof(*str_req) + sizeof(u32), 415 sizeof(stream->request) + sizeof(u32),
417 true, stream->str_id); 416 true, stream->str_id);
418 ret = sst_ipc_tx_message_wait(&byt->ipc, header, str_req, 417 request.data = &stream->request;
419 sizeof(*str_req), 418 request.size = sizeof(stream->request);
420 reply, sizeof(*reply)); 419 reply.data = &stream->reply;
420 reply.size = sizeof(stream->reply);
421
422 ret = sst_ipc_tx_message_wait(&byt->ipc, request, &reply);
421 if (ret < 0) { 423 if (ret < 0) {
422 dev_err(byt->dev, "ipc: error stream commit failed\n"); 424 dev_err(byt->dev, "ipc: error stream commit failed\n");
423 return ret; 425 return ret;
@@ -430,7 +432,7 @@ int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream)
430 432
431int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream) 433int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
432{ 434{
433 u64 header; 435 struct sst_ipc_message request = {0};
434 int ret = 0; 436 int ret = 0;
435 struct sst_dsp *sst = byt->dsp; 437 struct sst_dsp *sst = byt->dsp;
436 unsigned long flags; 438 unsigned long flags;
@@ -438,8 +440,9 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
438 if (!stream->commited) 440 if (!stream->commited)
439 goto out; 441 goto out;
440 442
441 header = sst_byt_header(IPC_IA_FREE_STREAM, 0, false, stream->str_id); 443 request.header = sst_byt_header(IPC_IA_FREE_STREAM,
442 ret = sst_ipc_tx_message_wait(&byt->ipc, header, NULL, 0, NULL, 0); 444 0, false, stream->str_id);
445 ret = sst_ipc_tx_message_wait(&byt->ipc, request, NULL);
443 if (ret < 0) { 446 if (ret < 0) {
444 dev_err(byt->dev, "ipc: free stream %d failed\n", 447 dev_err(byt->dev, "ipc: free stream %d failed\n",
445 stream->str_id); 448 stream->str_id);
@@ -459,15 +462,13 @@ out:
459static int sst_byt_stream_operations(struct sst_byt *byt, int type, 462static int sst_byt_stream_operations(struct sst_byt *byt, int type,
460 int stream_id, int wait) 463 int stream_id, int wait)
461{ 464{
462 u64 header; 465 struct sst_ipc_message request = {0};
463 466
464 header = sst_byt_header(type, 0, false, stream_id); 467 request.header = sst_byt_header(type, 0, false, stream_id);
465 if (wait) 468 if (wait)
466 return sst_ipc_tx_message_wait(&byt->ipc, header, NULL, 469 return sst_ipc_tx_message_wait(&byt->ipc, request, NULL);
467 0, NULL, 0);
468 else 470 else
469 return sst_ipc_tx_message_nowait(&byt->ipc, header, 471 return sst_ipc_tx_message_nowait(&byt->ipc, request);
470 NULL, 0);
471} 472}
472 473
473/* stream ALSA trigger operations */ 474/* stream ALSA trigger operations */
@@ -475,19 +476,17 @@ int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream,
475 u32 start_offset) 476 u32 start_offset)
476{ 477{
477 struct sst_byt_start_stream_params start_stream; 478 struct sst_byt_start_stream_params start_stream;
478 void *tx_msg; 479 struct sst_ipc_message request;
479 size_t size;
480 u64 header;
481 int ret; 480 int ret;
482 481
483 start_stream.byte_offset = start_offset; 482 start_stream.byte_offset = start_offset;
484 header = sst_byt_header(IPC_IA_START_STREAM, 483 request.header = sst_byt_header(IPC_IA_START_STREAM,
485 sizeof(start_stream) + sizeof(u32), 484 sizeof(start_stream) + sizeof(u32),
486 true, stream->str_id); 485 true, stream->str_id);
487 tx_msg = &start_stream; 486 request.data = &start_stream;
488 size = sizeof(start_stream); 487 request.size = sizeof(start_stream);
489 488
490 ret = sst_ipc_tx_message_nowait(&byt->ipc, header, tx_msg, size); 489 ret = sst_ipc_tx_message_nowait(&byt->ipc, request);
491 if (ret < 0) 490 if (ret < 0)
492 dev_err(byt->dev, "ipc: error failed to start stream %d\n", 491 dev_err(byt->dev, "ipc: error failed to start stream %d\n",
493 stream->str_id); 492 stream->str_id);
@@ -623,10 +622,10 @@ EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready);
623 622
624static void byt_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) 623static void byt_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
625{ 624{
626 if (msg->header & IPC_HEADER_LARGE(true)) 625 if (msg->tx.header & IPC_HEADER_LARGE(true))
627 sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); 626 sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
628 627
629 sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->header); 628 sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->tx.header);
630} 629}
631 630
632static void byt_shim_dbg(struct sst_generic_ipc *ipc, const char *text) 631static void byt_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
@@ -648,9 +647,9 @@ static void byt_tx_data_copy(struct ipc_message *msg, char *tx_data,
648 size_t tx_size) 647 size_t tx_size)
649{ 648{
650 /* msg content = lower 32-bit of the header + data */ 649 /* msg content = lower 32-bit of the header + data */
651 *(u32 *)msg->tx_data = (u32)(msg->header & (u32)-1); 650 *(u32 *)msg->tx.data = (u32)(msg->tx.header & (u32)-1);
652 memcpy(msg->tx_data + sizeof(u32), tx_data, tx_size); 651 memcpy(msg->tx.data + sizeof(u32), tx_data, tx_size);
653 msg->tx_size += sizeof(u32); 652 msg->tx.size += sizeof(u32);
654} 653}
655 654
656static u64 byt_reply_msg_match(u64 header, u64 *mask) 655static u64 byt_reply_msg_match(u64 header, u64 *mask)
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index 50bf149818b5..5c27f7ab4a5f 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -256,16 +256,20 @@ config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
256 256
257endif ## SND_SOC_INTEL_SKL 257endif ## SND_SOC_INTEL_SKL
258 258
259config SND_SOC_INTEL_DA7219_MAX98357A_GENERIC
260 tristate
261 select SND_SOC_DA7219
262 select SND_SOC_MAX98357A
263 select SND_SOC_DMIC
264 select SND_SOC_HDAC_HDMI
265
259if SND_SOC_INTEL_APL 266if SND_SOC_INTEL_APL
260 267
261config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH 268config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH
262 tristate "Broxton with DA7219 and MAX98357A in I2S Mode" 269 tristate "Broxton with DA7219 and MAX98357A in I2S Mode"
263 depends on I2C && ACPI 270 depends on I2C && ACPI
264 depends on MFD_INTEL_LPSS || COMPILE_TEST 271 depends on MFD_INTEL_LPSS || COMPILE_TEST
265 select SND_SOC_DA7219 272 select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC
266 select SND_SOC_MAX98357A
267 select SND_SOC_DMIC
268 select SND_SOC_HDAC_HDMI
269 select SND_HDA_DSP_LOADER 273 select SND_HDA_DSP_LOADER
270 help 274 help
271 This adds support for ASoC machine driver for Broxton-P platforms 275 This adds support for ASoC machine driver for Broxton-P platforms
@@ -326,10 +330,7 @@ config SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH
326 tristate "KBL with DA7219 and MAX98357A in I2S Mode" 330 tristate "KBL with DA7219 and MAX98357A in I2S Mode"
327 depends on I2C && ACPI 331 depends on I2C && ACPI
328 depends on MFD_INTEL_LPSS || COMPILE_TEST 332 depends on MFD_INTEL_LPSS || COMPILE_TEST
329 select SND_SOC_DA7219 333 select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC
330 select SND_SOC_MAX98357A
331 select SND_SOC_DMIC
332 select SND_SOC_HDAC_HDMI
333 help 334 help
334 This adds support for ASoC Onboard Codec I2S machine driver. This will 335 This adds support for ASoC Onboard Codec I2S machine driver. This will
335 create an alsa sound card for DA7219 + MAX98357A I2S audio codec. 336 create an alsa sound card for DA7219 + MAX98357A I2S audio codec.
@@ -387,6 +388,7 @@ if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC || SND_SOC_SOF_HDA_AUDIO_CODEC
387config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH 388config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH
388 tristate "SKL/KBL/BXT/APL with HDA Codecs" 389 tristate "SKL/KBL/BXT/APL with HDA Codecs"
389 select SND_SOC_HDAC_HDMI 390 select SND_SOC_HDAC_HDMI
391 select SND_SOC_DMIC
390 # SND_SOC_HDAC_HDA is already selected 392 # SND_SOC_HDAC_HDA is already selected
391 help 393 help
392 This adds support for ASoC machine driver for Intel platforms 394 This adds support for ASoC machine driver for Intel platforms
@@ -412,4 +414,14 @@ config SND_SOC_INTEL_SOF_RT5682_MACH
412 If unsure select "N". 414 If unsure select "N".
413endif ## SND_SOC_SOF_HDA_COMMON || SND_SOC_SOF_BAYTRAIL 415endif ## SND_SOC_SOF_HDA_COMMON || SND_SOC_SOF_BAYTRAIL
414 416
417if (SND_SOC_SOF_COMETLAKE_LP && SND_SOC_SOF_HDA_LINK)
418
419config SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH
420 tristate "CML_LP with DA7219 and MAX98357A in I2S Mode"
421 depends on I2C && ACPI
422 depends on MFD_INTEL_LPSS || COMPILE_TEST
423 select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC
424
425endif ## SND_SOC_SOF_COMETLAKE_LP && SND_SOC_SOF_HDA_LINK
426
415endif ## SND_SOC_INTEL_MACH 427endif ## SND_SOC_INTEL_MACH
diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c
index e8e9c3dc82a5..4a4d3353e26d 100644
--- a/sound/soc/intel/boards/bdw-rt5677.c
+++ b/sound/soc/intel/boards/bdw-rt5677.c
@@ -340,7 +340,6 @@ static int bdw_rt5677_probe(struct platform_device *pdev)
340{ 340{
341 struct bdw_rt5677_priv *bdw_rt5677; 341 struct bdw_rt5677_priv *bdw_rt5677;
342 struct snd_soc_acpi_mach *mach; 342 struct snd_soc_acpi_mach *mach;
343 const char *platform_name = NULL;
344 int ret; 343 int ret;
345 344
346 bdw_rt5677_card.dev = &pdev->dev; 345 bdw_rt5677_card.dev = &pdev->dev;
@@ -355,11 +354,8 @@ static int bdw_rt5677_probe(struct platform_device *pdev)
355 354
356 /* override plaform name, if required */ 355 /* override plaform name, if required */
357 mach = (&pdev->dev)->platform_data; 356 mach = (&pdev->dev)->platform_data;
358 if (mach) /* extra check since legacy does not pass parameters */
359 platform_name = mach->mach_params.platform;
360
361 ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5677_card, 357 ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5677_card,
362 platform_name); 358 mach->mach_params.platform);
363 if (ret) 359 if (ret)
364 return ret; 360 return ret;
365 361
diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c
index ab38ef30dfff..db7e1e87156d 100644
--- a/sound/soc/intel/boards/broadwell.c
+++ b/sound/soc/intel/boards/broadwell.c
@@ -270,18 +270,14 @@ static struct snd_soc_card broadwell_rt286 = {
270static int broadwell_audio_probe(struct platform_device *pdev) 270static int broadwell_audio_probe(struct platform_device *pdev)
271{ 271{
272 struct snd_soc_acpi_mach *mach; 272 struct snd_soc_acpi_mach *mach;
273 const char *platform_name = NULL;
274 int ret; 273 int ret;
275 274
276 broadwell_rt286.dev = &pdev->dev; 275 broadwell_rt286.dev = &pdev->dev;
277 276
278 /* override plaform name, if required */ 277 /* override plaform name, if required */
279 mach = (&pdev->dev)->platform_data; 278 mach = (&pdev->dev)->platform_data;
280 if (mach) /* extra check since legacy does not pass parameters */
281 platform_name = mach->mach_params.platform;
282
283 ret = snd_soc_fixup_dai_links_platform_name(&broadwell_rt286, 279 ret = snd_soc_fixup_dai_links_platform_name(&broadwell_rt286,
284 platform_name); 280 mach->mach_params.platform);
285 if (ret) 281 if (ret)
286 return ret; 282 return ret;
287 283
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
index c0d865a940dc..ac1dea5f9d11 100644
--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
@@ -179,10 +179,17 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
179 int ret; 179 int ret;
180 struct snd_soc_dai *codec_dai = rtd->codec_dai; 180 struct snd_soc_dai *codec_dai = rtd->codec_dai;
181 struct snd_soc_component *component = rtd->codec_dai->component; 181 struct snd_soc_component *component = rtd->codec_dai->component;
182 int clk_freq;
182 183
183 /* Configure sysclk for codec */ 184 /* Configure sysclk for codec */
184 ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 19200000, 185 if (soc_intel_is_cml())
186 clk_freq = 24000000;
187 else
188 clk_freq = 19200000;
189
190 ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq,
185 SND_SOC_CLOCK_IN); 191 SND_SOC_CLOCK_IN);
192
186 if (ret) { 193 if (ret) {
187 dev_err(rtd->dev, "can't set codec sysclk configuration\n"); 194 dev_err(rtd->dev, "can't set codec sysclk configuration\n");
188 return ret; 195 return ret;
@@ -683,6 +690,25 @@ static int broxton_audio_probe(struct platform_device *pdev)
683 broxton_dais[i].cpus->dai_name = "SSP2 Pin"; 690 broxton_dais[i].cpus->dai_name = "SSP2 Pin";
684 } 691 }
685 } 692 }
693 } else if (soc_intel_is_cml()) {
694 unsigned int i;
695
696 broxton_audio_card.name = "cmlda7219max";
697
698 for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
699 /* MAXIM_CODEC is connected to SSP1. */
700 if (!strcmp(broxton_dais[i].codecs->dai_name,
701 BXT_MAXIM_CODEC_DAI)) {
702 broxton_dais[i].name = "SSP1-Codec";
703 broxton_dais[i].cpus->dai_name = "SSP1 Pin";
704 }
705 /* DIALOG_CODEC is connected to SSP0 */
706 else if (!strcmp(broxton_dais[i].codecs->dai_name,
707 BXT_DIALOG_CODEC_DAI)) {
708 broxton_dais[i].name = "SSP0-Codec";
709 broxton_dais[i].cpus->dai_name = "SSP0 Pin";
710 }
711 }
686 } 712 }
687 713
688 /* override plaform name, if required */ 714 /* override plaform name, if required */
@@ -700,6 +726,7 @@ static int broxton_audio_probe(struct platform_device *pdev)
700static const struct platform_device_id bxt_board_ids[] = { 726static const struct platform_device_id bxt_board_ids[] = {
701 { .name = "bxt_da7219_max98357a" }, 727 { .name = "bxt_da7219_max98357a" },
702 { .name = "glk_da7219_max98357a" }, 728 { .name = "glk_da7219_max98357a" },
729 { .name = "cml_da7219_max98357a" },
703 { } 730 { }
704}; 731};
705 732
@@ -720,6 +747,8 @@ MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com>");
720MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); 747MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
721MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>"); 748MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>");
722MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>"); 749MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
750MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
723MODULE_LICENSE("GPL v2"); 751MODULE_LICENSE("GPL v2");
724MODULE_ALIAS("platform:bxt_da7219_max98357a"); 752MODULE_ALIAS("platform:bxt_da7219_max98357a");
725MODULE_ALIAS("platform:glk_da7219_max98357a"); 753MODULE_ALIAS("platform:glk_da7219_max98357a");
754MODULE_ALIAS("platform:cml_da7219_max98357a");
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index 83b978e7b4c4..eaf3e2208a06 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -324,9 +324,8 @@ static const struct snd_soc_ops cht_be_ssp2_ops = {
324}; 324};
325 325
326static struct snd_soc_aux_dev cht_max98090_headset_dev = { 326static struct snd_soc_aux_dev cht_max98090_headset_dev = {
327 .name = "Headset Chip", 327 .dlc = COMP_AUX("i2c-104C227E:00"),
328 .init = cht_max98090_headset_init, 328 .init = cht_max98090_headset_init,
329 .codec_name = "i2c-104C227E:00",
330}; 329};
331 330
332SND_SOC_DAILINK_DEF(dummy, 331SND_SOC_DAILINK_DEF(dummy,
diff --git a/sound/soc/intel/boards/haswell.c b/sound/soc/intel/boards/haswell.c
index 4d3822cff98c..3dadf9bff796 100644
--- a/sound/soc/intel/boards/haswell.c
+++ b/sound/soc/intel/boards/haswell.c
@@ -188,18 +188,14 @@ static struct snd_soc_card haswell_rt5640 = {
188static int haswell_audio_probe(struct platform_device *pdev) 188static int haswell_audio_probe(struct platform_device *pdev)
189{ 189{
190 struct snd_soc_acpi_mach *mach; 190 struct snd_soc_acpi_mach *mach;
191 const char *platform_name = NULL;
192 int ret; 191 int ret;
193 192
194 haswell_rt5640.dev = &pdev->dev; 193 haswell_rt5640.dev = &pdev->dev;
195 194
196 /* override plaform name, if required */ 195 /* override plaform name, if required */
197 mach = (&pdev->dev)->platform_data; 196 mach = (&pdev->dev)->platform_data;
198 if (mach) /* extra check since legacy does not pass parameters */
199 platform_name = mach->mach_params.platform;
200
201 ret = snd_soc_fixup_dai_links_platform_name(&haswell_rt5640, 197 ret = snd_soc_fixup_dai_links_platform_name(&haswell_rt5640,
202 platform_name); 198 mach->mach_params.platform);
203 if (ret) 199 if (ret)
204 return ret; 200 return ret;
205 201
diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.c b/sound/soc/intel/boards/skl_hda_dsp_common.c
index 55fd82e05e2c..58409b6e476e 100644
--- a/sound/soc/intel/boards/skl_hda_dsp_common.c
+++ b/sound/soc/intel/boards/skl_hda_dsp_common.c
@@ -147,6 +147,11 @@ int skl_hda_hdmi_jack_init(struct snd_soc_card *card)
147 if (err) 147 if (err)
148 return err; 148 return err;
149 149
150 err = snd_jack_add_new_kctl(pcm->hdmi_jack.jack,
151 jack_name, SND_JACK_AVOUT);
152 if (err)
153 dev_warn(component->dev, "failed creating Jack kctl\n");
154
150 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, 155 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
151 &pcm->hdmi_jack); 156 &pcm->hdmi_jack);
152 if (err < 0) 157 if (err < 0)
diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c
index 9ed68eb4f058..1778acdc367c 100644
--- a/sound/soc/intel/boards/skl_hda_dsp_generic.c
+++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c
@@ -23,6 +23,7 @@ static const struct snd_soc_dapm_widget skl_hda_widgets[] = {
23 SND_SOC_DAPM_MIC("Alt Analog In", NULL), 23 SND_SOC_DAPM_MIC("Alt Analog In", NULL),
24 SND_SOC_DAPM_SPK("Digital Out", NULL), 24 SND_SOC_DAPM_SPK("Digital Out", NULL),
25 SND_SOC_DAPM_MIC("Digital In", NULL), 25 SND_SOC_DAPM_MIC("Digital In", NULL),
26 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
26}; 27};
27 28
28static const struct snd_soc_dapm_route skl_hda_map[] = { 29static const struct snd_soc_dapm_route skl_hda_map[] = {
@@ -41,6 +42,9 @@ static const struct snd_soc_dapm_route skl_hda_map[] = {
41 { "Codec Input Pin2", NULL, "Digital In" }, 42 { "Codec Input Pin2", NULL, "Digital In" },
42 { "Codec Input Pin3", NULL, "Alt Analog In" }, 43 { "Codec Input Pin3", NULL, "Alt Analog In" },
43 44
45 /* digital mics */
46 {"DMic", NULL, "SoC DMIC"},
47
44 /* CODEC BE connections */ 48 /* CODEC BE connections */
45 { "Analog Codec Playback", NULL, "Analog CPU Playback" }, 49 { "Analog Codec Playback", NULL, "Analog CPU Playback" },
46 { "Analog CPU Playback", NULL, "codec0_out" }, 50 { "Analog CPU Playback", NULL, "codec0_out" },
diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
index 0b12d61cf1e7..a437567b8cee 100644
--- a/sound/soc/intel/boards/sof_rt5682.c
+++ b/sound/soc/intel/boards/sof_rt5682.c
@@ -91,8 +91,7 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
91 { 91 {
92 .callback = sof_rt5682_quirk_cb, 92 .callback = sof_rt5682_quirk_cb,
93 .matches = { 93 .matches = {
94 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 94 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"),
95 DMI_MATCH(DMI_PRODUCT_NAME, "Hatch"),
96 }, 95 },
97 .driver_data = (void *)(SOF_RT5682_MCLK_EN | 96 .driver_data = (void *)(SOF_RT5682_MCLK_EN |
98 SOF_RT5682_MCLK_24MHZ | 97 SOF_RT5682_MCLK_24MHZ |
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
index 56c81e20b5bf..18d9630ae9a2 100644
--- a/sound/soc/intel/common/Makefile
+++ b/sound/soc/intel/common/Makefile
@@ -8,6 +8,7 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m
8 soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \ 8 soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \
9 soc-acpi-intel-bxt-match.o soc-acpi-intel-glk-match.o \ 9 soc-acpi-intel-bxt-match.o soc-acpi-intel-glk-match.o \
10 soc-acpi-intel-cnl-match.o soc-acpi-intel-icl-match.o \ 10 soc-acpi-intel-cnl-match.o soc-acpi-intel-icl-match.o \
11 soc-acpi-intel-tgl-match.o soc-acpi-intel-ehl-match.o \
11 soc-acpi-intel-hda-match.o 12 soc-acpi-intel-hda-match.o
12 13
13obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o 14obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
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 771b0ef21051..985aa366c9e8 100644
--- a/sound/soc/intel/common/soc-acpi-intel-cnl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-cnl-match.c
@@ -19,6 +19,11 @@ static struct snd_soc_acpi_codecs cml_codecs = {
19 .codecs = {"10EC5682"} 19 .codecs = {"10EC5682"}
20}; 20};
21 21
22static struct snd_soc_acpi_codecs cml_spk_codecs = {
23 .num_codecs = 1,
24 .codecs = {"MX98357A"}
25};
26
22struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = { 27struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = {
23 { 28 {
24 .id = "INT34C2", 29 .id = "INT34C2",
@@ -29,6 +34,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = {
29 .sof_tplg_filename = "sof-cnl-rt274.tplg", 34 .sof_tplg_filename = "sof-cnl-rt274.tplg",
30 }, 35 },
31 { 36 {
37 .id = "DLGS7219",
38 .drv_name = "cml_da7219_max98357a",
39 .quirk_data = &cml_spk_codecs,
40 .sof_fw_filename = "sof-cnl.ri",
41 .sof_tplg_filename = "sof-cml-da7219-max98357a.tplg",
42 },
43 {
32 .id = "MX98357A", 44 .id = "MX98357A",
33 .drv_name = "sof_rt5682", 45 .drv_name = "sof_rt5682",
34 .quirk_data = &cml_codecs, 46 .quirk_data = &cml_codecs,
diff --git a/sound/soc/intel/common/soc-acpi-intel-ehl-match.c b/sound/soc/intel/common/soc-acpi-intel-ehl-match.c
new file mode 100644
index 000000000000..a1290c3fa99f
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-ehl-match.c
@@ -0,0 +1,18 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * soc-apci-intel-ehl-match.c - tables and support for EHL ACPI enumeration.
4 *
5 * Copyright (c) 2019, Intel Corporation.
6 *
7 */
8
9#include <sound/soc-acpi.h>
10#include <sound/soc-acpi-intel-match.h>
11
12struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[] = {
13 {},
14};
15EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ehl_machines);
16
17MODULE_LICENSE("GPL v2");
18MODULE_DESCRIPTION("Intel Common ACPI Match module");
diff --git a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
new file mode 100644
index 000000000000..57a6298d6dca
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c
@@ -0,0 +1,24 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * soc-apci-intel-tgl-match.c - tables and support for ICL ACPI enumeration.
4 *
5 * Copyright (c) 2019, Intel Corporation.
6 *
7 */
8
9#include <sound/soc-acpi.h>
10#include <sound/soc-acpi-intel-match.h>
11
12struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = {
13 {
14 .id = "10EC1308",
15 .drv_name = "tgl_rt1308",
16 .sof_fw_filename = "sof-tgl.ri",
17 .sof_tplg_filename = "sof-tgl-rt1308.tplg",
18 },
19 {},
20};
21EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_machines);
22
23MODULE_LICENSE("GPL v2");
24MODULE_DESCRIPTION("Intel Common ACPI Match module");
diff --git a/sound/soc/intel/common/soc-intel-quirks.h b/sound/soc/intel/common/soc-intel-quirks.h
index 4718fd3cf636..e6357d306cb8 100644
--- a/sound/soc/intel/common/soc-intel-quirks.h
+++ b/sound/soc/intel/common/soc-intel-quirks.h
@@ -36,6 +36,7 @@ SOC_INTEL_IS_CPU(byt, INTEL_FAM6_ATOM_SILVERMONT);
36SOC_INTEL_IS_CPU(cht, INTEL_FAM6_ATOM_AIRMONT); 36SOC_INTEL_IS_CPU(cht, INTEL_FAM6_ATOM_AIRMONT);
37SOC_INTEL_IS_CPU(apl, INTEL_FAM6_ATOM_GOLDMONT); 37SOC_INTEL_IS_CPU(apl, INTEL_FAM6_ATOM_GOLDMONT);
38SOC_INTEL_IS_CPU(glk, INTEL_FAM6_ATOM_GOLDMONT_PLUS); 38SOC_INTEL_IS_CPU(glk, INTEL_FAM6_ATOM_GOLDMONT_PLUS);
39SOC_INTEL_IS_CPU(cml, INTEL_FAM6_KABYLAKE_MOBILE);
39 40
40static inline bool soc_intel_is_byt_cr(struct platform_device *pdev) 41static inline bool soc_intel_is_byt_cr(struct platform_device *pdev)
41{ 42{
@@ -110,6 +111,10 @@ static inline bool soc_intel_is_glk(void)
110 return false; 111 return false;
111} 112}
112 113
114static inline bool soc_intel_is_cml(void)
115{
116 return false;
117}
113#endif 118#endif
114 119
115 #endif /* _SND_SOC_INTEL_QUIRKS_H */ 120 #endif /* _SND_SOC_INTEL_QUIRKS_H */
diff --git a/sound/soc/intel/common/sst-acpi.c b/sound/soc/intel/common/sst-acpi.c
index 0e8e0a7a11df..5854868650b9 100644
--- a/sound/soc/intel/common/sst-acpi.c
+++ b/sound/soc/intel/common/sst-acpi.c
@@ -141,11 +141,12 @@ static int sst_acpi_probe(struct platform_device *pdev)
141 } 141 }
142 142
143 platform_set_drvdata(pdev, sst_acpi); 143 platform_set_drvdata(pdev, sst_acpi);
144 mach->pdata = sst_pdata;
144 145
145 /* register machine driver */ 146 /* register machine driver */
146 sst_acpi->pdev_mach = 147 sst_acpi->pdev_mach =
147 platform_device_register_data(dev, mach->drv_name, -1, 148 platform_device_register_data(dev, mach->drv_name, -1,
148 sst_pdata, sizeof(*sst_pdata)); 149 mach, sizeof(*mach));
149 if (IS_ERR(sst_acpi->pdev_mach)) 150 if (IS_ERR(sst_acpi->pdev_mach))
150 return PTR_ERR(sst_acpi->pdev_mach); 151 return PTR_ERR(sst_acpi->pdev_mach);
151 152
diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c
index 3a66121ee9bb..6068bb697e22 100644
--- a/sound/soc/intel/common/sst-ipc.c
+++ b/sound/soc/intel/common/sst-ipc.c
@@ -43,7 +43,7 @@ static struct ipc_message *msg_get_empty(struct sst_generic_ipc *ipc)
43} 43}
44 44
45static int tx_wait_done(struct sst_generic_ipc *ipc, 45static int tx_wait_done(struct sst_generic_ipc *ipc,
46 struct ipc_message *msg, void *rx_data) 46 struct ipc_message *msg, struct sst_ipc_message *reply)
47{ 47{
48 unsigned long flags; 48 unsigned long flags;
49 int ret; 49 int ret;
@@ -62,8 +62,11 @@ static int tx_wait_done(struct sst_generic_ipc *ipc,
62 } else { 62 } else {
63 63
64 /* copy the data returned from DSP */ 64 /* copy the data returned from DSP */
65 if (rx_data) 65 if (reply) {
66 memcpy(rx_data, msg->rx_data, msg->rx_size); 66 reply->header = msg->rx.header;
67 if (reply->data)
68 memcpy(reply->data, msg->rx.data, msg->rx.size);
69 }
67 ret = msg->errno; 70 ret = msg->errno;
68 } 71 }
69 72
@@ -72,9 +75,9 @@ static int tx_wait_done(struct sst_generic_ipc *ipc,
72 return ret; 75 return ret;
73} 76}
74 77
75static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header, 78static int ipc_tx_message(struct sst_generic_ipc *ipc,
76 void *tx_data, size_t tx_bytes, void *rx_data, 79 struct sst_ipc_message request,
77 size_t rx_bytes, int wait) 80 struct sst_ipc_message *reply, int wait)
78{ 81{
79 struct ipc_message *msg; 82 struct ipc_message *msg;
80 unsigned long flags; 83 unsigned long flags;
@@ -87,23 +90,24 @@ static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header,
87 return -EBUSY; 90 return -EBUSY;
88 } 91 }
89 92
90 msg->header = header; 93 msg->tx.header = request.header;
91 msg->tx_size = tx_bytes; 94 msg->tx.size = request.size;
92 msg->rx_size = rx_bytes; 95 msg->rx.header = 0;
96 msg->rx.size = reply ? reply->size : 0;
93 msg->wait = wait; 97 msg->wait = wait;
94 msg->errno = 0; 98 msg->errno = 0;
95 msg->pending = false; 99 msg->pending = false;
96 msg->complete = false; 100 msg->complete = false;
97 101
98 if ((tx_bytes) && (ipc->ops.tx_data_copy != NULL)) 102 if ((request.size) && (ipc->ops.tx_data_copy != NULL))
99 ipc->ops.tx_data_copy(msg, tx_data, tx_bytes); 103 ipc->ops.tx_data_copy(msg, request.data, request.size);
100 104
101 list_add_tail(&msg->list, &ipc->tx_list); 105 list_add_tail(&msg->list, &ipc->tx_list);
102 schedule_work(&ipc->kwork); 106 schedule_work(&ipc->kwork);
103 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); 107 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
104 108
105 if (wait) 109 if (wait)
106 return tx_wait_done(ipc, msg, rx_data); 110 return tx_wait_done(ipc, msg, reply);
107 else 111 else
108 return 0; 112 return 0;
109} 113}
@@ -118,13 +122,13 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc)
118 return -ENOMEM; 122 return -ENOMEM;
119 123
120 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { 124 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
121 ipc->msg[i].tx_data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); 125 ipc->msg[i].tx.data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL);
122 if (ipc->msg[i].tx_data == NULL) 126 if (ipc->msg[i].tx.data == NULL)
123 goto free_mem; 127 goto free_mem;
124 128
125 ipc->msg[i].rx_data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); 129 ipc->msg[i].rx.data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL);
126 if (ipc->msg[i].rx_data == NULL) { 130 if (ipc->msg[i].rx.data == NULL) {
127 kfree(ipc->msg[i].tx_data); 131 kfree(ipc->msg[i].tx.data);
128 goto free_mem; 132 goto free_mem;
129 } 133 }
130 134
@@ -136,8 +140,8 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc)
136 140
137free_mem: 141free_mem:
138 while (i > 0) { 142 while (i > 0) {
139 kfree(ipc->msg[i-1].tx_data); 143 kfree(ipc->msg[i-1].tx.data);
140 kfree(ipc->msg[i-1].rx_data); 144 kfree(ipc->msg[i-1].rx.data);
141 --i; 145 --i;
142 } 146 }
143 kfree(ipc->msg); 147 kfree(ipc->msg);
@@ -173,8 +177,8 @@ static void ipc_tx_msgs(struct work_struct *work)
173 spin_unlock_irq(&ipc->dsp->spinlock); 177 spin_unlock_irq(&ipc->dsp->spinlock);
174} 178}
175 179
176int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header, 180int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc,
177 void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes) 181 struct sst_ipc_message request, struct sst_ipc_message *reply)
178{ 182{
179 int ret; 183 int ret;
180 184
@@ -187,8 +191,7 @@ int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
187 if (ipc->ops.check_dsp_lp_on(ipc->dsp, true)) 191 if (ipc->ops.check_dsp_lp_on(ipc->dsp, true))
188 return -EIO; 192 return -EIO;
189 193
190 ret = ipc_tx_message(ipc, header, tx_data, tx_bytes, 194 ret = ipc_tx_message(ipc, request, reply, 1);
191 rx_data, rx_bytes, 1);
192 195
193 if (ipc->ops.check_dsp_lp_on) 196 if (ipc->ops.check_dsp_lp_on)
194 if (ipc->ops.check_dsp_lp_on(ipc->dsp, false)) 197 if (ipc->ops.check_dsp_lp_on(ipc->dsp, false))
@@ -198,19 +201,17 @@ int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
198} 201}
199EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait); 202EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait);
200 203
201int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header, 204int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc,
202 void *tx_data, size_t tx_bytes) 205 struct sst_ipc_message request)
203{ 206{
204 return ipc_tx_message(ipc, header, tx_data, tx_bytes, 207 return ipc_tx_message(ipc, request, NULL, 0);
205 NULL, 0, 0);
206} 208}
207EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait); 209EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait);
208 210
209int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, u64 header, 211int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc,
210 void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes) 212 struct sst_ipc_message request, struct sst_ipc_message *reply)
211{ 213{
212 return ipc_tx_message(ipc, header, tx_data, tx_bytes, 214 return ipc_tx_message(ipc, request, reply, 1);
213 rx_data, rx_bytes, 1);
214} 215}
215EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nopm); 216EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nopm);
216 217
@@ -232,7 +233,7 @@ struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
232 } 233 }
233 234
234 list_for_each_entry(msg, &ipc->rx_list, list) { 235 list_for_each_entry(msg, &ipc->rx_list, list) {
235 if ((msg->header & mask) == header) 236 if ((msg->tx.header & mask) == header)
236 return msg; 237 return msg;
237 } 238 }
238 239
@@ -306,8 +307,8 @@ void sst_ipc_fini(struct sst_generic_ipc *ipc)
306 307
307 if (ipc->msg) { 308 if (ipc->msg) {
308 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { 309 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
309 kfree(ipc->msg[i].tx_data); 310 kfree(ipc->msg[i].tx.data);
310 kfree(ipc->msg[i].rx_data); 311 kfree(ipc->msg[i].rx.data);
311 } 312 }
312 kfree(ipc->msg); 313 kfree(ipc->msg);
313 } 314 }
diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h
index c6779e2ac830..08c4831b2664 100644
--- a/sound/soc/intel/common/sst-ipc.h
+++ b/sound/soc/intel/common/sst-ipc.h
@@ -17,15 +17,16 @@
17 17
18#define IPC_MAX_MAILBOX_BYTES 256 18#define IPC_MAX_MAILBOX_BYTES 256
19 19
20struct ipc_message { 20struct sst_ipc_message {
21 struct list_head list;
22 u64 header; 21 u64 header;
22 void *data;
23 size_t size;
24};
23 25
24 /* direction wrt host CPU */ 26struct ipc_message {
25 char *tx_data; 27 struct list_head list;
26 size_t tx_size; 28 struct sst_ipc_message tx;
27 char *rx_data; 29 struct sst_ipc_message rx;
28 size_t rx_size;
29 30
30 wait_queue_head_t waitq; 31 wait_queue_head_t waitq;
31 bool pending; 32 bool pending;
@@ -35,6 +36,7 @@ struct ipc_message {
35}; 36};
36 37
37struct sst_generic_ipc; 38struct sst_generic_ipc;
39struct sst_dsp;
38 40
39struct sst_plat_ipc_ops { 41struct sst_plat_ipc_ops {
40 void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *); 42 void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *);
@@ -65,14 +67,14 @@ struct sst_generic_ipc {
65 struct sst_plat_ipc_ops ops; 67 struct sst_plat_ipc_ops ops;
66}; 68};
67 69
68int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header, 70int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc,
69 void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes); 71 struct sst_ipc_message request, struct sst_ipc_message *reply);
70 72
71int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header, 73int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc,
72 void *tx_data, size_t tx_bytes); 74 struct sst_ipc_message request);
73 75
74int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, u64 header, 76int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc,
75 void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes); 77 struct sst_ipc_message request, struct sst_ipc_message *reply);
76 78
77struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, 79struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
78 u64 header); 80 u64 header);
diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c
index a83b92d6bea8..0ff89ea96ccf 100644
--- a/sound/soc/intel/haswell/sst-haswell-ipc.c
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.c
@@ -511,7 +511,7 @@ static void hsw_notification_work(struct work_struct *work)
511static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg) 511static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg)
512{ 512{
513 struct sst_hsw_stream *stream; 513 struct sst_hsw_stream *stream;
514 u32 header = msg->header & ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK); 514 u32 header = msg->tx.header & ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK);
515 u32 stream_id = msg_get_stream_id(header); 515 u32 stream_id = msg_get_stream_id(header);
516 u32 stream_msg = msg_get_stream_type(header); 516 u32 stream_msg = msg_get_stream_type(header);
517 517
@@ -552,6 +552,7 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
552 return -EIO; 552 return -EIO;
553 } 553 }
554 554
555 msg->rx.header = header;
555 /* first process the header */ 556 /* first process the header */
556 switch (reply) { 557 switch (reply) {
557 case IPC_GLB_REPLY_PENDING: 558 case IPC_GLB_REPLY_PENDING:
@@ -562,13 +563,13 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
562 case IPC_GLB_REPLY_SUCCESS: 563 case IPC_GLB_REPLY_SUCCESS:
563 if (msg->pending) { 564 if (msg->pending) {
564 trace_ipc_pending_reply("completed", header); 565 trace_ipc_pending_reply("completed", header);
565 sst_dsp_inbox_read(hsw->dsp, msg->rx_data, 566 sst_dsp_inbox_read(hsw->dsp, msg->rx.data,
566 msg->rx_size); 567 msg->rx.size);
567 hsw->ipc.pending = false; 568 hsw->ipc.pending = false;
568 } else { 569 } else {
569 /* copy data from the DSP */ 570 /* copy data from the DSP */
570 sst_dsp_outbox_read(hsw->dsp, msg->rx_data, 571 sst_dsp_outbox_read(hsw->dsp, msg->rx.data,
571 msg->rx_size); 572 msg->rx.size);
572 } 573 }
573 break; 574 break;
574 /* these will be rare - but useful for debug */ 575 /* these will be rare - but useful for debug */
@@ -810,11 +811,13 @@ static irqreturn_t hsw_irq_thread(int irq, void *context)
810int sst_hsw_fw_get_version(struct sst_hsw *hsw, 811int sst_hsw_fw_get_version(struct sst_hsw *hsw,
811 struct sst_hsw_ipc_fw_version *version) 812 struct sst_hsw_ipc_fw_version *version)
812{ 813{
814 struct sst_ipc_message request = {0}, reply = {0};
813 int ret; 815 int ret;
814 816
815 ret = sst_ipc_tx_message_wait(&hsw->ipc, 817 request.header = IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION);
816 IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION), 818 reply.data = version;
817 NULL, 0, version, sizeof(*version)); 819 reply.size = sizeof(*version);
820 ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
818 if (ret < 0) 821 if (ret < 0)
819 dev_err(hsw->dev, "error: get version failed\n"); 822 dev_err(hsw->dev, "error: get version failed\n");
820 823
@@ -840,7 +843,7 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
840 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume) 843 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume)
841{ 844{
842 struct sst_hsw_ipc_volume_req *req; 845 struct sst_hsw_ipc_volume_req *req;
843 u32 header; 846 struct sst_ipc_message request;
844 int ret; 847 int ret;
845 848
846 trace_ipc_request("set stream volume", stream->reply.stream_hw_id); 849 trace_ipc_request("set stream volume", stream->reply.stream_hw_id);
@@ -848,11 +851,11 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
848 if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL) 851 if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL)
849 return -EINVAL; 852 return -EINVAL;
850 853
851 header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | 854 request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
852 IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE); 855 IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
853 header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT); 856 request.header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT);
854 header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT); 857 request.header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
855 header |= (stage_id << IPC_STG_ID_SHIFT); 858 request.header |= (stage_id << IPC_STG_ID_SHIFT);
856 859
857 req = &stream->vol_req; 860 req = &stream->vol_req;
858 req->target_volume = volume; 861 req->target_volume = volume;
@@ -877,8 +880,9 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
877 req->channel = channel; 880 req->channel = channel;
878 } 881 }
879 882
880 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, req, 883 request.data = req;
881 sizeof(*req), NULL, 0); 884 request.size = sizeof(*req);
885 ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
882 if (ret < 0) { 886 if (ret < 0) {
883 dev_err(hsw->dev, "error: set stream volume failed\n"); 887 dev_err(hsw->dev, "error: set stream volume failed\n");
884 return ret; 888 return ret;
@@ -905,7 +909,7 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
905 u32 volume) 909 u32 volume)
906{ 910{
907 struct sst_hsw_ipc_volume_req req; 911 struct sst_hsw_ipc_volume_req req;
908 u32 header; 912 struct sst_ipc_message request;
909 int ret; 913 int ret;
910 914
911 trace_ipc_request("set mixer volume", volume); 915 trace_ipc_request("set mixer volume", volume);
@@ -933,18 +937,19 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
933 req.channel = channel; 937 req.channel = channel;
934 } 938 }
935 939
936 header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | 940 request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
937 IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE); 941 IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
938 header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT); 942 request.header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT);
939 header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT); 943 request.header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
940 header |= (stage_id << IPC_STG_ID_SHIFT); 944 request.header |= (stage_id << IPC_STG_ID_SHIFT);
941 945
942 req.curve_duration = hsw->curve_duration; 946 req.curve_duration = hsw->curve_duration;
943 req.curve_type = hsw->curve_type; 947 req.curve_type = hsw->curve_type;
944 req.target_volume = volume; 948 req.target_volume = volume;
945 949
946 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &req, 950 request.data = &req;
947 sizeof(req), NULL, 0); 951 request.size = sizeof(req);
952 ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
948 if (ret < 0) { 953 if (ret < 0) {
949 dev_err(hsw->dev, "error: set mixer volume failed\n"); 954 dev_err(hsw->dev, "error: set mixer volume failed\n");
950 return ret; 955 return ret;
@@ -983,7 +988,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
983 988
984int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream) 989int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
985{ 990{
986 u32 header; 991 struct sst_ipc_message request;
987 int ret = 0; 992 int ret = 0;
988 struct sst_dsp *sst = hsw->dsp; 993 struct sst_dsp *sst = hsw->dsp;
989 unsigned long flags; 994 unsigned long flags;
@@ -1000,10 +1005,11 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1000 trace_ipc_request("stream free", stream->host_id); 1005 trace_ipc_request("stream free", stream->host_id);
1001 1006
1002 stream->free_req.stream_id = stream->reply.stream_hw_id; 1007 stream->free_req.stream_id = stream->reply.stream_hw_id;
1003 header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM); 1008 request.header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM);
1009 request.data = &stream->free_req;
1010 request.size = sizeof(stream->free_req);
1004 1011
1005 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &stream->free_req, 1012 ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
1006 sizeof(stream->free_req), NULL, 0);
1007 if (ret < 0) { 1013 if (ret < 0) {
1008 dev_err(hsw->dev, "error: free stream %d failed\n", 1014 dev_err(hsw->dev, "error: free stream %d failed\n",
1009 stream->free_req.stream_id); 1015 stream->free_req.stream_id);
@@ -1175,9 +1181,7 @@ int sst_hsw_stream_set_module_info(struct sst_hsw *hsw,
1175 1181
1176int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream) 1182int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1177{ 1183{
1178 struct sst_hsw_ipc_stream_alloc_req *str_req = &stream->request; 1184 struct sst_ipc_message request, reply = {0};
1179 struct sst_hsw_ipc_stream_alloc_reply *reply = &stream->reply;
1180 u32 header;
1181 int ret; 1185 int ret;
1182 1186
1183 if (!stream) { 1187 if (!stream) {
@@ -1192,10 +1196,13 @@ int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1192 1196
1193 trace_ipc_request("stream alloc", stream->host_id); 1197 trace_ipc_request("stream alloc", stream->host_id);
1194 1198
1195 header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM); 1199 request.header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM);
1200 request.data = &stream->request;
1201 request.size = sizeof(stream->request);
1202 reply.data = &stream->reply;
1203 reply.size = sizeof(stream->reply);
1196 1204
1197 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, str_req, 1205 ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
1198 sizeof(*str_req), reply, sizeof(*reply));
1199 if (ret < 0) { 1206 if (ret < 0) {
1200 dev_err(hsw->dev, "error: stream commit failed\n"); 1207 dev_err(hsw->dev, "error: stream commit failed\n");
1201 return ret; 1208 return ret;
@@ -1235,23 +1242,22 @@ void sst_hsw_stream_set_silence_start(struct sst_hsw *hsw,
1235 ABI to be opaque to client PCM drivers to cope with any future ABI changes */ 1242 ABI to be opaque to client PCM drivers to cope with any future ABI changes */
1236int sst_hsw_mixer_get_info(struct sst_hsw *hsw) 1243int sst_hsw_mixer_get_info(struct sst_hsw *hsw)
1237{ 1244{
1238 struct sst_hsw_ipc_stream_info_reply *reply; 1245 struct sst_ipc_message request = {0}, reply = {0};
1239 u32 header;
1240 int ret; 1246 int ret;
1241 1247
1242 reply = &hsw->mixer_info; 1248 request.header = IPC_GLB_TYPE(IPC_GLB_GET_MIXER_STREAM_INFO);
1243 header = IPC_GLB_TYPE(IPC_GLB_GET_MIXER_STREAM_INFO); 1249 reply.data = &hsw->mixer_info;
1250 reply.size = sizeof(hsw->mixer_info);
1244 1251
1245 trace_ipc_request("get global mixer info", 0); 1252 trace_ipc_request("get global mixer info", 0);
1246 1253
1247 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0, 1254 ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
1248 reply, sizeof(*reply));
1249 if (ret < 0) { 1255 if (ret < 0) {
1250 dev_err(hsw->dev, "error: get stream info failed\n"); 1256 dev_err(hsw->dev, "error: get stream info failed\n");
1251 return ret; 1257 return ret;
1252 } 1258 }
1253 1259
1254 trace_hsw_mixer_info_reply(reply); 1260 trace_hsw_mixer_info_reply(&hsw->mixer_info);
1255 1261
1256 return 0; 1262 return 0;
1257} 1263}
@@ -1260,16 +1266,15 @@ int sst_hsw_mixer_get_info(struct sst_hsw *hsw)
1260static int sst_hsw_stream_operations(struct sst_hsw *hsw, int type, 1266static int sst_hsw_stream_operations(struct sst_hsw *hsw, int type,
1261 int stream_id, int wait) 1267 int stream_id, int wait)
1262{ 1268{
1263 u32 header; 1269 struct sst_ipc_message request = {0};
1264 1270
1265 header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | IPC_STR_TYPE(type); 1271 request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE);
1266 header |= (stream_id << IPC_STR_ID_SHIFT); 1272 request.header |= IPC_STR_TYPE(type) | (stream_id << IPC_STR_ID_SHIFT);
1267 1273
1268 if (wait) 1274 if (wait)
1269 return sst_ipc_tx_message_wait(&hsw->ipc, header, 1275 return sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
1270 NULL, 0, NULL, 0);
1271 else 1276 else
1272 return sst_ipc_tx_message_nowait(&hsw->ipc, header, NULL, 0); 1277 return sst_ipc_tx_message_nowait(&hsw->ipc, request);
1273} 1278}
1274 1279
1275/* Stream ALSA trigger operations */ 1280/* Stream ALSA trigger operations */
@@ -1377,8 +1382,8 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw,
1377 enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk, 1382 enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk,
1378 enum sst_hsw_device_mode mode, u32 clock_divider) 1383 enum sst_hsw_device_mode mode, u32 clock_divider)
1379{ 1384{
1385 struct sst_ipc_message request;
1380 struct sst_hsw_ipc_device_config_req config; 1386 struct sst_hsw_ipc_device_config_req config;
1381 u32 header;
1382 int ret; 1387 int ret;
1383 1388
1384 trace_ipc_request("set device config", dev); 1389 trace_ipc_request("set device config", dev);
@@ -1394,10 +1399,11 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw,
1394 1399
1395 trace_hsw_device_config_req(&config); 1400 trace_hsw_device_config_req(&config);
1396 1401
1397 header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS); 1402 request.header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS);
1403 request.data = &config;
1404 request.size = sizeof(config);
1398 1405
1399 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &config, 1406 ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
1400 sizeof(config), NULL, 0);
1401 if (ret < 0) 1407 if (ret < 0)
1402 dev_err(hsw->dev, "error: set device formats failed\n"); 1408 dev_err(hsw->dev, "error: set device formats failed\n");
1403 1409
@@ -1409,16 +1415,20 @@ EXPORT_SYMBOL_GPL(sst_hsw_device_set_config);
1409int sst_hsw_dx_set_state(struct sst_hsw *hsw, 1415int sst_hsw_dx_set_state(struct sst_hsw *hsw,
1410 enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx) 1416 enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx)
1411{ 1417{
1412 u32 header, state_; 1418 struct sst_ipc_message request, reply = {0};
1419 u32 state_;
1413 int ret, item; 1420 int ret, item;
1414 1421
1415 header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE);
1416 state_ = state; 1422 state_ = state;
1423 request.header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE);
1424 request.data = &state_;
1425 request.size = sizeof(state_);
1426 reply.data = dx;
1427 reply.size = sizeof(*dx);
1417 1428
1418 trace_ipc_request("PM enter Dx state", state); 1429 trace_ipc_request("PM enter Dx state", state);
1419 1430
1420 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &state_, 1431 ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
1421 sizeof(state_), dx, sizeof(*dx));
1422 if (ret < 0) { 1432 if (ret < 0) {
1423 dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state); 1433 dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state);
1424 return ret; 1434 return ret;
@@ -1878,7 +1888,7 @@ int sst_hsw_module_enable(struct sst_hsw *hsw,
1878 u32 module_id, u32 instance_id) 1888 u32 module_id, u32 instance_id)
1879{ 1889{
1880 int ret; 1890 int ret;
1881 u32 header = 0; 1891 struct sst_ipc_message request;
1882 struct sst_hsw_ipc_module_config config; 1892 struct sst_hsw_ipc_module_config config;
1883 struct sst_module *module; 1893 struct sst_module *module;
1884 struct sst_module_runtime *runtime; 1894 struct sst_module_runtime *runtime;
@@ -1907,10 +1917,10 @@ int sst_hsw_module_enable(struct sst_hsw *hsw,
1907 return -ENXIO; 1917 return -ENXIO;
1908 } 1918 }
1909 1919
1910 header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) | 1920 request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
1911 IPC_MODULE_OPERATION(IPC_MODULE_ENABLE) | 1921 IPC_MODULE_OPERATION(IPC_MODULE_ENABLE) |
1912 IPC_MODULE_ID(module_id); 1922 IPC_MODULE_ID(module_id);
1913 dev_dbg(dev, "module enable header: %x\n", header); 1923 dev_dbg(dev, "module enable header: %x\n", (u32)request.header);
1914 1924
1915 config.map.module_entries_count = 1; 1925 config.map.module_entries_count = 1;
1916 config.map.module_entries[0].module_id = module->id; 1926 config.map.module_entries[0].module_id = module->id;
@@ -1932,8 +1942,9 @@ int sst_hsw_module_enable(struct sst_hsw *hsw,
1932 config.scratch_mem.size, config.scratch_mem.offset, 1942 config.scratch_mem.size, config.scratch_mem.offset,
1933 config.map.module_entries[0].entry_point); 1943 config.map.module_entries[0].entry_point);
1934 1944
1935 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, 1945 request.data = &config;
1936 &config, sizeof(config), NULL, 0); 1946 request.size = sizeof(config);
1947 ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
1937 if (ret < 0) 1948 if (ret < 0)
1938 dev_err(dev, "ipc: module enable failed - %d\n", ret); 1949 dev_err(dev, "ipc: module enable failed - %d\n", ret);
1939 else 1950 else
@@ -1946,7 +1957,7 @@ int sst_hsw_module_disable(struct sst_hsw *hsw,
1946 u32 module_id, u32 instance_id) 1957 u32 module_id, u32 instance_id)
1947{ 1958{
1948 int ret; 1959 int ret;
1949 u32 header; 1960 struct sst_ipc_message request = {0};
1950 struct sst_module *module; 1961 struct sst_module *module;
1951 struct device *dev = hsw->dev; 1962 struct device *dev = hsw->dev;
1952 struct sst_dsp *dsp = hsw->dsp; 1963 struct sst_dsp *dsp = hsw->dsp;
@@ -1967,11 +1978,11 @@ int sst_hsw_module_disable(struct sst_hsw *hsw,
1967 return -ENXIO; 1978 return -ENXIO;
1968 } 1979 }
1969 1980
1970 header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) | 1981 request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
1971 IPC_MODULE_OPERATION(IPC_MODULE_DISABLE) | 1982 IPC_MODULE_OPERATION(IPC_MODULE_DISABLE) |
1972 IPC_MODULE_ID(module_id); 1983 IPC_MODULE_ID(module_id);
1973 1984
1974 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0, NULL, 0); 1985 ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
1975 if (ret < 0) 1986 if (ret < 0)
1976 dev_err(dev, "module disable failed - %d\n", ret); 1987 dev_err(dev, "module disable failed - %d\n", ret);
1977 else 1988 else
@@ -1985,15 +1996,16 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
1985 u32 param_size, char *param) 1996 u32 param_size, char *param)
1986{ 1997{
1987 int ret; 1998 int ret;
1988 u32 header = 0; 1999 struct sst_ipc_message request = {0};
1989 u32 payload_size = 0, transfer_parameter_size = 0; 2000 u32 payload_size = 0;
1990 struct sst_hsw_transfer_parameter *parameter; 2001 struct sst_hsw_transfer_parameter *parameter;
1991 struct device *dev = hsw->dev; 2002 struct device *dev = hsw->dev;
1992 2003
1993 header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) | 2004 request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
1994 IPC_MODULE_OPERATION(IPC_MODULE_SET_PARAMETER) | 2005 IPC_MODULE_OPERATION(IPC_MODULE_SET_PARAMETER) |
1995 IPC_MODULE_ID(module_id); 2006 IPC_MODULE_ID(module_id);
1996 dev_dbg(dev, "sst_hsw_module_set_param header=%x\n", header); 2007 dev_dbg(dev, "sst_hsw_module_set_param header=%x\n",
2008 (u32)request.header);
1997 2009
1998 payload_size = param_size + 2010 payload_size = param_size +
1999 sizeof(struct sst_hsw_transfer_parameter) - 2011 sizeof(struct sst_hsw_transfer_parameter) -
@@ -2003,14 +2015,14 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
2003 2015
2004 if (payload_size <= SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE) { 2016 if (payload_size <= SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE) {
2005 /* short parameter, mailbox can contain data */ 2017 /* short parameter, mailbox can contain data */
2006 dev_dbg(dev, "transfer parameter size : %d\n", 2018 dev_dbg(dev, "transfer parameter size : %zu\n",
2007 transfer_parameter_size); 2019 request.size);
2008 2020
2009 transfer_parameter_size = ALIGN(payload_size, 4); 2021 request.size = ALIGN(payload_size, 4);
2010 dev_dbg(dev, "transfer parameter aligned size : %d\n", 2022 dev_dbg(dev, "transfer parameter aligned size : %zu\n",
2011 transfer_parameter_size); 2023 request.size);
2012 2024
2013 parameter = kzalloc(transfer_parameter_size, GFP_KERNEL); 2025 parameter = kzalloc(request.size, GFP_KERNEL);
2014 if (parameter == NULL) 2026 if (parameter == NULL)
2015 return -ENOMEM; 2027 return -ENOMEM;
2016 2028
@@ -2022,9 +2034,9 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
2022 2034
2023 parameter->parameter_id = parameter_id; 2035 parameter->parameter_id = parameter_id;
2024 parameter->data_size = param_size; 2036 parameter->data_size = param_size;
2037 request.data = parameter;
2025 2038
2026 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, 2039 ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
2027 parameter, transfer_parameter_size , NULL, 0);
2028 if (ret < 0) 2040 if (ret < 0)
2029 dev_err(dev, "ipc: module set parameter failed - %d\n", ret); 2041 dev_err(dev, "ipc: module set parameter failed - %d\n", ret);
2030 2042
@@ -2041,8 +2053,8 @@ static struct sst_dsp_device hsw_dev = {
2041static void hsw_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) 2053static void hsw_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
2042{ 2054{
2043 /* send the message */ 2055 /* send the message */
2044 sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); 2056 sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
2045 sst_dsp_ipc_msg_tx(ipc->dsp, msg->header); 2057 sst_dsp_ipc_msg_tx(ipc->dsp, msg->tx.header);
2046} 2058}
2047 2059
2048static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text) 2060static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
@@ -2063,7 +2075,7 @@ static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
2063static void hsw_tx_data_copy(struct ipc_message *msg, char *tx_data, 2075static void hsw_tx_data_copy(struct ipc_message *msg, char *tx_data,
2064 size_t tx_size) 2076 size_t tx_size)
2065{ 2077{
2066 memcpy(msg->tx_data, tx_data, tx_size); 2078 memcpy(msg->tx.data, tx_data, tx_size);
2067} 2079}
2068 2080
2069static u64 hsw_reply_msg_match(u64 header, u64 *mask) 2081static u64 hsw_reply_msg_match(u64 header, u64 *mask)
diff --git a/sound/soc/intel/skylake/Makefile b/sound/soc/intel/skylake/Makefile
index 86f6e1d801af..48544ff1a3e6 100644
--- a/sound/soc/intel/skylake/Makefile
+++ b/sound/soc/intel/skylake/Makefile
@@ -1,6 +1,7 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o \ 2snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o skl-topology.o \
3skl-topology.o 3 skl-sst-ipc.o skl-sst-dsp.o cnl-sst-dsp.o skl-sst-cldma.o \
4 skl-sst.o bxt-sst.o cnl-sst.o skl-sst-utils.o
4 5
5ifdef CONFIG_DEBUG_FS 6ifdef CONFIG_DEBUG_FS
6 snd-soc-skl-objs += skl-debug.o 7 snd-soc-skl-objs += skl-debug.o
@@ -8,13 +9,6 @@ endif
8 9
9obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o 10obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o
10 11
11# Skylake IPC Support
12snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o cnl-sst-dsp.o \
13 skl-sst-cldma.o skl-sst.o bxt-sst.o cnl-sst.o \
14 skl-sst-utils.o
15
16obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl-ipc.o
17
18#Skylake Clock device support 12#Skylake Clock device support
19snd-soc-skl-ssp-clk-objs := skl-ssp-clk.o 13snd-soc-skl-ssp-clk-objs := skl-ssp-clk.o
20 14
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
index 46d5159cf905..92a82e6b5fe6 100644
--- a/sound/soc/intel/skylake/bxt-sst.c
+++ b/sound/soc/intel/skylake/bxt-sst.c
@@ -14,7 +14,7 @@
14 14
15#include "../common/sst-dsp.h" 15#include "../common/sst-dsp.h"
16#include "../common/sst-dsp-priv.h" 16#include "../common/sst-dsp-priv.h"
17#include "skl-sst-ipc.h" 17#include "skl.h"
18 18
19#define BXT_BASEFW_TIMEOUT 3000 19#define BXT_BASEFW_TIMEOUT 3000
20#define BXT_INIT_TIMEOUT 300 20#define BXT_INIT_TIMEOUT 300
@@ -49,7 +49,7 @@ static int
49bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) 49bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
50{ 50{
51 struct snd_dma_buffer dmab; 51 struct snd_dma_buffer dmab;
52 struct skl_sst *skl = ctx->thread_context; 52 struct skl_dev *skl = ctx->thread_context;
53 struct firmware stripped_fw; 53 struct firmware stripped_fw;
54 int ret = 0, i, dma_id, stream_tag; 54 int ret = 0, i, dma_id, stream_tag;
55 55
@@ -184,7 +184,7 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
184static int bxt_load_base_firmware(struct sst_dsp *ctx) 184static int bxt_load_base_firmware(struct sst_dsp *ctx)
185{ 185{
186 struct firmware stripped_fw; 186 struct firmware stripped_fw;
187 struct skl_sst *skl = ctx->thread_context; 187 struct skl_dev *skl = ctx->thread_context;
188 int ret, i; 188 int ret, i;
189 189
190 if (ctx->fw == NULL) { 190 if (ctx->fw == NULL) {
@@ -268,7 +268,7 @@ sst_load_base_firmware_failed:
268 */ 268 */
269static int bxt_d0i3_target_state(struct sst_dsp *ctx) 269static int bxt_d0i3_target_state(struct sst_dsp *ctx)
270{ 270{
271 struct skl_sst *skl = ctx->thread_context; 271 struct skl_dev *skl = ctx->thread_context;
272 struct skl_d0i3_data *d0i3 = &skl->d0i3; 272 struct skl_d0i3_data *d0i3 = &skl->d0i3;
273 273
274 if (skl->cores.state[SKL_DSP_CORE0_ID] != SKL_DSP_RUNNING) 274 if (skl->cores.state[SKL_DSP_CORE0_ID] != SKL_DSP_RUNNING)
@@ -288,8 +288,8 @@ static void bxt_set_dsp_D0i3(struct work_struct *work)
288{ 288{
289 int ret; 289 int ret;
290 struct skl_ipc_d0ix_msg msg; 290 struct skl_ipc_d0ix_msg msg;
291 struct skl_sst *skl = container_of(work, 291 struct skl_dev *skl = container_of(work,
292 struct skl_sst, d0i3.work.work); 292 struct skl_dev, d0i3.work.work);
293 struct sst_dsp *ctx = skl->dsp; 293 struct sst_dsp *ctx = skl->dsp;
294 struct skl_d0i3_data *d0i3 = &skl->d0i3; 294 struct skl_d0i3_data *d0i3 = &skl->d0i3;
295 int target_state; 295 int target_state;
@@ -331,7 +331,7 @@ static void bxt_set_dsp_D0i3(struct work_struct *work)
331 331
332static int bxt_schedule_dsp_D0i3(struct sst_dsp *ctx) 332static int bxt_schedule_dsp_D0i3(struct sst_dsp *ctx)
333{ 333{
334 struct skl_sst *skl = ctx->thread_context; 334 struct skl_dev *skl = ctx->thread_context;
335 struct skl_d0i3_data *d0i3 = &skl->d0i3; 335 struct skl_d0i3_data *d0i3 = &skl->d0i3;
336 336
337 /* Schedule D0i3 only if the usecase ref counts are appropriate */ 337 /* Schedule D0i3 only if the usecase ref counts are appropriate */
@@ -350,7 +350,7 @@ static int bxt_set_dsp_D0i0(struct sst_dsp *ctx)
350{ 350{
351 int ret; 351 int ret;
352 struct skl_ipc_d0ix_msg msg; 352 struct skl_ipc_d0ix_msg msg;
353 struct skl_sst *skl = ctx->thread_context; 353 struct skl_dev *skl = ctx->thread_context;
354 354
355 dev_dbg(ctx->dev, "In %s:\n", __func__); 355 dev_dbg(ctx->dev, "In %s:\n", __func__);
356 356
@@ -389,7 +389,7 @@ static int bxt_set_dsp_D0i0(struct sst_dsp *ctx)
389 389
390static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) 390static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
391{ 391{
392 struct skl_sst *skl = ctx->thread_context; 392 struct skl_dev *skl = ctx->thread_context;
393 int ret; 393 int ret;
394 struct skl_ipc_dxstate_info dx; 394 struct skl_ipc_dxstate_info dx;
395 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); 395 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
@@ -486,7 +486,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
486{ 486{
487 int ret; 487 int ret;
488 struct skl_ipc_dxstate_info dx; 488 struct skl_ipc_dxstate_info dx;
489 struct skl_sst *skl = ctx->thread_context; 489 struct skl_dev *skl = ctx->thread_context;
490 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); 490 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
491 491
492 dx.core_mask = core_mask; 492 dx.core_mask = core_mask;
@@ -548,9 +548,9 @@ static struct sst_dsp_device skl_dev = {
548 548
549int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 549int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
550 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 550 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
551 struct skl_sst **dsp) 551 struct skl_dev **dsp)
552{ 552{
553 struct skl_sst *skl; 553 struct skl_dev *skl;
554 struct sst_dsp *sst; 554 struct sst_dsp *sst;
555 int ret; 555 int ret;
556 556
@@ -591,10 +591,10 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
591} 591}
592EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); 592EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
593 593
594int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx) 594int bxt_sst_init_fw(struct device *dev, struct skl_dev *skl)
595{ 595{
596 int ret; 596 int ret;
597 struct sst_dsp *sst = ctx->dsp; 597 struct sst_dsp *sst = skl->dsp;
598 598
599 ret = sst->fw_ops.load_fw(sst); 599 ret = sst->fw_ops.load_fw(sst);
600 if (ret < 0) { 600 if (ret < 0) {
@@ -604,29 +604,29 @@ int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx)
604 604
605 skl_dsp_init_core_state(sst); 605 skl_dsp_init_core_state(sst);
606 606
607 if (ctx->lib_count > 1) { 607 if (skl->lib_count > 1) {
608 ret = sst->fw_ops.load_library(sst, ctx->lib_info, 608 ret = sst->fw_ops.load_library(sst, skl->lib_info,
609 ctx->lib_count); 609 skl->lib_count);
610 if (ret < 0) { 610 if (ret < 0) {
611 dev_err(dev, "Load Library failed : %x\n", ret); 611 dev_err(dev, "Load Library failed : %x\n", ret);
612 return ret; 612 return ret;
613 } 613 }
614 } 614 }
615 ctx->is_first_boot = false; 615 skl->is_first_boot = false;
616 616
617 return 0; 617 return 0;
618} 618}
619EXPORT_SYMBOL_GPL(bxt_sst_init_fw); 619EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
620 620
621void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 621void bxt_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl)
622{ 622{
623 623
624 skl_release_library(ctx->lib_info, ctx->lib_count); 624 skl_release_library(skl->lib_info, skl->lib_count);
625 if (ctx->dsp->fw) 625 if (skl->dsp->fw)
626 release_firmware(ctx->dsp->fw); 626 release_firmware(skl->dsp->fw);
627 skl_freeup_uuid_list(ctx); 627 skl_freeup_uuid_list(skl);
628 skl_ipc_free(&ctx->ipc); 628 skl_ipc_free(&skl->ipc);
629 ctx->dsp->ops->free(ctx->dsp); 629 skl->dsp->ops->free(skl->dsp);
630} 630}
631EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup); 631EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup);
632 632
diff --git a/sound/soc/intel/skylake/cnl-sst-dsp.h b/sound/soc/intel/skylake/cnl-sst-dsp.h
index 426515faab52..7bd4d2a8fdfa 100644
--- a/sound/soc/intel/skylake/cnl-sst-dsp.h
+++ b/sound/soc/intel/skylake/cnl-sst-dsp.h
@@ -9,7 +9,6 @@
9#define __CNL_SST_DSP_H__ 9#define __CNL_SST_DSP_H__
10 10
11struct sst_dsp; 11struct sst_dsp;
12struct skl_sst;
13struct sst_dsp_device; 12struct sst_dsp_device;
14struct sst_generic_ipc; 13struct sst_generic_ipc;
15 14
@@ -97,8 +96,8 @@ void cnl_ipc_free(struct sst_generic_ipc *ipc);
97 96
98int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 97int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
99 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 98 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
100 struct skl_sst **dsp); 99 struct skl_dev **dsp);
101int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx); 100int cnl_sst_init_fw(struct device *dev, struct skl_dev *skl);
102void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 101void cnl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl);
103 102
104#endif /*__CNL_SST_DSP_H__*/ 103#endif /*__CNL_SST_DSP_H__*/
diff --git a/sound/soc/intel/skylake/cnl-sst.c b/sound/soc/intel/skylake/cnl-sst.c
index f2c09fa6ea40..4f64f097e9ae 100644
--- a/sound/soc/intel/skylake/cnl-sst.c
+++ b/sound/soc/intel/skylake/cnl-sst.c
@@ -24,8 +24,7 @@
24#include "../common/sst-dsp-priv.h" 24#include "../common/sst-dsp-priv.h"
25#include "../common/sst-ipc.h" 25#include "../common/sst-ipc.h"
26#include "cnl-sst-dsp.h" 26#include "cnl-sst-dsp.h"
27#include "skl-sst-dsp.h" 27#include "skl.h"
28#include "skl-sst-ipc.h"
29 28
30#define CNL_FW_ROM_INIT 0x1 29#define CNL_FW_ROM_INIT 0x1
31#define CNL_FW_INIT 0x5 30#define CNL_FW_INIT 0x5
@@ -109,7 +108,7 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
109static int cnl_load_base_firmware(struct sst_dsp *ctx) 108static int cnl_load_base_firmware(struct sst_dsp *ctx)
110{ 109{
111 struct firmware stripped_fw; 110 struct firmware stripped_fw;
112 struct skl_sst *cnl = ctx->thread_context; 111 struct skl_dev *cnl = ctx->thread_context;
113 int ret; 112 int ret;
114 113
115 if (!ctx->fw) { 114 if (!ctx->fw) {
@@ -167,7 +166,7 @@ cnl_load_base_firmware_failed:
167 166
168static int cnl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) 167static int cnl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
169{ 168{
170 struct skl_sst *cnl = ctx->thread_context; 169 struct skl_dev *cnl = ctx->thread_context;
171 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); 170 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
172 struct skl_ipc_dxstate_info dx; 171 struct skl_ipc_dxstate_info dx;
173 int ret; 172 int ret;
@@ -229,7 +228,7 @@ err:
229 228
230static int cnl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) 229static int cnl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
231{ 230{
232 struct skl_sst *cnl = ctx->thread_context; 231 struct skl_dev *cnl = ctx->thread_context;
233 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); 232 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
234 struct skl_ipc_dxstate_info dx; 233 struct skl_ipc_dxstate_info dx;
235 int ret; 234 int ret;
@@ -293,7 +292,7 @@ static struct sst_ops cnl_ops = {
293static irqreturn_t cnl_dsp_irq_thread_handler(int irq, void *context) 292static irqreturn_t cnl_dsp_irq_thread_handler(int irq, void *context)
294{ 293{
295 struct sst_dsp *dsp = context; 294 struct sst_dsp *dsp = context;
296 struct skl_sst *cnl = sst_dsp_get_thread_context(dsp); 295 struct skl_dev *cnl = sst_dsp_get_thread_context(dsp);
297 struct sst_generic_ipc *ipc = &cnl->ipc; 296 struct sst_generic_ipc *ipc = &cnl->ipc;
298 struct skl_ipc_header header = {0}; 297 struct skl_ipc_header header = {0};
299 u32 hipcida, hipctdr, hipctdd; 298 u32 hipcida, hipctdr, hipctdd;
@@ -367,10 +366,10 @@ static struct sst_dsp_device cnl_dev = {
367 366
368static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) 367static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
369{ 368{
370 struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header); 369 struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header);
371 370
372 if (msg->tx_size) 371 if (msg->tx.size)
373 sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); 372 sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
374 sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD, 373 sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD,
375 header->extension); 374 header->extension);
376 sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR, 375 sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR,
@@ -386,7 +385,7 @@ static bool cnl_ipc_is_dsp_busy(struct sst_dsp *dsp)
386 return (hipcidr & CNL_ADSP_REG_HIPCIDR_BUSY); 385 return (hipcidr & CNL_ADSP_REG_HIPCIDR_BUSY);
387} 386}
388 387
389static int cnl_ipc_init(struct device *dev, struct skl_sst *cnl) 388static int cnl_ipc_init(struct device *dev, struct skl_dev *cnl)
390{ 389{
391 struct sst_generic_ipc *ipc; 390 struct sst_generic_ipc *ipc;
392 int err; 391 int err;
@@ -415,9 +414,9 @@ static int cnl_ipc_init(struct device *dev, struct skl_sst *cnl)
415 414
416int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 415int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
417 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 416 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
418 struct skl_sst **dsp) 417 struct skl_dev **dsp)
419{ 418{
420 struct skl_sst *cnl; 419 struct skl_dev *cnl;
421 struct sst_dsp *sst; 420 struct sst_dsp *sst;
422 int ret; 421 int ret;
423 422
@@ -454,12 +453,12 @@ int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
454} 453}
455EXPORT_SYMBOL_GPL(cnl_sst_dsp_init); 454EXPORT_SYMBOL_GPL(cnl_sst_dsp_init);
456 455
457int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx) 456int cnl_sst_init_fw(struct device *dev, struct skl_dev *skl)
458{ 457{
459 int ret; 458 int ret;
460 struct sst_dsp *sst = ctx->dsp; 459 struct sst_dsp *sst = skl->dsp;
461 460
462 ret = ctx->dsp->fw_ops.load_fw(sst); 461 ret = skl->dsp->fw_ops.load_fw(sst);
463 if (ret < 0) { 462 if (ret < 0) {
464 dev_err(dev, "load base fw failed: %d", ret); 463 dev_err(dev, "load base fw failed: %d", ret);
465 return ret; 464 return ret;
@@ -467,21 +466,21 @@ int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
467 466
468 skl_dsp_init_core_state(sst); 467 skl_dsp_init_core_state(sst);
469 468
470 ctx->is_first_boot = false; 469 skl->is_first_boot = false;
471 470
472 return 0; 471 return 0;
473} 472}
474EXPORT_SYMBOL_GPL(cnl_sst_init_fw); 473EXPORT_SYMBOL_GPL(cnl_sst_init_fw);
475 474
476void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 475void cnl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl)
477{ 476{
478 if (ctx->dsp->fw) 477 if (skl->dsp->fw)
479 release_firmware(ctx->dsp->fw); 478 release_firmware(skl->dsp->fw);
480 479
481 skl_freeup_uuid_list(ctx); 480 skl_freeup_uuid_list(skl);
482 cnl_ipc_free(&ctx->ipc); 481 cnl_ipc_free(&skl->ipc);
483 482
484 ctx->dsp->ops->free(ctx->dsp); 483 skl->dsp->ops->free(skl->dsp);
485} 484}
486EXPORT_SYMBOL_GPL(cnl_sst_dsp_cleanup); 485EXPORT_SYMBOL_GPL(cnl_sst_dsp_cleanup);
487 486
diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c
index b28a9c2b0380..3466675f2678 100644
--- a/sound/soc/intel/skylake/skl-debug.c
+++ b/sound/soc/intel/skylake/skl-debug.c
@@ -20,7 +20,7 @@
20#define FW_REG_SIZE 0x60 20#define FW_REG_SIZE 0x60
21 21
22struct skl_debug { 22struct skl_debug {
23 struct skl *skl; 23 struct skl_dev *skl;
24 struct device *dev; 24 struct device *dev;
25 25
26 struct dentry *fs; 26 struct dentry *fs;
@@ -66,6 +66,8 @@ static ssize_t module_read(struct file *file, char __user *user_buf,
66 size_t count, loff_t *ppos) 66 size_t count, loff_t *ppos)
67{ 67{
68 struct skl_module_cfg *mconfig = file->private_data; 68 struct skl_module_cfg *mconfig = file->private_data;
69 struct skl_module *module = mconfig->module;
70 struct skl_module_res *res = &module->resources[mconfig->res_idx];
69 char *buf; 71 char *buf;
70 ssize_t ret; 72 ssize_t ret;
71 73
@@ -79,8 +81,8 @@ static ssize_t module_read(struct file *file, char __user *user_buf,
79 mconfig->id.pvt_id); 81 mconfig->id.pvt_id);
80 82
81 ret += snprintf(buf + ret, MOD_BUF - ret, 83 ret += snprintf(buf + ret, MOD_BUF - ret,
82 "Resources:\n\tMCPS %#x\n\tIBS %#x\n\tOBS %#x\t\n", 84 "Resources:\n\tCPC %#x\n\tIBS %#x\n\tOBS %#x\t\n",
83 mconfig->mcps, mconfig->ibs, mconfig->obs); 85 res->cpc, res->ibs, res->obs);
84 86
85 ret += snprintf(buf + ret, MOD_BUF - ret, 87 ret += snprintf(buf + ret, MOD_BUF - ret,
86 "Module data:\n\tCore %d\n\tIn queue %d\n\t" 88 "Module data:\n\tCore %d\n\tIn queue %d\n\t"
@@ -162,17 +164,15 @@ void skl_debug_init_module(struct skl_debug *d,
162 struct snd_soc_dapm_widget *w, 164 struct snd_soc_dapm_widget *w,
163 struct skl_module_cfg *mconfig) 165 struct skl_module_cfg *mconfig)
164{ 166{
165 if (!debugfs_create_file(w->name, 0444, 167 debugfs_create_file(w->name, 0444, d->modules, mconfig,
166 d->modules, mconfig, 168 &mcfg_fops);
167 &mcfg_fops))
168 dev_err(d->dev, "%s: module debugfs init failed\n", w->name);
169} 169}
170 170
171static ssize_t fw_softreg_read(struct file *file, char __user *user_buf, 171static ssize_t fw_softreg_read(struct file *file, char __user *user_buf,
172 size_t count, loff_t *ppos) 172 size_t count, loff_t *ppos)
173{ 173{
174 struct skl_debug *d = file->private_data; 174 struct skl_debug *d = file->private_data;
175 struct sst_dsp *sst = d->skl->skl_sst->dsp; 175 struct sst_dsp *sst = d->skl->dsp;
176 size_t w0_stat_sz = sst->addr.w0_stat_sz; 176 size_t w0_stat_sz = sst->addr.w0_stat_sz;
177 void __iomem *in_base = sst->mailbox.in_base; 177 void __iomem *in_base = sst->mailbox.in_base;
178 void __iomem *fw_reg_addr; 178 void __iomem *fw_reg_addr;
@@ -213,7 +213,7 @@ static const struct file_operations soft_regs_ctrl_fops = {
213 .llseek = default_llseek, 213 .llseek = default_llseek,
214}; 214};
215 215
216struct skl_debug *skl_debugfs_init(struct skl *skl) 216struct skl_debug *skl_debugfs_init(struct skl_dev *skl)
217{ 217{
218 struct skl_debug *d; 218 struct skl_debug *d;
219 219
@@ -222,37 +222,21 @@ struct skl_debug *skl_debugfs_init(struct skl *skl)
222 return NULL; 222 return NULL;
223 223
224 /* create the debugfs dir with platform component's debugfs as parent */ 224 /* create the debugfs dir with platform component's debugfs as parent */
225 d->fs = debugfs_create_dir("dsp", 225 d->fs = debugfs_create_dir("dsp", skl->component->debugfs_root);
226 skl->component->debugfs_root);
227 if (IS_ERR(d->fs) || !d->fs) {
228 dev_err(&skl->pci->dev, "debugfs root creation failed\n");
229 return NULL;
230 }
231 226
232 d->skl = skl; 227 d->skl = skl;
233 d->dev = &skl->pci->dev; 228 d->dev = &skl->pci->dev;
234 229
235 /* now create the module dir */ 230 /* now create the module dir */
236 d->modules = debugfs_create_dir("modules", d->fs); 231 d->modules = debugfs_create_dir("modules", d->fs);
237 if (IS_ERR(d->modules) || !d->modules) {
238 dev_err(&skl->pci->dev, "modules debugfs create failed\n");
239 goto err;
240 }
241 232
242 if (!debugfs_create_file("fw_soft_regs_rd", 0444, d->fs, d, 233 debugfs_create_file("fw_soft_regs_rd", 0444, d->fs, d,
243 &soft_regs_ctrl_fops)) { 234 &soft_regs_ctrl_fops);
244 dev_err(d->dev, "fw soft regs control debugfs init failed\n");
245 goto err;
246 }
247 235
248 return d; 236 return d;
249
250err:
251 debugfs_remove_recursive(d->fs);
252 return NULL;
253} 237}
254 238
255void skl_debugfs_exit(struct skl *skl) 239void skl_debugfs_exit(struct skl_dev *skl)
256{ 240{
257 struct skl_debug *d = skl->debugfs; 241 struct skl_debug *d = skl->debugfs;
258 242
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index febc070839e0..476ef1897961 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -25,29 +25,18 @@
25static int skl_alloc_dma_buf(struct device *dev, 25static int skl_alloc_dma_buf(struct device *dev,
26 struct snd_dma_buffer *dmab, size_t size) 26 struct snd_dma_buffer *dmab, size_t size)
27{ 27{
28 struct hdac_bus *bus = dev_get_drvdata(dev); 28 return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, dmab);
29
30 if (!bus)
31 return -ENODEV;
32
33 return bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, size, dmab);
34} 29}
35 30
36static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab) 31static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab)
37{ 32{
38 struct hdac_bus *bus = dev_get_drvdata(dev); 33 snd_dma_free_pages(dmab);
39
40 if (!bus)
41 return -ENODEV;
42
43 bus->io_ops->dma_free_pages(bus, dmab);
44
45 return 0; 34 return 0;
46} 35}
47 36
48#define SKL_ASTATE_PARAM_ID 4 37#define SKL_ASTATE_PARAM_ID 4
49 38
50void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data) 39void skl_dsp_set_astate_cfg(struct skl_dev *skl, u32 cnt, void *data)
51{ 40{
52 struct skl_ipc_large_config_msg msg = {0}; 41 struct skl_ipc_large_config_msg msg = {0};
53 42
@@ -55,25 +44,7 @@ void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data)
55 msg.param_data_size = (cnt * sizeof(struct skl_astate_param) + 44 msg.param_data_size = (cnt * sizeof(struct skl_astate_param) +
56 sizeof(cnt)); 45 sizeof(cnt));
57 46
58 skl_ipc_set_large_config(&ctx->ipc, &msg, data); 47 skl_ipc_set_large_config(&skl->ipc, &msg, data);
59}
60
61#define NOTIFICATION_PARAM_ID 3
62#define NOTIFICATION_MASK 0xf
63
64/* disable notfication for underruns/overruns from firmware module */
65void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable)
66{
67 struct notification_mask mask;
68 struct skl_ipc_large_config_msg msg = {0};
69
70 mask.notify = NOTIFICATION_MASK;
71 mask.enable = enable;
72
73 msg.large_param_id = NOTIFICATION_PARAM_ID;
74 msg.param_data_size = sizeof(mask);
75
76 skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)&mask);
77} 48}
78 49
79static int skl_dsp_setup_spib(struct device *dev, unsigned int size, 50static int skl_dsp_setup_spib(struct device *dev, unsigned int size,
@@ -277,7 +248,7 @@ const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id)
277 return NULL; 248 return NULL;
278} 249}
279 250
280int skl_init_dsp(struct skl *skl) 251int skl_init_dsp(struct skl_dev *skl)
281{ 252{
282 void __iomem *mmio_base; 253 void __iomem *mmio_base;
283 struct hdac_bus *bus = skl_to_bus(skl); 254 struct hdac_bus *bus = skl_to_bus(skl);
@@ -307,13 +278,13 @@ int skl_init_dsp(struct skl *skl)
307 loader_ops = ops->loader_ops(); 278 loader_ops = ops->loader_ops();
308 ret = ops->init(bus->dev, mmio_base, irq, 279 ret = ops->init(bus->dev, mmio_base, irq,
309 skl->fw_name, loader_ops, 280 skl->fw_name, loader_ops,
310 &skl->skl_sst); 281 &skl);
311 282
312 if (ret < 0) 283 if (ret < 0)
313 goto unmap_mmio; 284 goto unmap_mmio;
314 285
315 skl->skl_sst->dsp_ops = ops; 286 skl->dsp_ops = ops;
316 cores = &skl->skl_sst->cores; 287 cores = &skl->cores;
317 cores->count = ops->num_cores; 288 cores->count = ops->num_cores;
318 289
319 cores->state = kcalloc(cores->count, sizeof(*cores->state), GFP_KERNEL); 290 cores->state = kcalloc(cores->count, sizeof(*cores->state), GFP_KERNEL);
@@ -342,21 +313,20 @@ unmap_mmio:
342 return ret; 313 return ret;
343} 314}
344 315
345int skl_free_dsp(struct skl *skl) 316int skl_free_dsp(struct skl_dev *skl)
346{ 317{
347 struct hdac_bus *bus = skl_to_bus(skl); 318 struct hdac_bus *bus = skl_to_bus(skl);
348 struct skl_sst *ctx = skl->skl_sst;
349 319
350 /* disable ppcap interrupt */ 320 /* disable ppcap interrupt */
351 snd_hdac_ext_bus_ppcap_int_enable(bus, false); 321 snd_hdac_ext_bus_ppcap_int_enable(bus, false);
352 322
353 ctx->dsp_ops->cleanup(bus->dev, ctx); 323 skl->dsp_ops->cleanup(bus->dev, skl);
354 324
355 kfree(ctx->cores.state); 325 kfree(skl->cores.state);
356 kfree(ctx->cores.usage_count); 326 kfree(skl->cores.usage_count);
357 327
358 if (ctx->dsp->addr.lpe) 328 if (skl->dsp->addr.lpe)
359 iounmap(ctx->dsp->addr.lpe); 329 iounmap(skl->dsp->addr.lpe);
360 330
361 return 0; 331 return 0;
362} 332}
@@ -368,15 +338,14 @@ int skl_free_dsp(struct skl *skl)
368 * mode during system suspend. In the case of normal suspend, cancel 338 * mode during system suspend. In the case of normal suspend, cancel
369 * any pending D0i3 work. 339 * any pending D0i3 work.
370 */ 340 */
371int skl_suspend_late_dsp(struct skl *skl) 341int skl_suspend_late_dsp(struct skl_dev *skl)
372{ 342{
373 struct skl_sst *ctx = skl->skl_sst;
374 struct delayed_work *dwork; 343 struct delayed_work *dwork;
375 344
376 if (!ctx) 345 if (!skl)
377 return 0; 346 return 0;
378 347
379 dwork = &ctx->d0i3.work; 348 dwork = &skl->d0i3.work;
380 349
381 if (dwork->work.func) { 350 if (dwork->work.func) {
382 if (skl->supend_active) 351 if (skl->supend_active)
@@ -388,9 +357,8 @@ int skl_suspend_late_dsp(struct skl *skl)
388 return 0; 357 return 0;
389} 358}
390 359
391int skl_suspend_dsp(struct skl *skl) 360int skl_suspend_dsp(struct skl_dev *skl)
392{ 361{
393 struct skl_sst *ctx = skl->skl_sst;
394 struct hdac_bus *bus = skl_to_bus(skl); 362 struct hdac_bus *bus = skl_to_bus(skl);
395 int ret; 363 int ret;
396 364
@@ -398,7 +366,7 @@ int skl_suspend_dsp(struct skl *skl)
398 if (!bus->ppcap) 366 if (!bus->ppcap)
399 return 0; 367 return 0;
400 368
401 ret = skl_dsp_sleep(ctx->dsp); 369 ret = skl_dsp_sleep(skl->dsp);
402 if (ret < 0) 370 if (ret < 0)
403 return ret; 371 return ret;
404 372
@@ -409,9 +377,8 @@ int skl_suspend_dsp(struct skl *skl)
409 return 0; 377 return 0;
410} 378}
411 379
412int skl_resume_dsp(struct skl *skl) 380int skl_resume_dsp(struct skl_dev *skl)
413{ 381{
414 struct skl_sst *ctx = skl->skl_sst;
415 struct hdac_bus *bus = skl_to_bus(skl); 382 struct hdac_bus *bus = skl_to_bus(skl);
416 int ret; 383 int ret;
417 384
@@ -424,26 +391,24 @@ int skl_resume_dsp(struct skl *skl)
424 snd_hdac_ext_bus_ppcap_int_enable(bus, true); 391 snd_hdac_ext_bus_ppcap_int_enable(bus, true);
425 392
426 /* check if DSP 1st boot is done */ 393 /* check if DSP 1st boot is done */
427 if (skl->skl_sst->is_first_boot) 394 if (skl->is_first_boot)
428 return 0; 395 return 0;
429 396
430 /* 397 /*
431 * Disable dynamic clock and power gating during firmware 398 * Disable dynamic clock and power gating during firmware
432 * and library download 399 * and library download
433 */ 400 */
434 ctx->enable_miscbdcge(ctx->dev, false); 401 skl->enable_miscbdcge(skl->dev, false);
435 ctx->clock_power_gating(ctx->dev, false); 402 skl->clock_power_gating(skl->dev, false);
436 403
437 ret = skl_dsp_wake(ctx->dsp); 404 ret = skl_dsp_wake(skl->dsp);
438 ctx->enable_miscbdcge(ctx->dev, true); 405 skl->enable_miscbdcge(skl->dev, true);
439 ctx->clock_power_gating(ctx->dev, true); 406 skl->clock_power_gating(skl->dev, true);
440 if (ret < 0) 407 if (ret < 0)
441 return ret; 408 return ret;
442 409
443 skl_dsp_enable_notification(skl->skl_sst, false);
444
445 if (skl->cfg.astate_cfg != NULL) { 410 if (skl->cfg.astate_cfg != NULL) {
446 skl_dsp_set_astate_cfg(skl->skl_sst, skl->cfg.astate_cfg->count, 411 skl_dsp_set_astate_cfg(skl, skl->cfg.astate_cfg->count,
447 skl->cfg.astate_cfg); 412 skl->cfg.astate_cfg);
448 } 413 }
449 return ret; 414 return ret;
@@ -476,7 +441,7 @@ enum skl_bitdepth skl_get_bit_depth(int params)
476 * which are read from widget information passed through topology binary 441 * which are read from widget information passed through topology binary
477 * This is send when we create a module with INIT_INSTANCE IPC msg 442 * This is send when we create a module with INIT_INSTANCE IPC msg
478 */ 443 */
479static void skl_set_base_module_format(struct skl_sst *ctx, 444static void skl_set_base_module_format(struct skl_dev *skl,
480 struct skl_module_cfg *mconfig, 445 struct skl_module_cfg *mconfig,
481 struct skl_base_cfg *base_cfg) 446 struct skl_base_cfg *base_cfg)
482{ 447{
@@ -493,7 +458,7 @@ static void skl_set_base_module_format(struct skl_sst *ctx,
493 base_cfg->audio_fmt.ch_cfg = format->ch_cfg; 458 base_cfg->audio_fmt.ch_cfg = format->ch_cfg;
494 base_cfg->audio_fmt.sample_type = format->sample_type; 459 base_cfg->audio_fmt.sample_type = format->sample_type;
495 460
496 dev_dbg(ctx->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n", 461 dev_dbg(skl->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n",
497 format->bit_depth, format->valid_bit_depth, 462 format->bit_depth, format->valid_bit_depth,
498 format->ch_cfg); 463 format->ch_cfg);
499 464
@@ -501,7 +466,7 @@ static void skl_set_base_module_format(struct skl_sst *ctx,
501 466
502 base_cfg->audio_fmt.interleaving = format->interleaving_style; 467 base_cfg->audio_fmt.interleaving = format->interleaving_style;
503 468
504 base_cfg->cps = res->cps; 469 base_cfg->cpc = res->cpc;
505 base_cfg->ibs = res->ibs; 470 base_cfg->ibs = res->ibs;
506 base_cfg->obs = res->obs; 471 base_cfg->obs = res->obs;
507 base_cfg->is_pages = res->is_pages; 472 base_cfg->is_pages = res->is_pages;
@@ -530,7 +495,7 @@ static void skl_copy_copier_caps(struct skl_module_cfg *mconfig,
530 * Calculate the gatewat settings required for copier module, type of 495 * Calculate the gatewat settings required for copier module, type of
531 * gateway and index of gateway to use 496 * gateway and index of gateway to use
532 */ 497 */
533static u32 skl_get_node_id(struct skl_sst *ctx, 498static u32 skl_get_node_id(struct skl_dev *skl,
534 struct skl_module_cfg *mconfig) 499 struct skl_module_cfg *mconfig)
535{ 500{
536 union skl_connector_node_id node_id = {0}; 501 union skl_connector_node_id node_id = {0};
@@ -587,16 +552,15 @@ static u32 skl_get_node_id(struct skl_sst *ctx,
587 return node_id.val; 552 return node_id.val;
588} 553}
589 554
590static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, 555static void skl_setup_cpr_gateway_cfg(struct skl_dev *skl,
591 struct skl_module_cfg *mconfig, 556 struct skl_module_cfg *mconfig,
592 struct skl_cpr_cfg *cpr_mconfig) 557 struct skl_cpr_cfg *cpr_mconfig)
593{ 558{
594 u32 dma_io_buf; 559 u32 dma_io_buf;
595 struct skl_module_res *res; 560 struct skl_module_res *res;
596 int res_idx = mconfig->res_idx; 561 int res_idx = mconfig->res_idx;
597 struct skl *skl = get_skl_ctx(ctx->dev);
598 562
599 cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(ctx, mconfig); 563 cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(skl, mconfig);
600 564
601 if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) { 565 if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) {
602 cpr_mconfig->cpr_feature_mask = 0; 566 cpr_mconfig->cpr_feature_mask = 0;
@@ -627,7 +591,7 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
627 break; 591 break;
628 592
629 default: 593 default:
630 dev_warn(ctx->dev, "wrong connection type: %d\n", 594 dev_warn(skl->dev, "wrong connection type: %d\n",
631 mconfig->hw_conn_type); 595 mconfig->hw_conn_type);
632 return; 596 return;
633 } 597 }
@@ -653,7 +617,7 @@ skip_buf_size_calc:
653#define DMA_CONTROL_ID 5 617#define DMA_CONTROL_ID 5
654#define DMA_I2S_BLOB_SIZE 21 618#define DMA_I2S_BLOB_SIZE 21
655 619
656int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps, 620int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps,
657 u32 caps_size, u32 node_id) 621 u32 caps_size, u32 node_id)
658{ 622{
659 struct skl_dma_control *dma_ctrl; 623 struct skl_dma_control *dma_ctrl;
@@ -686,14 +650,14 @@ int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
686 650
687 memcpy(dma_ctrl->config_data, caps, caps_size); 651 memcpy(dma_ctrl->config_data, caps, caps_size);
688 652
689 err = skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)dma_ctrl); 653 err = skl_ipc_set_large_config(&skl->ipc, &msg, (u32 *)dma_ctrl);
690 654
691 kfree(dma_ctrl); 655 kfree(dma_ctrl);
692 return err; 656 return err;
693} 657}
694EXPORT_SYMBOL_GPL(skl_dsp_set_dma_control); 658EXPORT_SYMBOL_GPL(skl_dsp_set_dma_control);
695 659
696static void skl_setup_out_format(struct skl_sst *ctx, 660static void skl_setup_out_format(struct skl_dev *skl,
697 struct skl_module_cfg *mconfig, 661 struct skl_module_cfg *mconfig,
698 struct skl_audio_data_format *out_fmt) 662 struct skl_audio_data_format *out_fmt)
699{ 663{
@@ -711,7 +675,7 @@ static void skl_setup_out_format(struct skl_sst *ctx,
711 out_fmt->interleaving = format->interleaving_style; 675 out_fmt->interleaving = format->interleaving_style;
712 out_fmt->sample_type = format->sample_type; 676 out_fmt->sample_type = format->sample_type;
713 677
714 dev_dbg(ctx->dev, "copier out format chan=%d fre=%d bitdepth=%d\n", 678 dev_dbg(skl->dev, "copier out format chan=%d fre=%d bitdepth=%d\n",
715 out_fmt->number_of_channels, format->s_freq, format->bit_depth); 679 out_fmt->number_of_channels, format->s_freq, format->bit_depth);
716} 680}
717 681
@@ -720,7 +684,7 @@ static void skl_setup_out_format(struct skl_sst *ctx,
720 * configuration and the target frequency as extra parameter passed as src 684 * configuration and the target frequency as extra parameter passed as src
721 * config 685 * config
722 */ 686 */
723static void skl_set_src_format(struct skl_sst *ctx, 687static void skl_set_src_format(struct skl_dev *skl,
724 struct skl_module_cfg *mconfig, 688 struct skl_module_cfg *mconfig,
725 struct skl_src_module_cfg *src_mconfig) 689 struct skl_src_module_cfg *src_mconfig)
726{ 690{
@@ -728,7 +692,7 @@ static void skl_set_src_format(struct skl_sst *ctx,
728 struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx]; 692 struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx];
729 struct skl_module_fmt *fmt = &iface->outputs[0].fmt; 693 struct skl_module_fmt *fmt = &iface->outputs[0].fmt;
730 694
731 skl_set_base_module_format(ctx, mconfig, 695 skl_set_base_module_format(skl, mconfig,
732 (struct skl_base_cfg *)src_mconfig); 696 (struct skl_base_cfg *)src_mconfig);
733 697
734 src_mconfig->src_cfg = fmt->s_freq; 698 src_mconfig->src_cfg = fmt->s_freq;
@@ -739,7 +703,7 @@ static void skl_set_src_format(struct skl_sst *ctx,
739 * module configuration and channel configuration 703 * module configuration and channel configuration
740 * It also take coefficients and now we have defaults applied here 704 * It also take coefficients and now we have defaults applied here
741 */ 705 */
742static void skl_set_updown_mixer_format(struct skl_sst *ctx, 706static void skl_set_updown_mixer_format(struct skl_dev *skl,
743 struct skl_module_cfg *mconfig, 707 struct skl_module_cfg *mconfig,
744 struct skl_up_down_mixer_cfg *mixer_mconfig) 708 struct skl_up_down_mixer_cfg *mixer_mconfig)
745{ 709{
@@ -747,7 +711,7 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx,
747 struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx]; 711 struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx];
748 struct skl_module_fmt *fmt = &iface->outputs[0].fmt; 712 struct skl_module_fmt *fmt = &iface->outputs[0].fmt;
749 713
750 skl_set_base_module_format(ctx, mconfig, 714 skl_set_base_module_format(skl, mconfig,
751 (struct skl_base_cfg *)mixer_mconfig); 715 (struct skl_base_cfg *)mixer_mconfig);
752 mixer_mconfig->out_ch_cfg = fmt->ch_cfg; 716 mixer_mconfig->out_ch_cfg = fmt->ch_cfg;
753 mixer_mconfig->ch_map = fmt->ch_map; 717 mixer_mconfig->ch_map = fmt->ch_map;
@@ -760,17 +724,17 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx,
760 * format, gateway settings 724 * format, gateway settings
761 * copier_module_config is sent as input buffer with INIT_INSTANCE IPC msg 725 * copier_module_config is sent as input buffer with INIT_INSTANCE IPC msg
762 */ 726 */
763static void skl_set_copier_format(struct skl_sst *ctx, 727static void skl_set_copier_format(struct skl_dev *skl,
764 struct skl_module_cfg *mconfig, 728 struct skl_module_cfg *mconfig,
765 struct skl_cpr_cfg *cpr_mconfig) 729 struct skl_cpr_cfg *cpr_mconfig)
766{ 730{
767 struct skl_audio_data_format *out_fmt = &cpr_mconfig->out_fmt; 731 struct skl_audio_data_format *out_fmt = &cpr_mconfig->out_fmt;
768 struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)cpr_mconfig; 732 struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)cpr_mconfig;
769 733
770 skl_set_base_module_format(ctx, mconfig, base_cfg); 734 skl_set_base_module_format(skl, mconfig, base_cfg);
771 735
772 skl_setup_out_format(ctx, mconfig, out_fmt); 736 skl_setup_out_format(skl, mconfig, out_fmt);
773 skl_setup_cpr_gateway_cfg(ctx, mconfig, cpr_mconfig); 737 skl_setup_cpr_gateway_cfg(skl, mconfig, cpr_mconfig);
774} 738}
775 739
776/* 740/*
@@ -778,13 +742,13 @@ static void skl_set_copier_format(struct skl_sst *ctx,
778 * configuration and params 742 * configuration and params
779 */ 743 */
780 744
781static void skl_set_algo_format(struct skl_sst *ctx, 745static void skl_set_algo_format(struct skl_dev *skl,
782 struct skl_module_cfg *mconfig, 746 struct skl_module_cfg *mconfig,
783 struct skl_algo_cfg *algo_mcfg) 747 struct skl_algo_cfg *algo_mcfg)
784{ 748{
785 struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg; 749 struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg;
786 750
787 skl_set_base_module_format(ctx, mconfig, base_cfg); 751 skl_set_base_module_format(skl, mconfig, base_cfg);
788 752
789 if (mconfig->formats_config.caps_size == 0) 753 if (mconfig->formats_config.caps_size == 0)
790 return; 754 return;
@@ -802,7 +766,7 @@ static void skl_set_algo_format(struct skl_sst *ctx,
802 * Mic select module take base module configuration and out-format 766 * Mic select module take base module configuration and out-format
803 * configuration 767 * configuration
804 */ 768 */
805static void skl_set_base_outfmt_format(struct skl_sst *ctx, 769static void skl_set_base_outfmt_format(struct skl_dev *skl,
806 struct skl_module_cfg *mconfig, 770 struct skl_module_cfg *mconfig,
807 struct skl_base_outfmt_cfg *base_outfmt_mcfg) 771 struct skl_base_outfmt_cfg *base_outfmt_mcfg)
808{ 772{
@@ -810,11 +774,11 @@ static void skl_set_base_outfmt_format(struct skl_sst *ctx,
810 struct skl_base_cfg *base_cfg = 774 struct skl_base_cfg *base_cfg =
811 (struct skl_base_cfg *)base_outfmt_mcfg; 775 (struct skl_base_cfg *)base_outfmt_mcfg;
812 776
813 skl_set_base_module_format(ctx, mconfig, base_cfg); 777 skl_set_base_module_format(skl, mconfig, base_cfg);
814 skl_setup_out_format(ctx, mconfig, out_fmt); 778 skl_setup_out_format(skl, mconfig, out_fmt);
815} 779}
816 780
817static u16 skl_get_module_param_size(struct skl_sst *ctx, 781static u16 skl_get_module_param_size(struct skl_dev *skl,
818 struct skl_module_cfg *mconfig) 782 struct skl_module_cfg *mconfig)
819{ 783{
820 u16 param_size; 784 u16 param_size;
@@ -859,14 +823,14 @@ static u16 skl_get_module_param_size(struct skl_sst *ctx,
859 * base module format configuration 823 * base module format configuration
860 */ 824 */
861 825
862static int skl_set_module_format(struct skl_sst *ctx, 826static int skl_set_module_format(struct skl_dev *skl,
863 struct skl_module_cfg *module_config, 827 struct skl_module_cfg *module_config,
864 u16 *module_config_size, 828 u16 *module_config_size,
865 void **param_data) 829 void **param_data)
866{ 830{
867 u16 param_size; 831 u16 param_size;
868 832
869 param_size = skl_get_module_param_size(ctx, module_config); 833 param_size = skl_get_module_param_size(skl, module_config);
870 834
871 *param_data = kzalloc(param_size, GFP_KERNEL); 835 *param_data = kzalloc(param_size, GFP_KERNEL);
872 if (NULL == *param_data) 836 if (NULL == *param_data)
@@ -876,35 +840,36 @@ static int skl_set_module_format(struct skl_sst *ctx,
876 840
877 switch (module_config->m_type) { 841 switch (module_config->m_type) {
878 case SKL_MODULE_TYPE_COPIER: 842 case SKL_MODULE_TYPE_COPIER:
879 skl_set_copier_format(ctx, module_config, *param_data); 843 skl_set_copier_format(skl, module_config, *param_data);
880 break; 844 break;
881 845
882 case SKL_MODULE_TYPE_SRCINT: 846 case SKL_MODULE_TYPE_SRCINT:
883 skl_set_src_format(ctx, module_config, *param_data); 847 skl_set_src_format(skl, module_config, *param_data);
884 break; 848 break;
885 849
886 case SKL_MODULE_TYPE_UPDWMIX: 850 case SKL_MODULE_TYPE_UPDWMIX:
887 skl_set_updown_mixer_format(ctx, module_config, *param_data); 851 skl_set_updown_mixer_format(skl, module_config, *param_data);
888 break; 852 break;
889 853
890 case SKL_MODULE_TYPE_ALGO: 854 case SKL_MODULE_TYPE_ALGO:
891 skl_set_algo_format(ctx, module_config, *param_data); 855 skl_set_algo_format(skl, module_config, *param_data);
892 break; 856 break;
893 857
894 case SKL_MODULE_TYPE_BASE_OUTFMT: 858 case SKL_MODULE_TYPE_BASE_OUTFMT:
895 case SKL_MODULE_TYPE_MIC_SELECT: 859 case SKL_MODULE_TYPE_MIC_SELECT:
896 case SKL_MODULE_TYPE_KPB: 860 case SKL_MODULE_TYPE_KPB:
897 skl_set_base_outfmt_format(ctx, module_config, *param_data); 861 skl_set_base_outfmt_format(skl, module_config, *param_data);
898 break; 862 break;
899 863
900 default: 864 default:
901 skl_set_base_module_format(ctx, module_config, *param_data); 865 skl_set_base_module_format(skl, module_config, *param_data);
902 break; 866 break;
903 867
904 } 868 }
905 869
906 dev_dbg(ctx->dev, "Module type=%d config size: %d bytes\n", 870 dev_dbg(skl->dev, "Module type=%d id=%d config size: %d bytes\n",
907 module_config->id.module_id, param_size); 871 module_config->m_type, module_config->id.module_id,
872 param_size);
908 print_hex_dump_debug("Module params:", DUMP_PREFIX_OFFSET, 8, 4, 873 print_hex_dump_debug("Module params:", DUMP_PREFIX_OFFSET, 8, 4,
909 *param_data, param_size, false); 874 *param_data, param_size, false);
910 return 0; 875 return 0;
@@ -1004,7 +969,7 @@ static void skl_clear_module_state(struct skl_module_pin *mpin, int max,
1004 * We first calculate the module format, based on module type and then 969 * We first calculate the module format, based on module type and then
1005 * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper 970 * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper
1006 */ 971 */
1007int skl_init_module(struct skl_sst *ctx, 972int skl_init_module(struct skl_dev *skl,
1008 struct skl_module_cfg *mconfig) 973 struct skl_module_cfg *mconfig)
1009{ 974{
1010 u16 module_config_size = 0; 975 u16 module_config_size = 0;
@@ -1012,19 +977,19 @@ int skl_init_module(struct skl_sst *ctx,
1012 int ret; 977 int ret;
1013 struct skl_ipc_init_instance_msg msg; 978 struct skl_ipc_init_instance_msg msg;
1014 979
1015 dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__, 980 dev_dbg(skl->dev, "%s: module_id = %d instance=%d\n", __func__,
1016 mconfig->id.module_id, mconfig->id.pvt_id); 981 mconfig->id.module_id, mconfig->id.pvt_id);
1017 982
1018 if (mconfig->pipe->state != SKL_PIPE_CREATED) { 983 if (mconfig->pipe->state != SKL_PIPE_CREATED) {
1019 dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n", 984 dev_err(skl->dev, "Pipe not created state= %d pipe_id= %d\n",
1020 mconfig->pipe->state, mconfig->pipe->ppl_id); 985 mconfig->pipe->state, mconfig->pipe->ppl_id);
1021 return -EIO; 986 return -EIO;
1022 } 987 }
1023 988
1024 ret = skl_set_module_format(ctx, mconfig, 989 ret = skl_set_module_format(skl, mconfig,
1025 &module_config_size, &param_data); 990 &module_config_size, &param_data);
1026 if (ret < 0) { 991 if (ret < 0) {
1027 dev_err(ctx->dev, "Failed to set module format ret=%d\n", ret); 992 dev_err(skl->dev, "Failed to set module format ret=%d\n", ret);
1028 return ret; 993 return ret;
1029 } 994 }
1030 995
@@ -1035,9 +1000,9 @@ int skl_init_module(struct skl_sst *ctx,
1035 msg.core_id = mconfig->core_id; 1000 msg.core_id = mconfig->core_id;
1036 msg.domain = mconfig->domain; 1001 msg.domain = mconfig->domain;
1037 1002
1038 ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data); 1003 ret = skl_ipc_init_instance(&skl->ipc, &msg, param_data);
1039 if (ret < 0) { 1004 if (ret < 0) {
1040 dev_err(ctx->dev, "Failed to init instance ret=%d\n", ret); 1005 dev_err(skl->dev, "Failed to init instance ret=%d\n", ret);
1041 kfree(param_data); 1006 kfree(param_data);
1042 return ret; 1007 return ret;
1043 } 1008 }
@@ -1046,15 +1011,15 @@ int skl_init_module(struct skl_sst *ctx,
1046 return ret; 1011 return ret;
1047} 1012}
1048 1013
1049static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg 1014static void skl_dump_bind_info(struct skl_dev *skl, struct skl_module_cfg
1050 *src_module, struct skl_module_cfg *dst_module) 1015 *src_module, struct skl_module_cfg *dst_module)
1051{ 1016{
1052 dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", 1017 dev_dbg(skl->dev, "%s: src module_id = %d src_instance=%d\n",
1053 __func__, src_module->id.module_id, src_module->id.pvt_id); 1018 __func__, src_module->id.module_id, src_module->id.pvt_id);
1054 dev_dbg(ctx->dev, "%s: dst_module=%d dst_instance=%d\n", __func__, 1019 dev_dbg(skl->dev, "%s: dst_module=%d dst_instance=%d\n", __func__,
1055 dst_module->id.module_id, dst_module->id.pvt_id); 1020 dst_module->id.module_id, dst_module->id.pvt_id);
1056 1021
1057 dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", 1022 dev_dbg(skl->dev, "src_module state = %d dst module state = %d\n",
1058 src_module->m_state, dst_module->m_state); 1023 src_module->m_state, dst_module->m_state);
1059} 1024}
1060 1025
@@ -1063,7 +1028,7 @@ static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg
1063 * it is already bind. 1028 * it is already bind.
1064 * Find the pin allocated and unbind then using bind_unbind IPC 1029 * Find the pin allocated and unbind then using bind_unbind IPC
1065 */ 1030 */
1066int skl_unbind_modules(struct skl_sst *ctx, 1031int skl_unbind_modules(struct skl_dev *skl,
1067 struct skl_module_cfg *src_mcfg, 1032 struct skl_module_cfg *src_mcfg,
1068 struct skl_module_cfg *dst_mcfg) 1033 struct skl_module_cfg *dst_mcfg)
1069{ 1034{
@@ -1075,7 +1040,7 @@ int skl_unbind_modules(struct skl_sst *ctx,
1075 int out_max = src_mcfg->module->max_output_pins; 1040 int out_max = src_mcfg->module->max_output_pins;
1076 int src_index, dst_index, src_pin_state, dst_pin_state; 1041 int src_index, dst_index, src_pin_state, dst_pin_state;
1077 1042
1078 skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); 1043 skl_dump_bind_info(skl, src_mcfg, dst_mcfg);
1079 1044
1080 /* get src queue index */ 1045 /* get src queue index */
1081 src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); 1046 src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max);
@@ -1104,7 +1069,7 @@ int skl_unbind_modules(struct skl_sst *ctx,
1104 msg.dst_instance_id = dst_mcfg->id.pvt_id; 1069 msg.dst_instance_id = dst_mcfg->id.pvt_id;
1105 msg.bind = false; 1070 msg.bind = false;
1106 1071
1107 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); 1072 ret = skl_ipc_bind_unbind(&skl->ipc, &msg);
1108 if (!ret) { 1073 if (!ret) {
1109 /* free queue only if unbind is success */ 1074 /* free queue only if unbind is success */
1110 skl_free_queue(src_mcfg->m_out_pin, src_index); 1075 skl_free_queue(src_mcfg->m_out_pin, src_index);
@@ -1142,7 +1107,7 @@ static void fill_pin_params(struct skl_audio_data_format *pin_fmt,
1142 * This function finds the pins and then sends bund_unbind IPC message to 1107 * This function finds the pins and then sends bund_unbind IPC message to
1143 * DSP using IPC helper 1108 * DSP using IPC helper
1144 */ 1109 */
1145int skl_bind_modules(struct skl_sst *ctx, 1110int skl_bind_modules(struct skl_dev *skl,
1146 struct skl_module_cfg *src_mcfg, 1111 struct skl_module_cfg *src_mcfg,
1147 struct skl_module_cfg *dst_mcfg) 1112 struct skl_module_cfg *dst_mcfg)
1148{ 1113{
@@ -1156,7 +1121,7 @@ int skl_bind_modules(struct skl_sst *ctx,
1156 struct skl_module *module; 1121 struct skl_module *module;
1157 struct skl_module_iface *fmt; 1122 struct skl_module_iface *fmt;
1158 1123
1159 skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); 1124 skl_dump_bind_info(skl, src_mcfg, dst_mcfg);
1160 1125
1161 if (src_mcfg->m_state < SKL_MODULE_INIT_DONE || 1126 if (src_mcfg->m_state < SKL_MODULE_INIT_DONE ||
1162 dst_mcfg->m_state < SKL_MODULE_INIT_DONE) 1127 dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
@@ -1188,7 +1153,7 @@ int skl_bind_modules(struct skl_sst *ctx,
1188 1153
1189 format = &fmt->outputs[src_index].fmt; 1154 format = &fmt->outputs[src_index].fmt;
1190 fill_pin_params(&(pin_fmt.dst_fmt), format); 1155 fill_pin_params(&(pin_fmt.dst_fmt), format);
1191 ret = skl_set_module_params(ctx, (void *)&pin_fmt, 1156 ret = skl_set_module_params(skl, (void *)&pin_fmt,
1192 sizeof(struct skl_cpr_pin_fmt), 1157 sizeof(struct skl_cpr_pin_fmt),
1193 CPR_SINK_FMT_PARAM_ID, src_mcfg); 1158 CPR_SINK_FMT_PARAM_ID, src_mcfg);
1194 1159
@@ -1198,7 +1163,7 @@ int skl_bind_modules(struct skl_sst *ctx,
1198 1163
1199 msg.dst_queue = dst_index; 1164 msg.dst_queue = dst_index;
1200 1165
1201 dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n", 1166 dev_dbg(skl->dev, "src queue = %d dst queue =%d\n",
1202 msg.src_queue, msg.dst_queue); 1167 msg.src_queue, msg.dst_queue);
1203 1168
1204 msg.module_id = src_mcfg->id.module_id; 1169 msg.module_id = src_mcfg->id.module_id;
@@ -1207,7 +1172,7 @@ int skl_bind_modules(struct skl_sst *ctx,
1207 msg.dst_instance_id = dst_mcfg->id.pvt_id; 1172 msg.dst_instance_id = dst_mcfg->id.pvt_id;
1208 msg.bind = true; 1173 msg.bind = true;
1209 1174
1210 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); 1175 ret = skl_ipc_bind_unbind(&skl->ipc, &msg);
1211 1176
1212 if (!ret) { 1177 if (!ret) {
1213 src_mcfg->m_state = SKL_MODULE_BIND_DONE; 1178 src_mcfg->m_state = SKL_MODULE_BIND_DONE;
@@ -1223,12 +1188,12 @@ out:
1223 return ret; 1188 return ret;
1224} 1189}
1225 1190
1226static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe, 1191static int skl_set_pipe_state(struct skl_dev *skl, struct skl_pipe *pipe,
1227 enum skl_ipc_pipeline_state state) 1192 enum skl_ipc_pipeline_state state)
1228{ 1193{
1229 dev_dbg(ctx->dev, "%s: pipe_state = %d\n", __func__, state); 1194 dev_dbg(skl->dev, "%s: pipe_state = %d\n", __func__, state);
1230 1195
1231 return skl_ipc_set_pipeline_state(&ctx->ipc, pipe->ppl_id, state); 1196 return skl_ipc_set_pipeline_state(&skl->ipc, pipe->ppl_id, state);
1232} 1197}
1233 1198
1234/* 1199/*
@@ -1237,17 +1202,17 @@ static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe,
1237 * This function creates pipeline, by sending create pipeline IPC messages 1202 * This function creates pipeline, by sending create pipeline IPC messages
1238 * to FW 1203 * to FW
1239 */ 1204 */
1240int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe) 1205int skl_create_pipeline(struct skl_dev *skl, struct skl_pipe *pipe)
1241{ 1206{
1242 int ret; 1207 int ret;
1243 1208
1244 dev_dbg(ctx->dev, "%s: pipe_id = %d\n", __func__, pipe->ppl_id); 1209 dev_dbg(skl->dev, "%s: pipe_id = %d\n", __func__, pipe->ppl_id);
1245 1210
1246 ret = skl_ipc_create_pipeline(&ctx->ipc, pipe->memory_pages, 1211 ret = skl_ipc_create_pipeline(&skl->ipc, pipe->memory_pages,
1247 pipe->pipe_priority, pipe->ppl_id, 1212 pipe->pipe_priority, pipe->ppl_id,
1248 pipe->lp_mode); 1213 pipe->lp_mode);
1249 if (ret < 0) { 1214 if (ret < 0) {
1250 dev_err(ctx->dev, "Failed to create pipeline\n"); 1215 dev_err(skl->dev, "Failed to create pipeline\n");
1251 return ret; 1216 return ret;
1252 } 1217 }
1253 1218
@@ -1262,11 +1227,11 @@ int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe)
1262 * reset state. Finish the procedure by sending delete pipeline IPC. 1227 * reset state. Finish the procedure by sending delete pipeline IPC.
1263 * DSP will stop the DMA engines and release resources 1228 * DSP will stop the DMA engines and release resources
1264 */ 1229 */
1265int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) 1230int skl_delete_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
1266{ 1231{
1267 int ret; 1232 int ret;
1268 1233
1269 dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); 1234 dev_dbg(skl->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
1270 1235
1271 /* If pipe was not created in FW, do not try to delete it */ 1236 /* If pipe was not created in FW, do not try to delete it */
1272 if (pipe->state < SKL_PIPE_CREATED) 1237 if (pipe->state < SKL_PIPE_CREATED)
@@ -1274,9 +1239,9 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1274 1239
1275 /* If pipe is started, do stop the pipe in FW. */ 1240 /* If pipe is started, do stop the pipe in FW. */
1276 if (pipe->state >= SKL_PIPE_STARTED) { 1241 if (pipe->state >= SKL_PIPE_STARTED) {
1277 ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); 1242 ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED);
1278 if (ret < 0) { 1243 if (ret < 0) {
1279 dev_err(ctx->dev, "Failed to stop pipeline\n"); 1244 dev_err(skl->dev, "Failed to stop pipeline\n");
1280 return ret; 1245 return ret;
1281 } 1246 }
1282 1247
@@ -1284,17 +1249,17 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1284 } 1249 }
1285 1250
1286 /* reset pipe state before deletion */ 1251 /* reset pipe state before deletion */
1287 ret = skl_set_pipe_state(ctx, pipe, PPL_RESET); 1252 ret = skl_set_pipe_state(skl, pipe, PPL_RESET);
1288 if (ret < 0) { 1253 if (ret < 0) {
1289 dev_err(ctx->dev, "Failed to reset pipe ret=%d\n", ret); 1254 dev_err(skl->dev, "Failed to reset pipe ret=%d\n", ret);
1290 return ret; 1255 return ret;
1291 } 1256 }
1292 1257
1293 pipe->state = SKL_PIPE_RESET; 1258 pipe->state = SKL_PIPE_RESET;
1294 1259
1295 ret = skl_ipc_delete_pipeline(&ctx->ipc, pipe->ppl_id); 1260 ret = skl_ipc_delete_pipeline(&skl->ipc, pipe->ppl_id);
1296 if (ret < 0) { 1261 if (ret < 0) {
1297 dev_err(ctx->dev, "Failed to delete pipeline\n"); 1262 dev_err(skl->dev, "Failed to delete pipeline\n");
1298 return ret; 1263 return ret;
1299 } 1264 }
1300 1265
@@ -1308,28 +1273,28 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1308 * For processing data the pipe need to be run by sending IPC set pipe state 1273 * For processing data the pipe need to be run by sending IPC set pipe state
1309 * to DSP 1274 * to DSP
1310 */ 1275 */
1311int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) 1276int skl_run_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
1312{ 1277{
1313 int ret; 1278 int ret;
1314 1279
1315 dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); 1280 dev_dbg(skl->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
1316 1281
1317 /* If pipe was not created in FW, do not try to pause or delete */ 1282 /* If pipe was not created in FW, do not try to pause or delete */
1318 if (pipe->state < SKL_PIPE_CREATED) 1283 if (pipe->state < SKL_PIPE_CREATED)
1319 return 0; 1284 return 0;
1320 1285
1321 /* Pipe has to be paused before it is started */ 1286 /* Pipe has to be paused before it is started */
1322 ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); 1287 ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED);
1323 if (ret < 0) { 1288 if (ret < 0) {
1324 dev_err(ctx->dev, "Failed to pause pipe\n"); 1289 dev_err(skl->dev, "Failed to pause pipe\n");
1325 return ret; 1290 return ret;
1326 } 1291 }
1327 1292
1328 pipe->state = SKL_PIPE_PAUSED; 1293 pipe->state = SKL_PIPE_PAUSED;
1329 1294
1330 ret = skl_set_pipe_state(ctx, pipe, PPL_RUNNING); 1295 ret = skl_set_pipe_state(skl, pipe, PPL_RUNNING);
1331 if (ret < 0) { 1296 if (ret < 0) {
1332 dev_err(ctx->dev, "Failed to start pipe\n"); 1297 dev_err(skl->dev, "Failed to start pipe\n");
1333 return ret; 1298 return ret;
1334 } 1299 }
1335 1300
@@ -1342,19 +1307,19 @@ int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1342 * Stop the pipeline by sending set pipe state IPC 1307 * Stop the pipeline by sending set pipe state IPC
1343 * DSP doesnt implement stop so we always send pause message 1308 * DSP doesnt implement stop so we always send pause message
1344 */ 1309 */
1345int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) 1310int skl_stop_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
1346{ 1311{
1347 int ret; 1312 int ret;
1348 1313
1349 dev_dbg(ctx->dev, "In %s pipe=%d\n", __func__, pipe->ppl_id); 1314 dev_dbg(skl->dev, "In %s pipe=%d\n", __func__, pipe->ppl_id);
1350 1315
1351 /* If pipe was not created in FW, do not try to pause or delete */ 1316 /* If pipe was not created in FW, do not try to pause or delete */
1352 if (pipe->state < SKL_PIPE_PAUSED) 1317 if (pipe->state < SKL_PIPE_PAUSED)
1353 return 0; 1318 return 0;
1354 1319
1355 ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); 1320 ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED);
1356 if (ret < 0) { 1321 if (ret < 0) {
1357 dev_dbg(ctx->dev, "Failed to stop pipe\n"); 1322 dev_dbg(skl->dev, "Failed to stop pipe\n");
1358 return ret; 1323 return ret;
1359 } 1324 }
1360 1325
@@ -1367,7 +1332,7 @@ int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1367 * Reset the pipeline by sending set pipe state IPC this will reset the DMA 1332 * Reset the pipeline by sending set pipe state IPC this will reset the DMA
1368 * from the DSP side 1333 * from the DSP side
1369 */ 1334 */
1370int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) 1335int skl_reset_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
1371{ 1336{
1372 int ret; 1337 int ret;
1373 1338
@@ -1375,9 +1340,9 @@ int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1375 if (pipe->state < SKL_PIPE_PAUSED) 1340 if (pipe->state < SKL_PIPE_PAUSED)
1376 return 0; 1341 return 0;
1377 1342
1378 ret = skl_set_pipe_state(ctx, pipe, PPL_RESET); 1343 ret = skl_set_pipe_state(skl, pipe, PPL_RESET);
1379 if (ret < 0) { 1344 if (ret < 0) {
1380 dev_dbg(ctx->dev, "Failed to reset pipe ret=%d\n", ret); 1345 dev_dbg(skl->dev, "Failed to reset pipe ret=%d\n", ret);
1381 return ret; 1346 return ret;
1382 } 1347 }
1383 1348
@@ -1387,7 +1352,7 @@ int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1387} 1352}
1388 1353
1389/* Algo parameter set helper function */ 1354/* Algo parameter set helper function */
1390int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size, 1355int skl_set_module_params(struct skl_dev *skl, u32 *params, int size,
1391 u32 param_id, struct skl_module_cfg *mcfg) 1356 u32 param_id, struct skl_module_cfg *mcfg)
1392{ 1357{
1393 struct skl_ipc_large_config_msg msg; 1358 struct skl_ipc_large_config_msg msg;
@@ -1397,18 +1362,19 @@ int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size,
1397 msg.param_data_size = size; 1362 msg.param_data_size = size;
1398 msg.large_param_id = param_id; 1363 msg.large_param_id = param_id;
1399 1364
1400 return skl_ipc_set_large_config(&ctx->ipc, &msg, params); 1365 return skl_ipc_set_large_config(&skl->ipc, &msg, params);
1401} 1366}
1402 1367
1403int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size, 1368int skl_get_module_params(struct skl_dev *skl, u32 *params, int size,
1404 u32 param_id, struct skl_module_cfg *mcfg) 1369 u32 param_id, struct skl_module_cfg *mcfg)
1405{ 1370{
1406 struct skl_ipc_large_config_msg msg; 1371 struct skl_ipc_large_config_msg msg;
1372 size_t bytes = size;
1407 1373
1408 msg.module_id = mcfg->id.module_id; 1374 msg.module_id = mcfg->id.module_id;
1409 msg.instance_id = mcfg->id.pvt_id; 1375 msg.instance_id = mcfg->id.pvt_id;
1410 msg.param_data_size = size; 1376 msg.param_data_size = size;
1411 msg.large_param_id = param_id; 1377 msg.large_param_id = param_id;
1412 1378
1413 return skl_ipc_get_large_config(&ctx->ipc, &msg, params); 1379 return skl_ipc_get_large_config(&skl->ipc, &msg, &params, &bytes);
1414} 1380}
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index e01815cec6fd..19f328d71f24 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -9,57 +9,10 @@
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 */ 10 */
11#include <linux/pci.h> 11#include <linux/pci.h>
12#include <sound/intel-nhlt.h>
12#include "skl.h" 13#include "skl.h"
13#include "skl-i2s.h" 14#include "skl-i2s.h"
14 15
15#define NHLT_ACPI_HEADER_SIG "NHLT"
16
17/* Unique identification for getting NHLT blobs */
18static guid_t osc_guid =
19 GUID_INIT(0xA69F886E, 0x6CEB, 0x4594,
20 0xA4, 0x1F, 0x7B, 0x5D, 0xCE, 0x24, 0xC5, 0x53);
21
22
23struct nhlt_acpi_table *skl_nhlt_init(struct device *dev)
24{
25 acpi_handle handle;
26 union acpi_object *obj;
27 struct nhlt_resource_desc *nhlt_ptr = NULL;
28 struct nhlt_acpi_table *nhlt_table = NULL;
29
30 handle = ACPI_HANDLE(dev);
31 if (!handle) {
32 dev_err(dev, "Didn't find ACPI_HANDLE\n");
33 return NULL;
34 }
35
36 obj = acpi_evaluate_dsm(handle, &osc_guid, 1, 1, NULL);
37 if (obj && obj->type == ACPI_TYPE_BUFFER) {
38 nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer;
39 if (nhlt_ptr->length)
40 nhlt_table = (struct nhlt_acpi_table *)
41 memremap(nhlt_ptr->min_addr, nhlt_ptr->length,
42 MEMREMAP_WB);
43 ACPI_FREE(obj);
44 if (nhlt_table && (strncmp(nhlt_table->header.signature,
45 NHLT_ACPI_HEADER_SIG,
46 strlen(NHLT_ACPI_HEADER_SIG)) != 0)) {
47 memunmap(nhlt_table);
48 dev_err(dev, "NHLT ACPI header signature incorrect\n");
49 return NULL;
50 }
51 return nhlt_table;
52 }
53
54 dev_err(dev, "device specific method to extract NHLT blob failed\n");
55 return NULL;
56}
57
58void skl_nhlt_free(struct nhlt_acpi_table *nhlt)
59{
60 memunmap((void *) nhlt);
61}
62
63static struct nhlt_specific_cfg *skl_get_specific_cfg( 16static struct nhlt_specific_cfg *skl_get_specific_cfg(
64 struct device *dev, struct nhlt_fmt *fmt, 17 struct device *dev, struct nhlt_fmt *fmt,
65 u8 no_ch, u32 rate, u16 bps, u8 linktype) 18 u8 no_ch, u32 rate, u16 bps, u8 linktype)
@@ -126,7 +79,7 @@ static bool skl_check_ep_match(struct device *dev, struct nhlt_endpoint *epnt,
126} 79}
127 80
128struct nhlt_specific_cfg 81struct nhlt_specific_cfg
129*skl_get_ep_blob(struct skl *skl, u32 instance, u8 link_type, 82*skl_get_ep_blob(struct skl_dev *skl, u32 instance, u8 link_type,
130 u8 s_fmt, u8 num_ch, u32 s_rate, 83 u8 s_fmt, u8 num_ch, u32 s_rate,
131 u8 dirn, u8 dev_type) 84 u8 dirn, u8 dev_type)
132{ 85{
@@ -162,48 +115,6 @@ struct nhlt_specific_cfg
162 return NULL; 115 return NULL;
163} 116}
164 117
165int skl_get_dmic_geo(struct skl *skl)
166{
167 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
168 struct nhlt_endpoint *epnt;
169 struct nhlt_dmic_array_config *cfg;
170 struct device *dev = &skl->pci->dev;
171 unsigned int dmic_geo = 0;
172 u8 j;
173
174 if (!nhlt)
175 return 0;
176
177 epnt = (struct nhlt_endpoint *)nhlt->desc;
178
179 for (j = 0; j < nhlt->endpoint_count; j++) {
180 if (epnt->linktype == NHLT_LINK_DMIC) {
181 cfg = (struct nhlt_dmic_array_config *)
182 (epnt->config.caps);
183 switch (cfg->array_type) {
184 case NHLT_MIC_ARRAY_2CH_SMALL:
185 case NHLT_MIC_ARRAY_2CH_BIG:
186 dmic_geo |= MIC_ARRAY_2CH;
187 break;
188
189 case NHLT_MIC_ARRAY_4CH_1ST_GEOM:
190 case NHLT_MIC_ARRAY_4CH_L_SHAPED:
191 case NHLT_MIC_ARRAY_4CH_2ND_GEOM:
192 dmic_geo |= MIC_ARRAY_4CH;
193 break;
194
195 default:
196 dev_warn(dev, "undefined DMIC array_type 0x%0x\n",
197 cfg->array_type);
198
199 }
200 }
201 epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
202 }
203
204 return dmic_geo;
205}
206
207static void skl_nhlt_trim_space(char *trim) 118static void skl_nhlt_trim_space(char *trim)
208{ 119{
209 char *s = trim; 120 char *s = trim;
@@ -219,7 +130,7 @@ static void skl_nhlt_trim_space(char *trim)
219 s[cnt] = '\0'; 130 s[cnt] = '\0';
220} 131}
221 132
222int skl_nhlt_update_topology_bin(struct skl *skl) 133int skl_nhlt_update_topology_bin(struct skl_dev *skl)
223{ 134{
224 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; 135 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
225 struct hdac_bus *bus = skl_to_bus(skl); 136 struct hdac_bus *bus = skl_to_bus(skl);
@@ -243,7 +154,7 @@ static ssize_t skl_nhlt_platform_id_show(struct device *dev,
243{ 154{
244 struct pci_dev *pci = to_pci_dev(dev); 155 struct pci_dev *pci = to_pci_dev(dev);
245 struct hdac_bus *bus = pci_get_drvdata(pci); 156 struct hdac_bus *bus = pci_get_drvdata(pci);
246 struct skl *skl = bus_to_skl(bus); 157 struct skl_dev *skl = bus_to_skl(bus);
247 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; 158 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
248 char platform_id[32]; 159 char platform_id[32];
249 160
@@ -257,7 +168,7 @@ static ssize_t skl_nhlt_platform_id_show(struct device *dev,
257 168
258static DEVICE_ATTR(platform_id, 0444, skl_nhlt_platform_id_show, NULL); 169static DEVICE_ATTR(platform_id, 0444, skl_nhlt_platform_id_show, NULL);
259 170
260int skl_nhlt_create_sysfs(struct skl *skl) 171int skl_nhlt_create_sysfs(struct skl_dev *skl)
261{ 172{
262 struct device *dev = &skl->pci->dev; 173 struct device *dev = &skl->pci->dev;
263 174
@@ -267,7 +178,7 @@ int skl_nhlt_create_sysfs(struct skl *skl)
267 return 0; 178 return 0;
268} 179}
269 180
270void skl_nhlt_remove_sysfs(struct skl *skl) 181void skl_nhlt_remove_sysfs(struct skl_dev *skl)
271{ 182{
272 struct device *dev = &skl->pci->dev; 183 struct device *dev = &skl->pci->dev;
273 184
@@ -279,7 +190,7 @@ void skl_nhlt_remove_sysfs(struct skl *skl)
279 * stores all possible rates supported in a rate table for the corresponding 190 * stores all possible rates supported in a rate table for the corresponding
280 * sclk/sclkfs. 191 * sclk/sclkfs.
281 */ 192 */
282static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks, 193static void skl_get_ssp_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks,
283 struct nhlt_fmt *fmt, u8 id) 194 struct nhlt_fmt *fmt, u8 id)
284{ 195{
285 struct skl_i2s_config_blob_ext *i2s_config_ext; 196 struct skl_i2s_config_blob_ext *i2s_config_ext;
@@ -377,7 +288,7 @@ static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks,
377 } 288 }
378} 289}
379 290
380static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk, 291static void skl_get_mclk(struct skl_dev *skl, struct skl_ssp_clk *mclk,
381 struct nhlt_fmt *fmt, u8 id) 292 struct nhlt_fmt *fmt, u8 id)
382{ 293{
383 struct skl_i2s_config_blob_ext *i2s_config_ext; 294 struct skl_i2s_config_blob_ext *i2s_config_ext;
@@ -421,7 +332,7 @@ static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk,
421 mclk[id].parent_name = parent->name; 332 mclk[id].parent_name = parent->name;
422} 333}
423 334
424void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks) 335void skl_get_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks)
425{ 336{
426 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; 337 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
427 struct nhlt_endpoint *epnt; 338 struct nhlt_endpoint *epnt;
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 760bbcf9a469..7f287424af9b 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -116,7 +116,7 @@ static void skl_set_suspend_active(struct snd_pcm_substream *substream,
116{ 116{
117 struct hdac_bus *bus = dev_get_drvdata(dai->dev); 117 struct hdac_bus *bus = dev_get_drvdata(dai->dev);
118 struct snd_soc_dapm_widget *w; 118 struct snd_soc_dapm_widget *w;
119 struct skl *skl = bus_to_skl(bus); 119 struct skl_dev *skl = bus_to_skl(bus);
120 120
121 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 121 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
122 w = dai->playback_widget; 122 w = dai->playback_widget;
@@ -132,7 +132,7 @@ static void skl_set_suspend_active(struct snd_pcm_substream *substream,
132int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params) 132int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params)
133{ 133{
134 struct hdac_bus *bus = dev_get_drvdata(dev); 134 struct hdac_bus *bus = dev_get_drvdata(dev);
135 struct skl *skl = bus_to_skl(bus); 135 struct skl_dev *skl = bus_to_skl(bus);
136 unsigned int format_val; 136 unsigned int format_val;
137 struct hdac_stream *hstream; 137 struct hdac_stream *hstream;
138 struct hdac_ext_stream *stream; 138 struct hdac_ext_stream *stream;
@@ -224,7 +224,7 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
224 struct hdac_ext_stream *stream; 224 struct hdac_ext_stream *stream;
225 struct snd_pcm_runtime *runtime = substream->runtime; 225 struct snd_pcm_runtime *runtime = substream->runtime;
226 struct skl_dma_params *dma_params; 226 struct skl_dma_params *dma_params;
227 struct skl *skl = get_skl_ctx(dai->dev); 227 struct skl_dev *skl = get_skl_ctx(dai->dev);
228 struct skl_module_cfg *mconfig; 228 struct skl_module_cfg *mconfig;
229 229
230 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 230 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
@@ -271,7 +271,7 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
271static int skl_pcm_prepare(struct snd_pcm_substream *substream, 271static int skl_pcm_prepare(struct snd_pcm_substream *substream,
272 struct snd_soc_dai *dai) 272 struct snd_soc_dai *dai)
273{ 273{
274 struct skl *skl = get_skl_ctx(dai->dev); 274 struct skl_dev *skl = get_skl_ctx(dai->dev);
275 struct skl_module_cfg *mconfig; 275 struct skl_module_cfg *mconfig;
276 int ret; 276 int ret;
277 277
@@ -288,7 +288,7 @@ static int skl_pcm_prepare(struct snd_pcm_substream *substream,
288 mconfig->pipe->state == SKL_PIPE_CREATED || 288 mconfig->pipe->state == SKL_PIPE_CREATED ||
289 mconfig->pipe->state == SKL_PIPE_PAUSED)) { 289 mconfig->pipe->state == SKL_PIPE_PAUSED)) {
290 290
291 ret = skl_reset_pipe(skl->skl_sst, mconfig->pipe); 291 ret = skl_reset_pipe(skl, mconfig->pipe);
292 292
293 if (ret < 0) 293 if (ret < 0)
294 return ret; 294 return ret;
@@ -350,7 +350,7 @@ static void skl_pcm_close(struct snd_pcm_substream *substream,
350 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 350 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
351 struct hdac_bus *bus = dev_get_drvdata(dai->dev); 351 struct hdac_bus *bus = dev_get_drvdata(dai->dev);
352 struct skl_dma_params *dma_params = NULL; 352 struct skl_dma_params *dma_params = NULL;
353 struct skl *skl = bus_to_skl(bus); 353 struct skl_dev *skl = bus_to_skl(bus);
354 struct skl_module_cfg *mconfig; 354 struct skl_module_cfg *mconfig;
355 355
356 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 356 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
@@ -370,9 +370,9 @@ static void skl_pcm_close(struct snd_pcm_substream *substream,
370 * CGCTL.MISCBDCGE if disabled by driver 370 * CGCTL.MISCBDCGE if disabled by driver
371 */ 371 */
372 if (!strncmp(dai->name, "Reference Pin", 13) && 372 if (!strncmp(dai->name, "Reference Pin", 13) &&
373 skl->skl_sst->miscbdcg_disabled) { 373 skl->miscbdcg_disabled) {
374 skl->skl_sst->enable_miscbdcge(dai->dev, true); 374 skl->enable_miscbdcge(dai->dev, true);
375 skl->skl_sst->miscbdcg_disabled = false; 375 skl->miscbdcg_disabled = false;
376 } 376 }
377 377
378 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); 378 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
@@ -387,7 +387,7 @@ static int skl_pcm_hw_free(struct snd_pcm_substream *substream,
387{ 387{
388 struct hdac_bus *bus = dev_get_drvdata(dai->dev); 388 struct hdac_bus *bus = dev_get_drvdata(dai->dev);
389 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 389 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
390 struct skl *skl = get_skl_ctx(dai->dev); 390 struct skl_dev *skl = get_skl_ctx(dai->dev);
391 struct skl_module_cfg *mconfig; 391 struct skl_module_cfg *mconfig;
392 int ret; 392 int ret;
393 393
@@ -396,7 +396,7 @@ static int skl_pcm_hw_free(struct snd_pcm_substream *substream,
396 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); 396 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
397 397
398 if (mconfig) { 398 if (mconfig) {
399 ret = skl_reset_pipe(skl->skl_sst, mconfig->pipe); 399 ret = skl_reset_pipe(skl, mconfig->pipe);
400 if (ret < 0) 400 if (ret < 0)
401 dev_err(dai->dev, "%s:Reset failed ret =%d", 401 dev_err(dai->dev, "%s:Reset failed ret =%d",
402 __func__, ret); 402 __func__, ret);
@@ -471,8 +471,7 @@ static int skl_decoupled_trigger(struct snd_pcm_substream *substream,
471static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, 471static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
472 struct snd_soc_dai *dai) 472 struct snd_soc_dai *dai)
473{ 473{
474 struct skl *skl = get_skl_ctx(dai->dev); 474 struct skl_dev *skl = get_skl_ctx(dai->dev);
475 struct skl_sst *ctx = skl->skl_sst;
476 struct skl_module_cfg *mconfig; 475 struct skl_module_cfg *mconfig;
477 struct hdac_bus *bus = get_bus_ctx(substream); 476 struct hdac_bus *bus = get_bus_ctx(substream);
478 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 477 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
@@ -515,7 +514,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
515 ret = skl_decoupled_trigger(substream, cmd); 514 ret = skl_decoupled_trigger(substream, cmd);
516 if (ret < 0) 515 if (ret < 0)
517 return ret; 516 return ret;
518 return skl_run_pipe(ctx, mconfig->pipe); 517 return skl_run_pipe(skl, mconfig->pipe);
519 break; 518 break;
520 519
521 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 520 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -526,7 +525,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
526 * there are no underrun/overrun in the case if there is a delay 525 * there are no underrun/overrun in the case if there is a delay
527 * between the two operations. 526 * between the two operations.
528 */ 527 */
529 ret = skl_stop_pipe(ctx, mconfig->pipe); 528 ret = skl_stop_pipe(skl, mconfig->pipe);
530 if (ret < 0) 529 if (ret < 0)
531 return ret; 530 return ret;
532 531
@@ -602,14 +601,14 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
602static int skl_link_pcm_prepare(struct snd_pcm_substream *substream, 601static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
603 struct snd_soc_dai *dai) 602 struct snd_soc_dai *dai)
604{ 603{
605 struct skl *skl = get_skl_ctx(dai->dev); 604 struct skl_dev *skl = get_skl_ctx(dai->dev);
606 struct skl_module_cfg *mconfig = NULL; 605 struct skl_module_cfg *mconfig = NULL;
607 606
608 /* In case of XRUN recovery, reset the FW pipe to clean state */ 607 /* In case of XRUN recovery, reset the FW pipe to clean state */
609 mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream); 608 mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream);
610 if (mconfig && !mconfig->pipe->passthru && 609 if (mconfig && !mconfig->pipe->passthru &&
611 (substream->runtime->status->state == SNDRV_PCM_STATE_XRUN)) 610 (substream->runtime->status->state == SNDRV_PCM_STATE_XRUN))
612 skl_reset_pipe(skl->skl_sst, mconfig->pipe); 611 skl_reset_pipe(skl, mconfig->pipe);
613 612
614 return 0; 613 return 0;
615} 614}
@@ -1301,7 +1300,7 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
1301 struct hdac_bus *bus = dev_get_drvdata(dai->dev); 1300 struct hdac_bus *bus = dev_get_drvdata(dai->dev);
1302 struct snd_pcm *pcm = rtd->pcm; 1301 struct snd_pcm *pcm = rtd->pcm;
1303 unsigned int size; 1302 unsigned int size;
1304 struct skl *skl = bus_to_skl(bus); 1303 struct skl_dev *skl = bus_to_skl(bus);
1305 1304
1306 if (dai->driver->playback.channels_min || 1305 if (dai->driver->playback.channels_min ||
1307 dai->driver->capture.channels_min) { 1306 dai->driver->capture.channels_min) {
@@ -1318,9 +1317,9 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
1318 return 0; 1317 return 0;
1319} 1318}
1320 1319
1321static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig) 1320static int skl_get_module_info(struct skl_dev *skl,
1321 struct skl_module_cfg *mconfig)
1322{ 1322{
1323 struct skl_sst *ctx = skl->skl_sst;
1324 struct skl_module_inst_id *pin_id; 1323 struct skl_module_inst_id *pin_id;
1325 guid_t *uuid_mod, *uuid_tplg; 1324 guid_t *uuid_mod, *uuid_tplg;
1326 struct skl_module *skl_module; 1325 struct skl_module *skl_module;
@@ -1329,12 +1328,12 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
1329 1328
1330 uuid_mod = (guid_t *)mconfig->guid; 1329 uuid_mod = (guid_t *)mconfig->guid;
1331 1330
1332 if (list_empty(&ctx->uuid_list)) { 1331 if (list_empty(&skl->uuid_list)) {
1333 dev_err(ctx->dev, "Module list is empty\n"); 1332 dev_err(skl->dev, "Module list is empty\n");
1334 return -EIO; 1333 return -EIO;
1335 } 1334 }
1336 1335
1337 list_for_each_entry(module, &ctx->uuid_list, list) { 1336 list_for_each_entry(module, &skl->uuid_list, list) {
1338 if (guid_equal(uuid_mod, &module->uuid)) { 1337 if (guid_equal(uuid_mod, &module->uuid)) {
1339 mconfig->id.module_id = module->id; 1338 mconfig->id.module_id = module->id;
1340 if (mconfig->module) 1339 if (mconfig->module)
@@ -1361,7 +1360,7 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
1361 if (skl->nr_modules && ret) 1360 if (skl->nr_modules && ret)
1362 return ret; 1361 return ret;
1363 1362
1364 list_for_each_entry(module, &ctx->uuid_list, list) { 1363 list_for_each_entry(module, &skl->uuid_list, list) {
1365 for (i = 0; i < MAX_IN_QUEUE; i++) { 1364 for (i = 0; i < MAX_IN_QUEUE; i++) {
1366 pin_id = &mconfig->m_in_pin[i].id; 1365 pin_id = &mconfig->m_in_pin[i].id;
1367 if (guid_equal(&pin_id->mod_uuid, &module->uuid)) 1366 if (guid_equal(&pin_id->mod_uuid, &module->uuid))
@@ -1378,7 +1377,7 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
1378 return 0; 1377 return 0;
1379} 1378}
1380 1379
1381static int skl_populate_modules(struct skl *skl) 1380static int skl_populate_modules(struct skl_dev *skl)
1382{ 1381{
1383 struct skl_pipeline *p; 1382 struct skl_pipeline *p;
1384 struct skl_pipe_module *m; 1383 struct skl_pipe_module *m;
@@ -1393,7 +1392,7 @@ static int skl_populate_modules(struct skl *skl)
1393 1392
1394 ret = skl_get_module_info(skl, mconfig); 1393 ret = skl_get_module_info(skl, mconfig);
1395 if (ret < 0) { 1394 if (ret < 0) {
1396 dev_err(skl->skl_sst->dev, 1395 dev_err(skl->dev,
1397 "query module info failed\n"); 1396 "query module info failed\n");
1398 return ret; 1397 return ret;
1399 } 1398 }
@@ -1408,7 +1407,7 @@ static int skl_populate_modules(struct skl *skl)
1408static int skl_platform_soc_probe(struct snd_soc_component *component) 1407static int skl_platform_soc_probe(struct snd_soc_component *component)
1409{ 1408{
1410 struct hdac_bus *bus = dev_get_drvdata(component->dev); 1409 struct hdac_bus *bus = dev_get_drvdata(component->dev);
1411 struct skl *skl = bus_to_skl(bus); 1410 struct skl_dev *skl = bus_to_skl(bus);
1412 const struct skl_dsp_ops *ops; 1411 const struct skl_dsp_ops *ops;
1413 int ret; 1412 int ret;
1414 1413
@@ -1434,22 +1433,21 @@ static int skl_platform_soc_probe(struct snd_soc_component *component)
1434 * Disable dynamic clock and power gating during firmware 1433 * Disable dynamic clock and power gating during firmware
1435 * and library download 1434 * and library download
1436 */ 1435 */
1437 skl->skl_sst->enable_miscbdcge(component->dev, false); 1436 skl->enable_miscbdcge(component->dev, false);
1438 skl->skl_sst->clock_power_gating(component->dev, false); 1437 skl->clock_power_gating(component->dev, false);
1439 1438
1440 ret = ops->init_fw(component->dev, skl->skl_sst); 1439 ret = ops->init_fw(component->dev, skl);
1441 skl->skl_sst->enable_miscbdcge(component->dev, true); 1440 skl->enable_miscbdcge(component->dev, true);
1442 skl->skl_sst->clock_power_gating(component->dev, true); 1441 skl->clock_power_gating(component->dev, true);
1443 if (ret < 0) { 1442 if (ret < 0) {
1444 dev_err(component->dev, "Failed to boot first fw: %d\n", ret); 1443 dev_err(component->dev, "Failed to boot first fw: %d\n", ret);
1445 return ret; 1444 return ret;
1446 } 1445 }
1447 skl_populate_modules(skl); 1446 skl_populate_modules(skl);
1448 skl->skl_sst->update_d0i3c = skl_update_d0i3c; 1447 skl->update_d0i3c = skl_update_d0i3c;
1449 skl_dsp_enable_notification(skl->skl_sst, false);
1450 1448
1451 if (skl->cfg.astate_cfg != NULL) { 1449 if (skl->cfg.astate_cfg != NULL) {
1452 skl_dsp_set_astate_cfg(skl->skl_sst, 1450 skl_dsp_set_astate_cfg(skl,
1453 skl->cfg.astate_cfg->count, 1451 skl->cfg.astate_cfg->count,
1454 skl->cfg.astate_cfg); 1452 skl->cfg.astate_cfg);
1455 } 1453 }
@@ -1463,7 +1461,7 @@ static int skl_platform_soc_probe(struct snd_soc_component *component)
1463static void skl_pcm_remove(struct snd_soc_component *component) 1461static void skl_pcm_remove(struct snd_soc_component *component)
1464{ 1462{
1465 struct hdac_bus *bus = dev_get_drvdata(component->dev); 1463 struct hdac_bus *bus = dev_get_drvdata(component->dev);
1466 struct skl *skl = bus_to_skl(bus); 1464 struct skl_dev *skl = bus_to_skl(bus);
1467 1465
1468 skl_tplg_exit(component, bus); 1466 skl_tplg_exit(component, bus);
1469 1467
@@ -1486,7 +1484,7 @@ int skl_platform_register(struct device *dev)
1486 struct snd_soc_dai_driver *dais; 1484 struct snd_soc_dai_driver *dais;
1487 int num_dais = ARRAY_SIZE(skl_platform_dai); 1485 int num_dais = ARRAY_SIZE(skl_platform_dai);
1488 struct hdac_bus *bus = dev_get_drvdata(dev); 1486 struct hdac_bus *bus = dev_get_drvdata(dev);
1489 struct skl *skl = bus_to_skl(bus); 1487 struct skl_dev *skl = bus_to_skl(bus);
1490 1488
1491 skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai), 1489 skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai),
1492 GFP_KERNEL); 1490 GFP_KERNEL);
@@ -1520,7 +1518,7 @@ err:
1520int skl_platform_unregister(struct device *dev) 1518int skl_platform_unregister(struct device *dev)
1521{ 1519{
1522 struct hdac_bus *bus = dev_get_drvdata(dev); 1520 struct hdac_bus *bus = dev_get_drvdata(dev);
1523 struct skl *skl = bus_to_skl(bus); 1521 struct skl_dev *skl = bus_to_skl(bus);
1524 struct skl_module_deferred_bind *modules, *tmp; 1522 struct skl_module_deferred_bind *modules, *tmp;
1525 1523
1526 if (!list_empty(&skl->bind_list)) { 1524 if (!list_empty(&skl->bind_list)) {
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.c b/sound/soc/intel/skylake/skl-ssp-clk.c
index 5bb6e40d4d3e..1c0e5226cb5b 100644
--- a/sound/soc/intel/skylake/skl-ssp-clk.c
+++ b/sound/soc/intel/skylake/skl-ssp-clk.c
@@ -11,6 +11,7 @@
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/clk-provider.h> 12#include <linux/clk-provider.h>
13#include <linux/clkdev.h> 13#include <linux/clkdev.h>
14#include <sound/intel-nhlt.h>
14#include "skl.h" 15#include "skl.h"
15#include "skl-ssp-clk.h" 16#include "skl-ssp-clk.h"
16#include "skl-topology.h" 17#include "skl-topology.h"
@@ -101,7 +102,7 @@ static void skl_fill_clk_ipc(struct skl_clk_rate_cfg_table *rcfg, u8 clk_type)
101} 102}
102 103
103/* Sends dma control IPC to turn the clock ON/OFF */ 104/* Sends dma control IPC to turn the clock ON/OFF */
104static int skl_send_clk_dma_control(struct skl *skl, 105static int skl_send_clk_dma_control(struct skl_dev *skl,
105 struct skl_clk_rate_cfg_table *rcfg, 106 struct skl_clk_rate_cfg_table *rcfg,
106 u32 vbus_id, u8 clk_type, 107 u32 vbus_id, u8 clk_type,
107 bool enable) 108 bool enable)
@@ -152,7 +153,7 @@ static int skl_send_clk_dma_control(struct skl *skl,
152 memcpy(i2s_config + sp_cfg->size, data, size); 153 memcpy(i2s_config + sp_cfg->size, data, size);
153 154
154 node_id = ((SKL_DMA_I2S_LINK_INPUT_CLASS << 8) | (vbus_id << 4)); 155 node_id = ((SKL_DMA_I2S_LINK_INPUT_CLASS << 8) | (vbus_id << 4));
155 ret = skl_dsp_set_dma_control(skl->skl_sst, (u32 *)i2s_config, 156 ret = skl_dsp_set_dma_control(skl, (u32 *)i2s_config,
156 i2s_config_size, node_id); 157 i2s_config_size, node_id);
157 kfree(i2s_config); 158 kfree(i2s_config);
158 159
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c
index 36590c5b4673..225706d148d8 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.c
+++ b/sound/soc/intel/skylake/skl-sst-dsp.c
@@ -12,7 +12,7 @@
12#include "../common/sst-dsp.h" 12#include "../common/sst-dsp.h"
13#include "../common/sst-ipc.h" 13#include "../common/sst-ipc.h"
14#include "../common/sst-dsp-priv.h" 14#include "../common/sst-dsp-priv.h"
15#include "skl-sst-ipc.h" 15#include "skl.h"
16 16
17/* various timeout values */ 17/* various timeout values */
18#define SKL_DSP_PU_TO 50 18#define SKL_DSP_PU_TO 50
@@ -33,7 +33,7 @@ void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state)
33 */ 33 */
34void skl_dsp_init_core_state(struct sst_dsp *ctx) 34void skl_dsp_init_core_state(struct sst_dsp *ctx)
35{ 35{
36 struct skl_sst *skl = ctx->thread_context; 36 struct skl_dev *skl = ctx->thread_context;
37 int i; 37 int i;
38 38
39 skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING; 39 skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING;
@@ -48,7 +48,7 @@ void skl_dsp_init_core_state(struct sst_dsp *ctx)
48/* Get the mask for all enabled cores */ 48/* Get the mask for all enabled cores */
49unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx) 49unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx)
50{ 50{
51 struct skl_sst *skl = ctx->thread_context; 51 struct skl_dev *skl = ctx->thread_context;
52 unsigned int core_mask, en_cores_mask; 52 unsigned int core_mask, en_cores_mask;
53 u32 val; 53 u32 val;
54 54
@@ -335,7 +335,7 @@ irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id)
335 */ 335 */
336int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id) 336int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
337{ 337{
338 struct skl_sst *skl = ctx->thread_context; 338 struct skl_dev *skl = ctx->thread_context;
339 int ret = 0; 339 int ret = 0;
340 340
341 if (core_id >= skl->cores.count) { 341 if (core_id >= skl->cores.count) {
@@ -364,7 +364,7 @@ EXPORT_SYMBOL_GPL(skl_dsp_get_core);
364 364
365int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id) 365int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id)
366{ 366{
367 struct skl_sst *skl = ctx->thread_context; 367 struct skl_dev *skl = ctx->thread_context;
368 int ret = 0; 368 int ret = 0;
369 369
370 if (core_id >= skl->cores.count) { 370 if (core_id >= skl->cores.count) {
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index a80219562036..cdfec0fca577 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -15,9 +15,9 @@
15#include "skl-sst-cldma.h" 15#include "skl-sst-cldma.h"
16 16
17struct sst_dsp; 17struct sst_dsp;
18struct skl_sst;
19struct sst_dsp_device; 18struct sst_dsp_device;
20struct skl_lib_info; 19struct skl_lib_info;
20struct skl_dev;
21 21
22/* Intel HD Audio General DSP Registers */ 22/* Intel HD Audio General DSP Registers */
23#define SKL_ADSP_GEN_BASE 0x0 23#define SKL_ADSP_GEN_BASE 0x0
@@ -222,32 +222,31 @@ int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id);
222int skl_dsp_boot(struct sst_dsp *ctx); 222int skl_dsp_boot(struct sst_dsp *ctx);
223int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 223int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
224 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 224 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
225 struct skl_sst **dsp); 225 struct skl_dev **dsp);
226int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 226int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
227 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 227 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
228 struct skl_sst **dsp); 228 struct skl_dev **dsp);
229int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx); 229int skl_sst_init_fw(struct device *dev, struct skl_dev *skl);
230int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx); 230int bxt_sst_init_fw(struct device *dev, struct skl_dev *skl);
231void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 231void skl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl);
232void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 232void bxt_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl);
233 233
234int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, 234int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
235 unsigned int offset, int index); 235 unsigned int offset, int index);
236int skl_get_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int instance_id); 236int skl_get_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int instance_id);
237int skl_put_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int *pvt_id); 237int skl_put_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int *pvt_id);
238int skl_get_pvt_instance_id_map(struct skl_sst *ctx, 238int skl_get_pvt_instance_id_map(struct skl_dev *skl,
239 int module_id, int instance_id); 239 int module_id, int instance_id);
240void skl_freeup_uuid_list(struct skl_sst *ctx); 240void skl_freeup_uuid_list(struct skl_dev *skl);
241 241
242int skl_dsp_strip_extended_manifest(struct firmware *fw); 242int skl_dsp_strip_extended_manifest(struct firmware *fw);
243void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable);
244 243
245void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data); 244void skl_dsp_set_astate_cfg(struct skl_dev *skl, u32 cnt, void *data);
246 245
247int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, 246int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
248 struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp, 247 struct skl_dsp_loader_ops dsp_ops, struct skl_dev **dsp,
249 struct sst_dsp_device *skl_dev); 248 struct sst_dsp_device *skl_dev);
250int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo, 249int skl_prepare_lib_load(struct skl_dev *skl, struct skl_lib_info *linfo,
251 struct firmware *stripped_fw, 250 struct firmware *stripped_fw,
252 unsigned int hdr_offset, int index); 251 unsigned int hdr_offset, int index);
253void skl_release_library(struct skl_lib_info *linfo, int lib_count); 252void skl_release_library(struct skl_lib_info *linfo, int lib_count);
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 2cc8f7d2d319..667cdddc289f 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -281,7 +281,7 @@ void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data,
281 size_t tx_size) 281 size_t tx_size)
282{ 282{
283 if (tx_size) 283 if (tx_size)
284 memcpy(msg->tx_data, tx_data, tx_size); 284 memcpy(msg->tx.data, tx_data, tx_size);
285} 285}
286 286
287static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp) 287static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp)
@@ -295,10 +295,10 @@ static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp)
295/* Lock to be held by caller */ 295/* Lock to be held by caller */
296static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) 296static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
297{ 297{
298 struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header); 298 struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header);
299 299
300 if (msg->tx_size) 300 if (msg->tx.size)
301 sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); 301 sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
302 sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE, 302 sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE,
303 header->extension); 303 header->extension);
304 sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI, 304 sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI,
@@ -345,7 +345,7 @@ out:
345int skl_ipc_process_notification(struct sst_generic_ipc *ipc, 345int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
346 struct skl_ipc_header header) 346 struct skl_ipc_header header)
347{ 347{
348 struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); 348 struct skl_dev *skl = container_of(ipc, struct skl_dev, ipc);
349 349
350 if (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { 350 if (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
351 switch (IPC_GLB_NOTIFY_TYPE(header.primary)) { 351 switch (IPC_GLB_NOTIFY_TYPE(header.primary)) {
@@ -436,7 +436,7 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
436 struct ipc_message *msg; 436 struct ipc_message *msg;
437 u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK; 437 u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK;
438 u64 *ipc_header = (u64 *)(&header); 438 u64 *ipc_header = (u64 *)(&header);
439 struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); 439 struct skl_dev *skl = container_of(ipc, struct skl_dev, ipc);
440 unsigned long flags; 440 unsigned long flags;
441 441
442 spin_lock_irqsave(&ipc->dsp->spinlock, flags); 442 spin_lock_irqsave(&ipc->dsp->spinlock, flags);
@@ -447,11 +447,12 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
447 return; 447 return;
448 } 448 }
449 449
450 msg->rx.header = *ipc_header;
450 /* first process the header */ 451 /* first process the header */
451 if (reply == IPC_GLB_REPLY_SUCCESS) { 452 if (reply == IPC_GLB_REPLY_SUCCESS) {
452 dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary); 453 dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary);
453 /* copy the rx data from the mailbox */ 454 /* copy the rx data from the mailbox */
454 sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size); 455 sst_dsp_inbox_read(ipc->dsp, msg->rx.data, msg->rx.size);
455 switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { 456 switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
456 case IPC_GLB_LOAD_MULTIPLE_MODS: 457 case IPC_GLB_LOAD_MULTIPLE_MODS:
457 case IPC_GLB_LOAD_LIBRARY: 458 case IPC_GLB_LOAD_LIBRARY:
@@ -488,7 +489,7 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
488irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context) 489irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
489{ 490{
490 struct sst_dsp *dsp = context; 491 struct sst_dsp *dsp = context;
491 struct skl_sst *skl = sst_dsp_get_thread_context(dsp); 492 struct skl_dev *skl = sst_dsp_get_thread_context(dsp);
492 struct sst_generic_ipc *ipc = &skl->ipc; 493 struct sst_generic_ipc *ipc = &skl->ipc;
493 struct skl_ipc_header header = {0}; 494 struct skl_ipc_header header = {0};
494 u32 hipcie, hipct, hipcte; 495 u32 hipcie, hipct, hipcte;
@@ -595,7 +596,7 @@ bool skl_ipc_int_status(struct sst_dsp *ctx)
595 SKL_ADSP_REG_ADSPIS) & SKL_ADSPIS_IPC; 596 SKL_ADSP_REG_ADSPIS) & SKL_ADSPIS_IPC;
596} 597}
597 598
598int skl_ipc_init(struct device *dev, struct skl_sst *skl) 599int skl_ipc_init(struct device *dev, struct skl_dev *skl)
599{ 600{
600 struct sst_generic_ipc *ipc; 601 struct sst_generic_ipc *ipc;
601 int err; 602 int err;
@@ -635,7 +636,7 @@ int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
635 u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode) 636 u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode)
636{ 637{
637 struct skl_ipc_header header = {0}; 638 struct skl_ipc_header header = {0};
638 u64 *ipc_header = (u64 *)(&header); 639 struct sst_ipc_message request = {0};
639 int ret; 640 int ret;
640 641
641 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); 642 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
@@ -646,9 +647,10 @@ int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
646 header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size); 647 header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size);
647 648
648 header.extension = IPC_PPL_LP_MODE(lp_mode); 649 header.extension = IPC_PPL_LP_MODE(lp_mode);
650 request.header = *(u64 *)(&header);
649 651
650 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); 652 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
651 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); 653 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
652 if (ret < 0) { 654 if (ret < 0) {
653 dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret); 655 dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret);
654 return ret; 656 return ret;
@@ -661,16 +663,17 @@ EXPORT_SYMBOL_GPL(skl_ipc_create_pipeline);
661int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id) 663int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
662{ 664{
663 struct skl_ipc_header header = {0}; 665 struct skl_ipc_header header = {0};
664 u64 *ipc_header = (u64 *)(&header); 666 struct sst_ipc_message request = {0};
665 int ret; 667 int ret;
666 668
667 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); 669 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
668 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); 670 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
669 header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL); 671 header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL);
670 header.primary |= IPC_INSTANCE_ID(instance_id); 672 header.primary |= IPC_INSTANCE_ID(instance_id);
673 request.header = *(u64 *)(&header);
671 674
672 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); 675 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
673 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); 676 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
674 if (ret < 0) { 677 if (ret < 0) {
675 dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret); 678 dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret);
676 return ret; 679 return ret;
@@ -684,7 +687,7 @@ int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc,
684 u8 instance_id, enum skl_ipc_pipeline_state state) 687 u8 instance_id, enum skl_ipc_pipeline_state state)
685{ 688{
686 struct skl_ipc_header header = {0}; 689 struct skl_ipc_header header = {0};
687 u64 *ipc_header = (u64 *)(&header); 690 struct sst_ipc_message request = {0};
688 int ret; 691 int ret;
689 692
690 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); 693 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
@@ -692,9 +695,10 @@ int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc,
692 header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE); 695 header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE);
693 header.primary |= IPC_INSTANCE_ID(instance_id); 696 header.primary |= IPC_INSTANCE_ID(instance_id);
694 header.primary |= IPC_PPL_STATE(state); 697 header.primary |= IPC_PPL_STATE(state);
698 request.header = *(u64 *)(&header);
695 699
696 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); 700 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
697 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); 701 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
698 if (ret < 0) { 702 if (ret < 0) {
699 dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret); 703 dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret);
700 return ret; 704 return ret;
@@ -707,7 +711,7 @@ int
707skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id) 711skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id)
708{ 712{
709 struct skl_ipc_header header = {0}; 713 struct skl_ipc_header header = {0};
710 u64 *ipc_header = (u64 *)(&header); 714 struct sst_ipc_message request = {0};
711 int ret; 715 int ret;
712 716
713 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); 717 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
@@ -716,8 +720,10 @@ skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id)
716 header.primary |= IPC_INSTANCE_ID(instance_id); 720 header.primary |= IPC_INSTANCE_ID(instance_id);
717 721
718 header.extension = IPC_DMA_ID(dma_id); 722 header.extension = IPC_DMA_ID(dma_id);
723 request.header = *(u64 *)(&header);
724
719 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); 725 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
720 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); 726 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
721 if (ret < 0) { 727 if (ret < 0) {
722 dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret); 728 dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret);
723 return ret; 729 return ret;
@@ -730,16 +736,17 @@ EXPORT_SYMBOL_GPL(skl_ipc_save_pipeline);
730int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id) 736int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
731{ 737{
732 struct skl_ipc_header header = {0}; 738 struct skl_ipc_header header = {0};
733 u64 *ipc_header = (u64 *)(&header); 739 struct sst_ipc_message request = {0};
734 int ret; 740 int ret;
735 741
736 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); 742 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
737 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); 743 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
738 header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL); 744 header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL);
739 header.primary |= IPC_INSTANCE_ID(instance_id); 745 header.primary |= IPC_INSTANCE_ID(instance_id);
746 request.header = *(u64 *)(&header);
740 747
741 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); 748 dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
742 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); 749 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
743 if (ret < 0) { 750 if (ret < 0) {
744 dev_err(ipc->dev, "ipc: restore pipeline failed, err: %d\n", ret); 751 dev_err(ipc->dev, "ipc: restore pipeline failed, err: %d\n", ret);
745 return ret; 752 return ret;
@@ -753,7 +760,7 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id,
753 u16 module_id, struct skl_ipc_dxstate_info *dx) 760 u16 module_id, struct skl_ipc_dxstate_info *dx)
754{ 761{
755 struct skl_ipc_header header = {0}; 762 struct skl_ipc_header header = {0};
756 u64 *ipc_header = (u64 *)(&header); 763 struct sst_ipc_message request;
757 int ret; 764 int ret;
758 765
759 header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); 766 header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
@@ -762,10 +769,13 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id,
762 header.primary |= IPC_MOD_INSTANCE_ID(instance_id); 769 header.primary |= IPC_MOD_INSTANCE_ID(instance_id);
763 header.primary |= IPC_MOD_ID(module_id); 770 header.primary |= IPC_MOD_ID(module_id);
764 771
772 request.header = *(u64 *)(&header);
773 request.data = dx;
774 request.size = sizeof(*dx);
775
765 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, 776 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
766 header.primary, header.extension); 777 header.primary, header.extension);
767 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, 778 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
768 dx, sizeof(*dx), NULL, 0);
769 if (ret < 0) { 779 if (ret < 0) {
770 dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret); 780 dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret);
771 return ret; 781 return ret;
@@ -779,7 +789,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
779 struct skl_ipc_init_instance_msg *msg, void *param_data) 789 struct skl_ipc_init_instance_msg *msg, void *param_data)
780{ 790{
781 struct skl_ipc_header header = {0}; 791 struct skl_ipc_header header = {0};
782 u64 *ipc_header = (u64 *)(&header); 792 struct sst_ipc_message request;
783 int ret; 793 int ret;
784 u32 *buffer = (u32 *)param_data; 794 u32 *buffer = (u32 *)param_data;
785 /* param_block_size must be in dwords */ 795 /* param_block_size must be in dwords */
@@ -799,10 +809,13 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
799 header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size); 809 header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
800 header.extension |= IPC_DOMAIN(msg->domain); 810 header.extension |= IPC_DOMAIN(msg->domain);
801 811
812 request.header = *(u64 *)(&header);
813 request.data = param_data;
814 request.size = msg->param_data_size;
815
802 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, 816 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
803 header.primary, header.extension); 817 header.primary, header.extension);
804 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, param_data, 818 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
805 msg->param_data_size, NULL, 0);
806 819
807 if (ret < 0) { 820 if (ret < 0) {
808 dev_err(ipc->dev, "ipc: init instance failed\n"); 821 dev_err(ipc->dev, "ipc: init instance failed\n");
@@ -817,7 +830,7 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
817 struct skl_ipc_bind_unbind_msg *msg) 830 struct skl_ipc_bind_unbind_msg *msg)
818{ 831{
819 struct skl_ipc_header header = {0}; 832 struct skl_ipc_header header = {0};
820 u64 *ipc_header = (u64 *)(&header); 833 struct sst_ipc_message request = {0};
821 u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND; 834 u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND;
822 int ret; 835 int ret;
823 836
@@ -831,10 +844,11 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
831 header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id); 844 header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id);
832 header.extension |= IPC_DST_QUEUE(msg->dst_queue); 845 header.extension |= IPC_DST_QUEUE(msg->dst_queue);
833 header.extension |= IPC_SRC_QUEUE(msg->src_queue); 846 header.extension |= IPC_SRC_QUEUE(msg->src_queue);
847 request.header = *(u64 *)(&header);
834 848
835 dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary, 849 dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary,
836 header.extension); 850 header.extension);
837 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); 851 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
838 if (ret < 0) { 852 if (ret < 0) {
839 dev_err(ipc->dev, "ipc: bind/unbind failed\n"); 853 dev_err(ipc->dev, "ipc: bind/unbind failed\n");
840 return ret; 854 return ret;
@@ -854,7 +868,7 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
854 u8 module_cnt, void *data) 868 u8 module_cnt, void *data)
855{ 869{
856 struct skl_ipc_header header = {0}; 870 struct skl_ipc_header header = {0};
857 u64 *ipc_header = (u64 *)(&header); 871 struct sst_ipc_message request;
858 int ret; 872 int ret;
859 873
860 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); 874 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
@@ -862,8 +876,11 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
862 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS); 876 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS);
863 header.primary |= IPC_LOAD_MODULE_CNT(module_cnt); 877 header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
864 878
865 ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, data, 879 request.header = *(u64 *)(&header);
866 (sizeof(u16) * module_cnt)); 880 request.data = data;
881 request.size = sizeof(u16) * module_cnt;
882
883 ret = sst_ipc_tx_message_nowait(ipc, request);
867 if (ret < 0) 884 if (ret < 0)
868 dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret); 885 dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret);
869 886
@@ -875,7 +892,7 @@ int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt,
875 void *data) 892 void *data)
876{ 893{
877 struct skl_ipc_header header = {0}; 894 struct skl_ipc_header header = {0};
878 u64 *ipc_header = (u64 *)(&header); 895 struct sst_ipc_message request;
879 int ret; 896 int ret;
880 897
881 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); 898 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
@@ -883,8 +900,11 @@ int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt,
883 header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS); 900 header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS);
884 header.primary |= IPC_LOAD_MODULE_CNT(module_cnt); 901 header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
885 902
886 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data, 903 request.header = *(u64 *)(&header);
887 (sizeof(u16) * module_cnt), NULL, 0); 904 request.data = data;
905 request.size = sizeof(u16) * module_cnt;
906
907 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
888 if (ret < 0) 908 if (ret < 0)
889 dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret); 909 dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret);
890 910
@@ -896,7 +916,7 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
896 struct skl_ipc_large_config_msg *msg, u32 *param) 916 struct skl_ipc_large_config_msg *msg, u32 *param)
897{ 917{
898 struct skl_ipc_header header = {0}; 918 struct skl_ipc_header header = {0};
899 u64 *ipc_header = (u64 *)(&header); 919 struct sst_ipc_message request;
900 int ret = 0; 920 int ret = 0;
901 size_t sz_remaining, tx_size, data_offset; 921 size_t sz_remaining, tx_size, data_offset;
902 922
@@ -923,9 +943,11 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
923 header.primary, header.extension); 943 header.primary, header.extension);
924 dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n", 944 dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n",
925 (unsigned)data_offset, (unsigned)tx_size); 945 (unsigned)data_offset, (unsigned)tx_size);
926 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, 946
927 ((char *)param) + data_offset, 947 request.header = *(u64 *)(&header);
928 tx_size, NULL, 0); 948 request.data = ((char *)param) + data_offset;
949 request.size = tx_size;
950 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
929 if (ret < 0) { 951 if (ret < 0) {
930 dev_err(ipc->dev, 952 dev_err(ipc->dev,
931 "ipc: set large config fail, err: %d\n", ret); 953 "ipc: set large config fail, err: %d\n", ret);
@@ -947,12 +969,17 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
947EXPORT_SYMBOL_GPL(skl_ipc_set_large_config); 969EXPORT_SYMBOL_GPL(skl_ipc_set_large_config);
948 970
949int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, 971int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
950 struct skl_ipc_large_config_msg *msg, u32 *param) 972 struct skl_ipc_large_config_msg *msg,
973 u32 **payload, size_t *bytes)
951{ 974{
952 struct skl_ipc_header header = {0}; 975 struct skl_ipc_header header = {0};
953 u64 *ipc_header = (u64 *)(&header); 976 struct sst_ipc_message request, reply = {0};
954 int ret = 0; 977 unsigned int *buf;
955 size_t sz_remaining, rx_size, data_offset; 978 int ret;
979
980 reply.data = kzalloc(SKL_ADSP_W1_SZ, GFP_KERNEL);
981 if (!reply.data)
982 return -ENOMEM;
956 983
957 header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); 984 header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
958 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); 985 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
@@ -965,33 +992,21 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
965 header.extension |= IPC_FINAL_BLOCK(1); 992 header.extension |= IPC_FINAL_BLOCK(1);
966 header.extension |= IPC_INITIAL_BLOCK(1); 993 header.extension |= IPC_INITIAL_BLOCK(1);
967 994
968 sz_remaining = msg->param_data_size; 995 request.header = *(u64 *)&header;
969 data_offset = 0; 996 request.data = *payload;
997 request.size = *bytes;
998 reply.size = SKL_ADSP_W1_SZ;
970 999
971 while (sz_remaining != 0) { 1000 ret = sst_ipc_tx_message_wait(ipc, request, &reply);
972 rx_size = sz_remaining > SKL_ADSP_W1_SZ 1001 if (ret < 0)
973 ? SKL_ADSP_W1_SZ : sz_remaining; 1002 dev_err(ipc->dev, "ipc: get large config fail, err: %d\n", ret);
974 if (rx_size == sz_remaining)
975 header.extension |= IPC_FINAL_BLOCK(1);
976
977 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0,
978 ((char *)param) + data_offset,
979 msg->param_data_size);
980 if (ret < 0) {
981 dev_err(ipc->dev,
982 "ipc: get large config fail, err: %d\n", ret);
983 return ret;
984 }
985 sz_remaining -= rx_size;
986 data_offset = msg->param_data_size - sz_remaining;
987 1003
988 /* clear the fields */ 1004 reply.size = (reply.header >> 32) & IPC_DATA_OFFSET_SZ_MASK;
989 header.extension &= IPC_INITIAL_BLOCK_CLEAR; 1005 buf = krealloc(reply.data, reply.size, GFP_KERNEL);
990 header.extension &= IPC_DATA_OFFSET_SZ_CLEAR; 1006 if (!buf)
991 /* fill the fields */ 1007 return -ENOMEM;
992 header.extension |= IPC_INITIAL_BLOCK(1); 1008 *payload = buf;
993 header.extension |= IPC_DATA_OFFSET_SZ(data_offset); 1009 *bytes = reply.size;
994 }
995 1010
996 return ret; 1011 return ret;
997} 1012}
@@ -1001,7 +1016,7 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
1001 u8 dma_id, u8 table_id, bool wait) 1016 u8 dma_id, u8 table_id, bool wait)
1002{ 1017{
1003 struct skl_ipc_header header = {0}; 1018 struct skl_ipc_header header = {0};
1004 u64 *ipc_header = (u64 *)(&header); 1019 struct sst_ipc_message request = {0};
1005 int ret = 0; 1020 int ret = 0;
1006 1021
1007 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); 1022 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
@@ -1009,12 +1024,12 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
1009 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY); 1024 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
1010 header.primary |= IPC_MOD_INSTANCE_ID(table_id); 1025 header.primary |= IPC_MOD_INSTANCE_ID(table_id);
1011 header.primary |= IPC_MOD_ID(dma_id); 1026 header.primary |= IPC_MOD_ID(dma_id);
1027 request.header = *(u64 *)(&header);
1012 1028
1013 if (wait) 1029 if (wait)
1014 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, 1030 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
1015 NULL, 0, NULL, 0);
1016 else 1031 else
1017 ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, NULL, 0); 1032 ret = sst_ipc_tx_message_nowait(ipc, request);
1018 1033
1019 if (ret < 0) 1034 if (ret < 0)
1020 dev_err(ipc->dev, "ipc: load lib failed\n"); 1035 dev_err(ipc->dev, "ipc: load lib failed\n");
@@ -1026,7 +1041,7 @@ EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library);
1026int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg) 1041int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
1027{ 1042{
1028 struct skl_ipc_header header = {0}; 1043 struct skl_ipc_header header = {0};
1029 u64 *ipc_header = (u64 *)(&header); 1044 struct sst_ipc_message request = {0};
1030 int ret; 1045 int ret;
1031 1046
1032 header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); 1047 header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
@@ -1037,6 +1052,7 @@ int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
1037 1052
1038 header.extension = IPC_D0IX_WAKE(msg->wake); 1053 header.extension = IPC_D0IX_WAKE(msg->wake);
1039 header.extension |= IPC_D0IX_STREAMING(msg->streaming); 1054 header.extension |= IPC_D0IX_STREAMING(msg->streaming);
1055 request.header = *(u64 *)(&header);
1040 1056
1041 dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__, 1057 dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__,
1042 header.primary, header.extension); 1058 header.primary, header.extension);
@@ -1044,7 +1060,7 @@ int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
1044 /* 1060 /*
1045 * Use the nopm IPC here as we dont want it checking for D0iX 1061 * Use the nopm IPC here as we dont want it checking for D0iX
1046 */ 1062 */
1047 ret = sst_ipc_tx_message_nopm(ipc, *ipc_header, NULL, 0, NULL, 0); 1063 ret = sst_ipc_tx_message_nopm(ipc, request, NULL);
1048 if (ret < 0) 1064 if (ret < 0)
1049 dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret); 1065 dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret);
1050 1066
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 9c31a48e99dd..08ac31778325 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -10,9 +10,9 @@
10 10
11#include <linux/irqreturn.h> 11#include <linux/irqreturn.h>
12#include "../common/sst-ipc.h" 12#include "../common/sst-ipc.h"
13#include "skl-sst-dsp.h"
13 14
14struct sst_dsp; 15struct sst_dsp;
15struct skl_sst;
16struct sst_generic_ipc; 16struct sst_generic_ipc;
17 17
18enum skl_ipc_pipeline_state { 18enum skl_ipc_pipeline_state {
@@ -67,54 +67,6 @@ struct skl_lib_info {
67 const struct firmware *fw; 67 const struct firmware *fw;
68}; 68};
69 69
70struct skl_sst {
71 struct device *dev;
72 struct sst_dsp *dsp;
73
74 /* boot */
75 wait_queue_head_t boot_wait;
76 bool boot_complete;
77
78 /* module load */
79 wait_queue_head_t mod_load_wait;
80 bool mod_load_complete;
81 bool mod_load_status;
82
83 /* IPC messaging */
84 struct sst_generic_ipc ipc;
85
86 /* callback for miscbdge */
87 void (*enable_miscbdcge)(struct device *dev, bool enable);
88 /* Is CGCTL.MISCBDCGE disabled */
89 bool miscbdcg_disabled;
90
91 /* Populate module information */
92 struct list_head uuid_list;
93
94 /* Is firmware loaded */
95 bool fw_loaded;
96
97 /* first boot ? */
98 bool is_first_boot;
99
100 /* multi-core */
101 struct skl_dsp_cores cores;
102
103 /* library info */
104 struct skl_lib_info lib_info[SKL_MAX_LIB];
105 int lib_count;
106
107 /* Callback to update D0i3C register */
108 void (*update_d0i3c)(struct device *dev, bool enable);
109
110 struct skl_d0i3_data d0i3;
111
112 const struct skl_dsp_ops *dsp_ops;
113
114 /* Callback to update dynamic clock and power gating registers */
115 void (*clock_power_gating)(struct device *dev, bool enable);
116};
117
118struct skl_ipc_init_instance_msg { 70struct skl_ipc_init_instance_msg {
119 u32 module_id; 71 u32 module_id;
120 u32 instance_id; 72 u32 instance_id;
@@ -187,7 +139,8 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
187 struct skl_ipc_large_config_msg *msg, u32 *param); 139 struct skl_ipc_large_config_msg *msg, u32 *param);
188 140
189int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, 141int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
190 struct skl_ipc_large_config_msg *msg, u32 *param); 142 struct skl_ipc_large_config_msg *msg,
143 u32 **payload, size_t *bytes);
191 144
192int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, 145int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
193 u8 dma_id, u8 table_id, bool wait); 146 u8 dma_id, u8 table_id, bool wait);
@@ -204,7 +157,7 @@ void skl_ipc_int_disable(struct sst_dsp *dsp);
204 157
205bool skl_ipc_int_status(struct sst_dsp *dsp); 158bool skl_ipc_int_status(struct sst_dsp *dsp);
206void skl_ipc_free(struct sst_generic_ipc *ipc); 159void skl_ipc_free(struct sst_generic_ipc *ipc);
207int skl_ipc_init(struct device *dev, struct skl_sst *skl); 160int skl_ipc_init(struct device *dev, struct skl_dev *skl);
208void skl_clear_module_cnt(struct sst_dsp *ctx); 161void skl_clear_module_cnt(struct sst_dsp *ctx);
209 162
210void skl_ipc_process_reply(struct sst_generic_ipc *ipc, 163void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
index 928c677b506c..d43cbf4a71ef 100644
--- a/sound/soc/intel/skylake/skl-sst-utils.c
+++ b/sound/soc/intel/skylake/skl-sst-utils.c
@@ -8,10 +8,9 @@
8#include <linux/device.h> 8#include <linux/device.h>
9#include <linux/slab.h> 9#include <linux/slab.h>
10#include <linux/uuid.h> 10#include <linux/uuid.h>
11#include "skl-sst-dsp.h"
12#include "../common/sst-dsp.h" 11#include "../common/sst-dsp.h"
13#include "../common/sst-dsp-priv.h" 12#include "../common/sst-dsp-priv.h"
14#include "skl-sst-ipc.h" 13#include "skl.h"
15 14
16#define DEFAULT_HASH_SHA256_LEN 32 15#define DEFAULT_HASH_SHA256_LEN 32
17 16
@@ -99,12 +98,12 @@ static int skl_get_pvtid_map(struct uuid_module *module, int instance_id)
99 return -EINVAL; 98 return -EINVAL;
100} 99}
101 100
102int skl_get_pvt_instance_id_map(struct skl_sst *ctx, 101int skl_get_pvt_instance_id_map(struct skl_dev *skl,
103 int module_id, int instance_id) 102 int module_id, int instance_id)
104{ 103{
105 struct uuid_module *module; 104 struct uuid_module *module;
106 105
107 list_for_each_entry(module, &ctx->uuid_list, list) { 106 list_for_each_entry(module, &skl->uuid_list, list) {
108 if (module->id == module_id) 107 if (module->id == module_id)
109 return skl_get_pvtid_map(module, instance_id); 108 return skl_get_pvtid_map(module, instance_id);
110 } 109 }
@@ -163,19 +162,19 @@ static inline int skl_pvtid_128(struct uuid_module *module)
163/** 162/**
164 * skl_get_pvt_id: generate a private id for use as module id 163 * skl_get_pvt_id: generate a private id for use as module id
165 * 164 *
166 * @ctx: driver context 165 * @skl: driver context
167 * @uuid_mod: module's uuid 166 * @uuid_mod: module's uuid
168 * @instance_id: module's instance id 167 * @instance_id: module's instance id
169 * 168 *
170 * This generates a 128 bit private unique id for a module TYPE so that 169 * This generates a 128 bit private unique id for a module TYPE so that
171 * module instance is unique 170 * module instance is unique
172 */ 171 */
173int skl_get_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int instance_id) 172int skl_get_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int instance_id)
174{ 173{
175 struct uuid_module *module; 174 struct uuid_module *module;
176 int pvt_id; 175 int pvt_id;
177 176
178 list_for_each_entry(module, &ctx->uuid_list, list) { 177 list_for_each_entry(module, &skl->uuid_list, list) {
179 if (guid_equal(uuid_mod, &module->uuid)) { 178 if (guid_equal(uuid_mod, &module->uuid)) {
180 179
181 pvt_id = skl_pvtid_128(module); 180 pvt_id = skl_pvtid_128(module);
@@ -194,18 +193,18 @@ EXPORT_SYMBOL_GPL(skl_get_pvt_id);
194/** 193/**
195 * skl_put_pvt_id: free up the private id allocated 194 * skl_put_pvt_id: free up the private id allocated
196 * 195 *
197 * @ctx: driver context 196 * @skl: driver context
198 * @uuid_mod: module's uuid 197 * @uuid_mod: module's uuid
199 * @pvt_id: module pvt id 198 * @pvt_id: module pvt id
200 * 199 *
201 * This frees a 128 bit private unique id previously generated 200 * This frees a 128 bit private unique id previously generated
202 */ 201 */
203int skl_put_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int *pvt_id) 202int skl_put_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int *pvt_id)
204{ 203{
205 int i; 204 int i;
206 struct uuid_module *module; 205 struct uuid_module *module;
207 206
208 list_for_each_entry(module, &ctx->uuid_list, list) { 207 list_for_each_entry(module, &skl->uuid_list, list) {
209 if (guid_equal(uuid_mod, &module->uuid)) { 208 if (guid_equal(uuid_mod, &module->uuid)) {
210 209
211 if (*pvt_id != 0) 210 if (*pvt_id != 0)
@@ -234,7 +233,7 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
234 struct adsp_module_entry *mod_entry; 233 struct adsp_module_entry *mod_entry;
235 int i, num_entry, size; 234 int i, num_entry, size;
236 const char *buf; 235 const char *buf;
237 struct skl_sst *skl = ctx->thread_context; 236 struct skl_dev *skl = ctx->thread_context;
238 struct uuid_module *module; 237 struct uuid_module *module;
239 struct firmware stripped_fw; 238 struct firmware stripped_fw;
240 unsigned int safe_file; 239 unsigned int safe_file;
@@ -317,11 +316,11 @@ free_uuid_list:
317 return ret; 316 return ret;
318} 317}
319 318
320void skl_freeup_uuid_list(struct skl_sst *ctx) 319void skl_freeup_uuid_list(struct skl_dev *skl)
321{ 320{
322 struct uuid_module *uuid, *_uuid; 321 struct uuid_module *uuid, *_uuid;
323 322
324 list_for_each_entry_safe(uuid, _uuid, &ctx->uuid_list, list) { 323 list_for_each_entry_safe(uuid, _uuid, &skl->uuid_list, list) {
325 list_del(&uuid->list); 324 list_del(&uuid->list);
326 kfree(uuid); 325 kfree(uuid);
327 } 326 }
@@ -355,16 +354,12 @@ int skl_dsp_strip_extended_manifest(struct firmware *fw)
355} 354}
356 355
357int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, 356int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
358 struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp, 357 struct skl_dsp_loader_ops dsp_ops, struct skl_dev **dsp,
359 struct sst_dsp_device *skl_dev) 358 struct sst_dsp_device *skl_dev)
360{ 359{
361 struct skl_sst *skl; 360 struct skl_dev *skl = *dsp;
362 struct sst_dsp *sst; 361 struct sst_dsp *sst;
363 362
364 skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL);
365 if (skl == NULL)
366 return -ENOMEM;
367
368 skl->dev = dev; 363 skl->dev = dev;
369 skl_dev->thread_context = skl; 364 skl_dev->thread_context = skl;
370 INIT_LIST_HEAD(&skl->uuid_list); 365 INIT_LIST_HEAD(&skl->uuid_list);
@@ -381,13 +376,11 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
381 INIT_LIST_HEAD(&sst->module_list); 376 INIT_LIST_HEAD(&sst->module_list);
382 377
383 skl->is_first_boot = true; 378 skl->is_first_boot = true;
384 if (dsp)
385 *dsp = skl;
386 379
387 return 0; 380 return 0;
388} 381}
389 382
390int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo, 383int skl_prepare_lib_load(struct skl_dev *skl, struct skl_lib_info *linfo,
391 struct firmware *stripped_fw, 384 struct firmware *stripped_fw,
392 unsigned int hdr_offset, int index) 385 unsigned int hdr_offset, int index)
393{ 386{
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index 70c3a604c381..61a8e4756a2b 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -16,7 +16,7 @@
16#include "../common/sst-dsp.h" 16#include "../common/sst-dsp.h"
17#include "../common/sst-dsp-priv.h" 17#include "../common/sst-dsp-priv.h"
18#include "../common/sst-ipc.h" 18#include "../common/sst-ipc.h"
19#include "skl-sst-ipc.h" 19#include "skl.h"
20 20
21#define SKL_BASEFW_TIMEOUT 300 21#define SKL_BASEFW_TIMEOUT 300
22#define SKL_INIT_TIMEOUT 1000 22#define SKL_INIT_TIMEOUT 1000
@@ -66,7 +66,7 @@ static int skl_transfer_firmware(struct sst_dsp *ctx,
66static int skl_load_base_firmware(struct sst_dsp *ctx) 66static int skl_load_base_firmware(struct sst_dsp *ctx)
67{ 67{
68 int ret = 0, i; 68 int ret = 0, i;
69 struct skl_sst *skl = ctx->thread_context; 69 struct skl_dev *skl = ctx->thread_context;
70 struct firmware stripped_fw; 70 struct firmware stripped_fw;
71 u32 reg; 71 u32 reg;
72 72
@@ -161,7 +161,7 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
161{ 161{
162 int ret; 162 int ret;
163 struct skl_ipc_dxstate_info dx; 163 struct skl_ipc_dxstate_info dx;
164 struct skl_sst *skl = ctx->thread_context; 164 struct skl_dev *skl = ctx->thread_context;
165 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); 165 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
166 166
167 /* If core0 is being turned on, we need to load the FW */ 167 /* If core0 is being turned on, we need to load the FW */
@@ -215,7 +215,7 @@ static int skl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
215{ 215{
216 int ret; 216 int ret;
217 struct skl_ipc_dxstate_info dx; 217 struct skl_ipc_dxstate_info dx;
218 struct skl_sst *skl = ctx->thread_context; 218 struct skl_dev *skl = ctx->thread_context;
219 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); 219 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
220 220
221 dx.core_mask = core_mask; 221 dx.core_mask = core_mask;
@@ -332,7 +332,7 @@ static int skl_transfer_module(struct sst_dsp *ctx, const void *data,
332 u32 size, u16 mod_id, u8 table_id, bool is_module) 332 u32 size, u16 mod_id, u8 table_id, bool is_module)
333{ 333{
334 int ret, bytes_left, curr_pos; 334 int ret, bytes_left, curr_pos;
335 struct skl_sst *skl = ctx->thread_context; 335 struct skl_dev *skl = ctx->thread_context;
336 skl->mod_load_complete = false; 336 skl->mod_load_complete = false;
337 337
338 bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, data, size, false); 338 bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, data, size, false);
@@ -384,7 +384,7 @@ out:
384static int 384static int
385skl_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) 385skl_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
386{ 386{
387 struct skl_sst *skl = ctx->thread_context; 387 struct skl_dev *skl = ctx->thread_context;
388 struct firmware stripped_fw; 388 struct firmware stripped_fw;
389 int ret, i; 389 int ret, i;
390 390
@@ -413,8 +413,7 @@ static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid)
413 int ret = 0; 413 int ret = 0;
414 char mod_name[64]; /* guid str = 32 chars + 4 hyphens */ 414 char mod_name[64]; /* guid str = 32 chars + 4 hyphens */
415 415
416 snprintf(mod_name, sizeof(mod_name), "%s%pUL%s", 416 snprintf(mod_name, sizeof(mod_name), "intel/dsp_fw_%pUL.bin", guid);
417 "intel/dsp_fw_", guid, ".bin");
418 417
419 module_entry = skl_module_get_from_id(ctx, mod_id); 418 module_entry = skl_module_get_from_id(ctx, mod_id);
420 if (module_entry == NULL) { 419 if (module_entry == NULL) {
@@ -443,7 +442,7 @@ static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid)
443static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id) 442static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id)
444{ 443{
445 int usage_cnt; 444 int usage_cnt;
446 struct skl_sst *skl = ctx->thread_context; 445 struct skl_dev *skl = ctx->thread_context;
447 int ret = 0; 446 int ret = 0;
448 447
449 usage_cnt = skl_put_module(ctx, mod_id); 448 usage_cnt = skl_put_module(ctx, mod_id);
@@ -518,9 +517,10 @@ static struct sst_dsp_device skl_dev = {
518}; 517};
519 518
520int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 519int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
521 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp) 520 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
521 struct skl_dev **dsp)
522{ 522{
523 struct skl_sst *skl; 523 struct skl_dev *skl;
524 struct sst_dsp *sst; 524 struct sst_dsp *sst;
525 int ret; 525 int ret;
526 526
@@ -554,10 +554,10 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
554} 554}
555EXPORT_SYMBOL_GPL(skl_sst_dsp_init); 555EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
556 556
557int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx) 557int skl_sst_init_fw(struct device *dev, struct skl_dev *skl)
558{ 558{
559 int ret; 559 int ret;
560 struct sst_dsp *sst = ctx->dsp; 560 struct sst_dsp *sst = skl->dsp;
561 561
562 ret = sst->fw_ops.load_fw(sst); 562 ret = sst->fw_ops.load_fw(sst);
563 if (ret < 0) { 563 if (ret < 0) {
@@ -567,32 +567,32 @@ int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
567 567
568 skl_dsp_init_core_state(sst); 568 skl_dsp_init_core_state(sst);
569 569
570 if (ctx->lib_count > 1) { 570 if (skl->lib_count > 1) {
571 ret = sst->fw_ops.load_library(sst, ctx->lib_info, 571 ret = sst->fw_ops.load_library(sst, skl->lib_info,
572 ctx->lib_count); 572 skl->lib_count);
573 if (ret < 0) { 573 if (ret < 0) {
574 dev_err(dev, "Load Library failed : %x\n", ret); 574 dev_err(dev, "Load Library failed : %x\n", ret);
575 return ret; 575 return ret;
576 } 576 }
577 } 577 }
578 ctx->is_first_boot = false; 578 skl->is_first_boot = false;
579 579
580 return 0; 580 return 0;
581} 581}
582EXPORT_SYMBOL_GPL(skl_sst_init_fw); 582EXPORT_SYMBOL_GPL(skl_sst_init_fw);
583 583
584void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 584void skl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl)
585{ 585{
586 586
587 if (ctx->dsp->fw) 587 if (skl->dsp->fw)
588 release_firmware(ctx->dsp->fw); 588 release_firmware(skl->dsp->fw);
589 skl_clear_module_table(ctx->dsp); 589 skl_clear_module_table(skl->dsp);
590 skl_freeup_uuid_list(ctx); 590 skl_freeup_uuid_list(skl);
591 skl_ipc_free(&ctx->ipc); 591 skl_ipc_free(&skl->ipc);
592 ctx->dsp->ops->free(ctx->dsp); 592 skl->dsp->ops->free(skl->dsp);
593 if (ctx->boot_complete) { 593 if (skl->boot_complete) {
594 ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp); 594 skl->dsp->cl_dev.ops.cl_cleanup_controller(skl->dsp);
595 skl_cldma_int_disable(ctx->dsp); 595 skl_cldma_int_disable(skl->dsp);
596 } 596 }
597} 597}
598EXPORT_SYMBOL_GPL(skl_sst_dsp_cleanup); 598EXPORT_SYMBOL_GPL(skl_sst_dsp_cleanup);
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 6241e35213af..69cd7a81bf2a 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -12,6 +12,7 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/firmware.h> 13#include <linux/firmware.h>
14#include <linux/uuid.h> 14#include <linux/uuid.h>
15#include <sound/intel-nhlt.h>
15#include <sound/soc.h> 16#include <sound/soc.h>
16#include <sound/soc-topology.h> 17#include <sound/soc-topology.h>
17#include <uapi/sound/snd_sst_tokens.h> 18#include <uapi/sound/snd_sst_tokens.h>
@@ -45,9 +46,9 @@ static const int mic_quatro_list[][SKL_CH_QUATRO] = {
45#define CHECK_HW_PARAMS(ch, freq, bps, prm_ch, prm_freq, prm_bps) \ 46#define CHECK_HW_PARAMS(ch, freq, bps, prm_ch, prm_freq, prm_bps) \
46 ((ch == prm_ch) && (bps == prm_bps) && (freq == prm_freq)) 47 ((ch == prm_ch) && (bps == prm_bps) && (freq == prm_freq))
47 48
48void skl_tplg_d0i3_get(struct skl *skl, enum d0i3_capability caps) 49void skl_tplg_d0i3_get(struct skl_dev *skl, enum d0i3_capability caps)
49{ 50{
50 struct skl_d0i3_data *d0i3 = &skl->skl_sst->d0i3; 51 struct skl_d0i3_data *d0i3 = &skl->d0i3;
51 52
52 switch (caps) { 53 switch (caps) {
53 case SKL_D0I3_NONE: 54 case SKL_D0I3_NONE:
@@ -64,9 +65,9 @@ void skl_tplg_d0i3_get(struct skl *skl, enum d0i3_capability caps)
64 } 65 }
65} 66}
66 67
67void skl_tplg_d0i3_put(struct skl *skl, enum d0i3_capability caps) 68void skl_tplg_d0i3_put(struct skl_dev *skl, enum d0i3_capability caps)
68{ 69{
69 struct skl_d0i3_data *d0i3 = &skl->skl_sst->d0i3; 70 struct skl_d0i3_data *d0i3 = &skl->d0i3;
70 71
71 switch (caps) { 72 switch (caps) {
72 case SKL_D0I3_NONE: 73 case SKL_D0I3_NONE:
@@ -109,118 +110,23 @@ static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w,
109 } 110 }
110} 111}
111 112
112/* 113static void skl_dump_mconfig(struct skl_dev *skl, struct skl_module_cfg *mcfg)
113 * Each pipelines needs memory to be allocated. Check if we have free memory
114 * from available pool.
115 */
116static bool skl_is_pipe_mem_avail(struct skl *skl,
117 struct skl_module_cfg *mconfig)
118{
119 struct skl_sst *ctx = skl->skl_sst;
120
121 if (skl->resource.mem + mconfig->pipe->memory_pages >
122 skl->resource.max_mem) {
123 dev_err(ctx->dev,
124 "%s: module_id %d instance %d\n", __func__,
125 mconfig->id.module_id,
126 mconfig->id.instance_id);
127 dev_err(ctx->dev,
128 "exceeds ppl memory available %d mem %d\n",
129 skl->resource.max_mem, skl->resource.mem);
130 return false;
131 } else {
132 return true;
133 }
134}
135
136/*
137 * Add the mem to the mem pool. This is freed when pipe is deleted.
138 * Note: DSP does actual memory management we only keep track for complete
139 * pool
140 */
141static void skl_tplg_alloc_pipe_mem(struct skl *skl,
142 struct skl_module_cfg *mconfig)
143{
144 skl->resource.mem += mconfig->pipe->memory_pages;
145}
146
147/*
148 * Pipeline needs needs DSP CPU resources for computation, this is
149 * quantified in MCPS (Million Clocks Per Second) required for module/pipe
150 *
151 * Each pipelines needs mcps to be allocated. Check if we have mcps for this
152 * pipe.
153 */
154
155static bool skl_is_pipe_mcps_avail(struct skl *skl,
156 struct skl_module_cfg *mconfig)
157{
158 struct skl_sst *ctx = skl->skl_sst;
159 u8 res_idx = mconfig->res_idx;
160 struct skl_module_res *res = &mconfig->module->resources[res_idx];
161
162 if (skl->resource.mcps + res->cps > skl->resource.max_mcps) {
163 dev_err(ctx->dev,
164 "%s: module_id %d instance %d\n", __func__,
165 mconfig->id.module_id, mconfig->id.instance_id);
166 dev_err(ctx->dev,
167 "exceeds ppl mcps available %d > mem %d\n",
168 skl->resource.max_mcps, skl->resource.mcps);
169 return false;
170 } else {
171 return true;
172 }
173}
174
175static void skl_tplg_alloc_pipe_mcps(struct skl *skl,
176 struct skl_module_cfg *mconfig)
177{
178 u8 res_idx = mconfig->res_idx;
179 struct skl_module_res *res = &mconfig->module->resources[res_idx];
180
181 skl->resource.mcps += res->cps;
182}
183
184/*
185 * Free the mcps when tearing down
186 */
187static void
188skl_tplg_free_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig)
189{
190 u8 res_idx = mconfig->res_idx;
191 struct skl_module_res *res = &mconfig->module->resources[res_idx];
192
193 skl->resource.mcps -= res->cps;
194}
195
196/*
197 * Free the memory when tearing down
198 */
199static void
200skl_tplg_free_pipe_mem(struct skl *skl, struct skl_module_cfg *mconfig)
201{
202 skl->resource.mem -= mconfig->pipe->memory_pages;
203}
204
205
206static void skl_dump_mconfig(struct skl_sst *ctx,
207 struct skl_module_cfg *mcfg)
208{ 114{
209 struct skl_module_iface *iface = &mcfg->module->formats[0]; 115 struct skl_module_iface *iface = &mcfg->module->formats[0];
210 116
211 dev_dbg(ctx->dev, "Dumping config\n"); 117 dev_dbg(skl->dev, "Dumping config\n");
212 dev_dbg(ctx->dev, "Input Format:\n"); 118 dev_dbg(skl->dev, "Input Format:\n");
213 dev_dbg(ctx->dev, "channels = %d\n", iface->inputs[0].fmt.channels); 119 dev_dbg(skl->dev, "channels = %d\n", iface->inputs[0].fmt.channels);
214 dev_dbg(ctx->dev, "s_freq = %d\n", iface->inputs[0].fmt.s_freq); 120 dev_dbg(skl->dev, "s_freq = %d\n", iface->inputs[0].fmt.s_freq);
215 dev_dbg(ctx->dev, "ch_cfg = %d\n", iface->inputs[0].fmt.ch_cfg); 121 dev_dbg(skl->dev, "ch_cfg = %d\n", iface->inputs[0].fmt.ch_cfg);
216 dev_dbg(ctx->dev, "valid bit depth = %d\n", 122 dev_dbg(skl->dev, "valid bit depth = %d\n",
217 iface->inputs[0].fmt.valid_bit_depth); 123 iface->inputs[0].fmt.valid_bit_depth);
218 dev_dbg(ctx->dev, "Output Format:\n"); 124 dev_dbg(skl->dev, "Output Format:\n");
219 dev_dbg(ctx->dev, "channels = %d\n", iface->outputs[0].fmt.channels); 125 dev_dbg(skl->dev, "channels = %d\n", iface->outputs[0].fmt.channels);
220 dev_dbg(ctx->dev, "s_freq = %d\n", iface->outputs[0].fmt.s_freq); 126 dev_dbg(skl->dev, "s_freq = %d\n", iface->outputs[0].fmt.s_freq);
221 dev_dbg(ctx->dev, "valid bit depth = %d\n", 127 dev_dbg(skl->dev, "valid bit depth = %d\n",
222 iface->outputs[0].fmt.valid_bit_depth); 128 iface->outputs[0].fmt.valid_bit_depth);
223 dev_dbg(ctx->dev, "ch_cfg = %d\n", iface->outputs[0].fmt.ch_cfg); 129 dev_dbg(skl->dev, "ch_cfg = %d\n", iface->outputs[0].fmt.ch_cfg);
224} 130}
225 131
226static void skl_tplg_update_chmap(struct skl_module_fmt *fmt, int chs) 132static void skl_tplg_update_chmap(struct skl_module_fmt *fmt, int chs)
@@ -322,7 +228,7 @@ static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg,
322 * params, so once we have calculate params, we need buffer calculation as 228 * params, so once we have calculate params, we need buffer calculation as
323 * well. 229 * well.
324 */ 230 */
325static void skl_tplg_update_buffer_size(struct skl_sst *ctx, 231static void skl_tplg_update_buffer_size(struct skl_dev *skl,
326 struct skl_module_cfg *mcfg) 232 struct skl_module_cfg *mcfg)
327{ 233{
328 int multiplier = 1; 234 int multiplier = 1;
@@ -374,13 +280,12 @@ static u8 skl_tplg_be_dev_type(int dev_type)
374} 280}
375 281
376static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, 282static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
377 struct skl_sst *ctx) 283 struct skl_dev *skl)
378{ 284{
379 struct skl_module_cfg *m_cfg = w->priv; 285 struct skl_module_cfg *m_cfg = w->priv;
380 int link_type, dir; 286 int link_type, dir;
381 u32 ch, s_freq, s_fmt; 287 u32 ch, s_freq, s_fmt;
382 struct nhlt_specific_cfg *cfg; 288 struct nhlt_specific_cfg *cfg;
383 struct skl *skl = get_skl_ctx(ctx->dev);
384 u8 dev_type = skl_tplg_be_dev_type(m_cfg->dev_type); 289 u8 dev_type = skl_tplg_be_dev_type(m_cfg->dev_type);
385 int fmt_idx = m_cfg->fmt_idx; 290 int fmt_idx = m_cfg->fmt_idx;
386 struct skl_module_iface *m_iface = &m_cfg->module->formats[fmt_idx]; 291 struct skl_module_iface *m_iface = &m_cfg->module->formats[fmt_idx];
@@ -389,7 +294,7 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
389 if (m_cfg->formats_config.caps_size > 0) 294 if (m_cfg->formats_config.caps_size > 0)
390 return 0; 295 return 0;
391 296
392 dev_dbg(ctx->dev, "Applying default cfg blob\n"); 297 dev_dbg(skl->dev, "Applying default cfg blob\n");
393 switch (m_cfg->dev_type) { 298 switch (m_cfg->dev_type) {
394 case SKL_DEVICE_DMIC: 299 case SKL_DEVICE_DMIC:
395 link_type = NHLT_LINK_DMIC; 300 link_type = NHLT_LINK_DMIC;
@@ -425,9 +330,9 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
425 m_cfg->formats_config.caps_size = cfg->size; 330 m_cfg->formats_config.caps_size = cfg->size;
426 m_cfg->formats_config.caps = (u32 *) &cfg->caps; 331 m_cfg->formats_config.caps = (u32 *) &cfg->caps;
427 } else { 332 } else {
428 dev_err(ctx->dev, "Blob NULL for id %x type %d dirn %d\n", 333 dev_err(skl->dev, "Blob NULL for id %x type %d dirn %d\n",
429 m_cfg->vbus_id, link_type, dir); 334 m_cfg->vbus_id, link_type, dir);
430 dev_err(ctx->dev, "PCM: ch %d, freq %d, fmt %d\n", 335 dev_err(skl->dev, "PCM: ch %d, freq %d, fmt %d\n",
431 ch, s_freq, s_fmt); 336 ch, s_freq, s_fmt);
432 return -EIO; 337 return -EIO;
433 } 338 }
@@ -436,7 +341,7 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
436} 341}
437 342
438static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w, 343static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
439 struct skl_sst *ctx) 344 struct skl_dev *skl)
440{ 345{
441 struct skl_module_cfg *m_cfg = w->priv; 346 struct skl_module_cfg *m_cfg = w->priv;
442 struct skl_pipe_params *params = m_cfg->pipe->p_params; 347 struct skl_pipe_params *params = m_cfg->pipe->p_params;
@@ -446,10 +351,10 @@ static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
446 if (!m_cfg->params_fixup) 351 if (!m_cfg->params_fixup)
447 return; 352 return;
448 353
449 dev_dbg(ctx->dev, "Mconfig for widget=%s BEFORE updation\n", 354 dev_dbg(skl->dev, "Mconfig for widget=%s BEFORE updation\n",
450 w->name); 355 w->name);
451 356
452 skl_dump_mconfig(ctx, m_cfg); 357 skl_dump_mconfig(skl, m_cfg);
453 358
454 if (p_conn_type == SKL_PIPE_CONN_TYPE_FE) 359 if (p_conn_type == SKL_PIPE_CONN_TYPE_FE)
455 is_fe = true; 360 is_fe = true;
@@ -457,12 +362,12 @@ static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
457 is_fe = false; 362 is_fe = false;
458 363
459 skl_tplg_update_params_fixup(m_cfg, params, is_fe); 364 skl_tplg_update_params_fixup(m_cfg, params, is_fe);
460 skl_tplg_update_buffer_size(ctx, m_cfg); 365 skl_tplg_update_buffer_size(skl, m_cfg);
461 366
462 dev_dbg(ctx->dev, "Mconfig for widget=%s AFTER updation\n", 367 dev_dbg(skl->dev, "Mconfig for widget=%s AFTER updation\n",
463 w->name); 368 w->name);
464 369
465 skl_dump_mconfig(ctx, m_cfg); 370 skl_dump_mconfig(skl, m_cfg);
466} 371}
467 372
468/* 373/*
@@ -471,7 +376,7 @@ static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
471 * set module params will be done after module is initialised. 376 * set module params will be done after module is initialised.
472 */ 377 */
473static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w, 378static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
474 struct skl_sst *ctx) 379 struct skl_dev *skl)
475{ 380{
476 int i, ret; 381 int i, ret;
477 struct skl_module_cfg *mconfig = w->priv; 382 struct skl_module_cfg *mconfig = w->priv;
@@ -483,7 +388,7 @@ static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
483 if (mconfig->formats_config.caps_size > 0 && 388 if (mconfig->formats_config.caps_size > 0 &&
484 mconfig->formats_config.set_params == SKL_PARAM_SET) { 389 mconfig->formats_config.set_params == SKL_PARAM_SET) {
485 sp_cfg = &mconfig->formats_config; 390 sp_cfg = &mconfig->formats_config;
486 ret = skl_set_module_params(ctx, sp_cfg->caps, 391 ret = skl_set_module_params(skl, sp_cfg->caps,
487 sp_cfg->caps_size, 392 sp_cfg->caps_size,
488 sp_cfg->param_id, mconfig); 393 sp_cfg->param_id, mconfig);
489 if (ret < 0) 394 if (ret < 0)
@@ -497,7 +402,7 @@ static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
497 bc = (struct skl_algo_data *)sb->dobj.private; 402 bc = (struct skl_algo_data *)sb->dobj.private;
498 403
499 if (bc->set_params == SKL_PARAM_SET) { 404 if (bc->set_params == SKL_PARAM_SET) {
500 ret = skl_set_module_params(ctx, 405 ret = skl_set_module_params(skl,
501 (u32 *)bc->params, bc->size, 406 (u32 *)bc->params, bc->size,
502 bc->param_id, mconfig); 407 bc->param_id, mconfig);
503 if (ret < 0) 408 if (ret < 0)
@@ -542,15 +447,15 @@ static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w)
542 return 0; 447 return 0;
543} 448}
544 449
545static int skl_tplg_module_prepare(struct skl_sst *ctx, struct skl_pipe *pipe, 450static int skl_tplg_module_prepare(struct skl_dev *skl, struct skl_pipe *pipe,
546 struct snd_soc_dapm_widget *w, struct skl_module_cfg *mcfg) 451 struct snd_soc_dapm_widget *w, struct skl_module_cfg *mcfg)
547{ 452{
548 switch (mcfg->dev_type) { 453 switch (mcfg->dev_type) {
549 case SKL_DEVICE_HDAHOST: 454 case SKL_DEVICE_HDAHOST:
550 return skl_pcm_host_dma_prepare(ctx->dev, pipe->p_params); 455 return skl_pcm_host_dma_prepare(skl->dev, pipe->p_params);
551 456
552 case SKL_DEVICE_HDALINK: 457 case SKL_DEVICE_HDALINK:
553 return skl_pcm_link_dma_prepare(ctx->dev, pipe->p_params); 458 return skl_pcm_link_dma_prepare(skl->dev, pipe->p_params);
554 } 459 }
555 460
556 return 0; 461 return 0;
@@ -562,12 +467,11 @@ static int skl_tplg_module_prepare(struct skl_sst *ctx, struct skl_pipe *pipe,
562 * skl_init_module() routine, so invoke that for all modules in a pipeline 467 * skl_init_module() routine, so invoke that for all modules in a pipeline
563 */ 468 */
564static int 469static int
565skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) 470skl_tplg_init_pipe_modules(struct skl_dev *skl, struct skl_pipe *pipe)
566{ 471{
567 struct skl_pipe_module *w_module; 472 struct skl_pipe_module *w_module;
568 struct snd_soc_dapm_widget *w; 473 struct snd_soc_dapm_widget *w;
569 struct skl_module_cfg *mconfig; 474 struct skl_module_cfg *mconfig;
570 struct skl_sst *ctx = skl->skl_sst;
571 u8 cfg_idx; 475 u8 cfg_idx;
572 int ret = 0; 476 int ret = 0;
573 477
@@ -578,7 +482,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
578 482
579 /* check if module ids are populated */ 483 /* check if module ids are populated */
580 if (mconfig->id.module_id < 0) { 484 if (mconfig->id.module_id < 0) {
581 dev_err(skl->skl_sst->dev, 485 dev_err(skl->dev,
582 "module %pUL id not populated\n", 486 "module %pUL id not populated\n",
583 (guid_t *)mconfig->guid); 487 (guid_t *)mconfig->guid);
584 return -EIO; 488 return -EIO;
@@ -588,12 +492,8 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
588 mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx; 492 mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx;
589 mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx; 493 mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx;
590 494
591 /* check resource available */ 495 if (mconfig->module->loadable && skl->dsp->fw_ops.load_mod) {
592 if (!skl_is_pipe_mcps_avail(skl, mconfig)) 496 ret = skl->dsp->fw_ops.load_mod(skl->dsp,
593 return -ENOMEM;
594
595 if (mconfig->module->loadable && ctx->dsp->fw_ops.load_mod) {
596 ret = ctx->dsp->fw_ops.load_mod(ctx->dsp,
597 mconfig->id.module_id, mconfig->guid); 497 mconfig->id.module_id, mconfig->guid);
598 if (ret < 0) 498 if (ret < 0)
599 return ret; 499 return ret;
@@ -602,50 +502,50 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
602 } 502 }
603 503
604 /* prepare the DMA if the module is gateway cpr */ 504 /* prepare the DMA if the module is gateway cpr */
605 ret = skl_tplg_module_prepare(ctx, pipe, w, mconfig); 505 ret = skl_tplg_module_prepare(skl, pipe, w, mconfig);
606 if (ret < 0) 506 if (ret < 0)
607 return ret; 507 return ret;
608 508
609 /* update blob if blob is null for be with default value */ 509 /* update blob if blob is null for be with default value */
610 skl_tplg_update_be_blob(w, ctx); 510 skl_tplg_update_be_blob(w, skl);
611 511
612 /* 512 /*
613 * apply fix/conversion to module params based on 513 * apply fix/conversion to module params based on
614 * FE/BE params 514 * FE/BE params
615 */ 515 */
616 skl_tplg_update_module_params(w, ctx); 516 skl_tplg_update_module_params(w, skl);
617 uuid_mod = (guid_t *)mconfig->guid; 517 uuid_mod = (guid_t *)mconfig->guid;
618 mconfig->id.pvt_id = skl_get_pvt_id(ctx, uuid_mod, 518 mconfig->id.pvt_id = skl_get_pvt_id(skl, uuid_mod,
619 mconfig->id.instance_id); 519 mconfig->id.instance_id);
620 if (mconfig->id.pvt_id < 0) 520 if (mconfig->id.pvt_id < 0)
621 return ret; 521 return ret;
622 skl_tplg_set_module_init_data(w); 522 skl_tplg_set_module_init_data(w);
623 523
624 ret = skl_dsp_get_core(ctx->dsp, mconfig->core_id); 524 ret = skl_dsp_get_core(skl->dsp, mconfig->core_id);
625 if (ret < 0) { 525 if (ret < 0) {
626 dev_err(ctx->dev, "Failed to wake up core %d ret=%d\n", 526 dev_err(skl->dev, "Failed to wake up core %d ret=%d\n",
627 mconfig->core_id, ret); 527 mconfig->core_id, ret);
628 return ret; 528 return ret;
629 } 529 }
630 530
631 ret = skl_init_module(ctx, mconfig); 531 ret = skl_init_module(skl, mconfig);
632 if (ret < 0) { 532 if (ret < 0) {
633 skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id); 533 skl_put_pvt_id(skl, uuid_mod, &mconfig->id.pvt_id);
634 goto err; 534 goto err;
635 } 535 }
636 skl_tplg_alloc_pipe_mcps(skl, mconfig); 536
637 ret = skl_tplg_set_module_params(w, ctx); 537 ret = skl_tplg_set_module_params(w, skl);
638 if (ret < 0) 538 if (ret < 0)
639 goto err; 539 goto err;
640 } 540 }
641 541
642 return 0; 542 return 0;
643err: 543err:
644 skl_dsp_put_core(ctx->dsp, mconfig->core_id); 544 skl_dsp_put_core(skl->dsp, mconfig->core_id);
645 return ret; 545 return ret;
646} 546}
647 547
648static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, 548static int skl_tplg_unload_pipe_modules(struct skl_dev *skl,
649 struct skl_pipe *pipe) 549 struct skl_pipe *pipe)
650{ 550{
651 int ret = 0; 551 int ret = 0;
@@ -657,19 +557,19 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
657 mconfig = w_module->w->priv; 557 mconfig = w_module->w->priv;
658 uuid_mod = (guid_t *)mconfig->guid; 558 uuid_mod = (guid_t *)mconfig->guid;
659 559
660 if (mconfig->module->loadable && ctx->dsp->fw_ops.unload_mod && 560 if (mconfig->module->loadable && skl->dsp->fw_ops.unload_mod &&
661 mconfig->m_state > SKL_MODULE_UNINIT) { 561 mconfig->m_state > SKL_MODULE_UNINIT) {
662 ret = ctx->dsp->fw_ops.unload_mod(ctx->dsp, 562 ret = skl->dsp->fw_ops.unload_mod(skl->dsp,
663 mconfig->id.module_id); 563 mconfig->id.module_id);
664 if (ret < 0) 564 if (ret < 0)
665 return -EIO; 565 return -EIO;
666 } 566 }
667 skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id); 567 skl_put_pvt_id(skl, uuid_mod, &mconfig->id.pvt_id);
668 568
669 ret = skl_dsp_put_core(ctx->dsp, mconfig->core_id); 569 ret = skl_dsp_put_core(skl->dsp, mconfig->core_id);
670 if (ret < 0) { 570 if (ret < 0) {
671 /* don't return; continue with other modules */ 571 /* don't return; continue with other modules */
672 dev_err(ctx->dev, "Failed to sleep core %d ret=%d\n", 572 dev_err(skl->dev, "Failed to sleep core %d ret=%d\n",
673 mconfig->core_id, ret); 573 mconfig->core_id, ret);
674 } 574 }
675 } 575 }
@@ -686,9 +586,8 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
686 * 0th configuratation by default for such pipes. 586 * 0th configuratation by default for such pipes.
687 */ 587 */
688static int 588static int
689skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig) 589skl_tplg_get_pipe_config(struct skl_dev *skl, struct skl_module_cfg *mconfig)
690{ 590{
691 struct skl_sst *ctx = skl->skl_sst;
692 struct skl_pipe *pipe = mconfig->pipe; 591 struct skl_pipe *pipe = mconfig->pipe;
693 struct skl_pipe_params *params = pipe->p_params; 592 struct skl_pipe_params *params = pipe->p_params;
694 struct skl_path_config *pconfig = &pipe->configs[0]; 593 struct skl_path_config *pconfig = &pipe->configs[0];
@@ -702,7 +601,7 @@ skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig)
702 } 601 }
703 602
704 if (pipe->conn_type == SKL_PIPE_CONN_TYPE_NONE) { 603 if (pipe->conn_type == SKL_PIPE_CONN_TYPE_NONE) {
705 dev_dbg(ctx->dev, "No conn_type detected, take 0th config\n"); 604 dev_dbg(skl->dev, "No conn_type detected, take 0th config\n");
706 pipe->cur_config_idx = 0; 605 pipe->cur_config_idx = 0;
707 pipe->memory_pages = pconfig->mem_pages; 606 pipe->memory_pages = pconfig->mem_pages;
708 607
@@ -726,13 +625,13 @@ skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig)
726 fmt->channels, fmt->freq, fmt->bps)) { 625 fmt->channels, fmt->freq, fmt->bps)) {
727 pipe->cur_config_idx = i; 626 pipe->cur_config_idx = i;
728 pipe->memory_pages = pconfig->mem_pages; 627 pipe->memory_pages = pconfig->mem_pages;
729 dev_dbg(ctx->dev, "Using pipe config: %d\n", i); 628 dev_dbg(skl->dev, "Using pipe config: %d\n", i);
730 629
731 return 0; 630 return 0;
732 } 631 }
733 } 632 }
734 633
735 dev_err(ctx->dev, "Invalid pipe config: %d %d %d for pipe: %d\n", 634 dev_err(skl->dev, "Invalid pipe config: %d %d %d for pipe: %d\n",
736 params->ch, params->s_freq, params->s_fmt, pipe->ppl_id); 635 params->ch, params->s_freq, params->s_fmt, pipe->ppl_id);
737 return -EINVAL; 636 return -EINVAL;
738} 637}
@@ -740,44 +639,32 @@ skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig)
740/* 639/*
741 * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we 640 * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we
742 * need create the pipeline. So we do following: 641 * need create the pipeline. So we do following:
743 * - check the resources
744 * - Create the pipeline 642 * - Create the pipeline
745 * - Initialize the modules in pipeline 643 * - Initialize the modules in pipeline
746 * - finally bind all modules together 644 * - finally bind all modules together
747 */ 645 */
748static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, 646static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
749 struct skl *skl) 647 struct skl_dev *skl)
750{ 648{
751 int ret; 649 int ret;
752 struct skl_module_cfg *mconfig = w->priv; 650 struct skl_module_cfg *mconfig = w->priv;
753 struct skl_pipe_module *w_module; 651 struct skl_pipe_module *w_module;
754 struct skl_pipe *s_pipe = mconfig->pipe; 652 struct skl_pipe *s_pipe = mconfig->pipe;
755 struct skl_module_cfg *src_module = NULL, *dst_module, *module; 653 struct skl_module_cfg *src_module = NULL, *dst_module, *module;
756 struct skl_sst *ctx = skl->skl_sst;
757 struct skl_module_deferred_bind *modules; 654 struct skl_module_deferred_bind *modules;
758 655
759 ret = skl_tplg_get_pipe_config(skl, mconfig); 656 ret = skl_tplg_get_pipe_config(skl, mconfig);
760 if (ret < 0) 657 if (ret < 0)
761 return ret; 658 return ret;
762 659
763 /* check resource available */
764 if (!skl_is_pipe_mcps_avail(skl, mconfig))
765 return -EBUSY;
766
767 if (!skl_is_pipe_mem_avail(skl, mconfig))
768 return -ENOMEM;
769
770 /* 660 /*
771 * Create a list of modules for pipe. 661 * Create a list of modules for pipe.
772 * This list contains modules from source to sink 662 * This list contains modules from source to sink
773 */ 663 */
774 ret = skl_create_pipeline(ctx, mconfig->pipe); 664 ret = skl_create_pipeline(skl, mconfig->pipe);
775 if (ret < 0) 665 if (ret < 0)
776 return ret; 666 return ret;
777 667
778 skl_tplg_alloc_pipe_mem(skl, mconfig);
779 skl_tplg_alloc_pipe_mcps(skl, mconfig);
780
781 /* Init all pipe modules from source to sink */ 668 /* Init all pipe modules from source to sink */
782 ret = skl_tplg_init_pipe_modules(skl, s_pipe); 669 ret = skl_tplg_init_pipe_modules(skl, s_pipe);
783 if (ret < 0) 670 if (ret < 0)
@@ -792,7 +679,7 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
792 continue; 679 continue;
793 } 680 }
794 681
795 ret = skl_bind_modules(ctx, src_module, dst_module); 682 ret = skl_bind_modules(skl, src_module, dst_module);
796 if (ret < 0) 683 if (ret < 0)
797 return ret; 684 return ret;
798 685
@@ -810,7 +697,7 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
810 list_for_each_entry(modules, &skl->bind_list, node) { 697 list_for_each_entry(modules, &skl->bind_list, node) {
811 module = w_module->w->priv; 698 module = w_module->w->priv;
812 if (modules->dst == module) 699 if (modules->dst == module)
813 skl_bind_modules(ctx, modules->src, 700 skl_bind_modules(skl, modules->src,
814 modules->dst); 701 modules->dst);
815 } 702 }
816 } 703 }
@@ -818,7 +705,7 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
818 return 0; 705 return 0;
819} 706}
820 707
821static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params, 708static int skl_fill_sink_instance_id(struct skl_dev *skl, u32 *params,
822 int size, struct skl_module_cfg *mcfg) 709 int size, struct skl_module_cfg *mcfg)
823{ 710{
824 int i, pvt_id; 711 int i, pvt_id;
@@ -829,7 +716,7 @@ static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params,
829 struct skl_mod_inst_map *inst = kpb_params->u.map; 716 struct skl_mod_inst_map *inst = kpb_params->u.map;
830 717
831 for (i = 0; i < kpb_params->num_modules; i++) { 718 for (i = 0; i < kpb_params->num_modules; i++) {
832 pvt_id = skl_get_pvt_instance_id_map(ctx, inst->mod_id, 719 pvt_id = skl_get_pvt_instance_id_map(skl, inst->mod_id,
833 inst->inst_id); 720 inst->inst_id);
834 if (pvt_id < 0) 721 if (pvt_id < 0)
835 return -EINVAL; 722 return -EINVAL;
@@ -849,7 +736,7 @@ static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params,
849 * send params after binding 736 * send params after binding
850 */ 737 */
851static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, 738static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
852 struct skl_module_cfg *mcfg, struct skl_sst *ctx) 739 struct skl_module_cfg *mcfg, struct skl_dev *skl)
853{ 740{
854 int i, ret; 741 int i, ret;
855 struct skl_module_cfg *mconfig = w->priv; 742 struct skl_module_cfg *mconfig = w->priv;
@@ -876,7 +763,7 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
876 if (mconfig->formats_config.caps_size > 0 && 763 if (mconfig->formats_config.caps_size > 0 &&
877 mconfig->formats_config.set_params == SKL_PARAM_BIND) { 764 mconfig->formats_config.set_params == SKL_PARAM_BIND) {
878 sp_cfg = &mconfig->formats_config; 765 sp_cfg = &mconfig->formats_config;
879 ret = skl_set_module_params(ctx, sp_cfg->caps, 766 ret = skl_set_module_params(skl, sp_cfg->caps,
880 sp_cfg->caps_size, 767 sp_cfg->caps_size,
881 sp_cfg->param_id, mconfig); 768 sp_cfg->param_id, mconfig);
882 if (ret < 0) 769 if (ret < 0)
@@ -894,10 +781,10 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
894 if (!params) 781 if (!params)
895 return -ENOMEM; 782 return -ENOMEM;
896 783
897 skl_fill_sink_instance_id(ctx, params, bc->max, 784 skl_fill_sink_instance_id(skl, params, bc->max,
898 mconfig); 785 mconfig);
899 786
900 ret = skl_set_module_params(ctx, params, 787 ret = skl_set_module_params(skl, params,
901 bc->max, bc->param_id, mconfig); 788 bc->max, bc->param_id, mconfig);
902 kfree(params); 789 kfree(params);
903 790
@@ -910,11 +797,11 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
910 return 0; 797 return 0;
911} 798}
912 799
913static int skl_get_module_id(struct skl_sst *ctx, guid_t *uuid) 800static int skl_get_module_id(struct skl_dev *skl, guid_t *uuid)
914{ 801{
915 struct uuid_module *module; 802 struct uuid_module *module;
916 803
917 list_for_each_entry(module, &ctx->uuid_list, list) { 804 list_for_each_entry(module, &skl->uuid_list, list) {
918 if (guid_equal(uuid, &module->uuid)) 805 if (guid_equal(uuid, &module->uuid))
919 return module->id; 806 return module->id;
920 } 807 }
@@ -922,7 +809,7 @@ static int skl_get_module_id(struct skl_sst *ctx, guid_t *uuid)
922 return -EINVAL; 809 return -EINVAL;
923} 810}
924 811
925static int skl_tplg_find_moduleid_from_uuid(struct skl *skl, 812static int skl_tplg_find_moduleid_from_uuid(struct skl_dev *skl,
926 const struct snd_kcontrol_new *k) 813 const struct snd_kcontrol_new *k)
927{ 814{
928 struct soc_bytes_ext *sb = (void *) k->private_value; 815 struct soc_bytes_ext *sb = (void *) k->private_value;
@@ -942,7 +829,7 @@ static int skl_tplg_find_moduleid_from_uuid(struct skl *skl,
942 params->num_modules = uuid_params->num_modules; 829 params->num_modules = uuid_params->num_modules;
943 830
944 for (i = 0; i < uuid_params->num_modules; i++) { 831 for (i = 0; i < uuid_params->num_modules; i++) {
945 module_id = skl_get_module_id(skl->skl_sst, 832 module_id = skl_get_module_id(skl,
946 &uuid_params->u.map_uuid[i].mod_uuid); 833 &uuid_params->u.map_uuid[i].mod_uuid);
947 if (module_id < 0) { 834 if (module_id < 0) {
948 devm_kfree(bus->dev, params); 835 devm_kfree(bus->dev, params);
@@ -966,7 +853,7 @@ static int skl_tplg_find_moduleid_from_uuid(struct skl *skl,
966 * Retrieve the module id from UUID mentioned in the 853 * Retrieve the module id from UUID mentioned in the
967 * post bind params 854 * post bind params
968 */ 855 */
969void skl_tplg_add_moduleid_in_bind_params(struct skl *skl, 856void skl_tplg_add_moduleid_in_bind_params(struct skl_dev *skl,
970 struct snd_soc_dapm_widget *w) 857 struct snd_soc_dapm_widget *w)
971{ 858{
972 struct skl_module_cfg *mconfig = w->priv; 859 struct skl_module_cfg *mconfig = w->priv;
@@ -985,12 +872,12 @@ void skl_tplg_add_moduleid_in_bind_params(struct skl *skl,
985 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) && 872 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) &&
986 (skl_tplg_find_moduleid_from_uuid(skl, 873 (skl_tplg_find_moduleid_from_uuid(skl,
987 &w->kcontrol_news[i]) < 0)) 874 &w->kcontrol_news[i]) < 0))
988 dev_err(skl->skl_sst->dev, 875 dev_err(skl->dev,
989 "%s: invalid kpb post bind params\n", 876 "%s: invalid kpb post bind params\n",
990 __func__); 877 __func__);
991} 878}
992 879
993static int skl_tplg_module_add_deferred_bind(struct skl *skl, 880static int skl_tplg_module_add_deferred_bind(struct skl_dev *skl,
994 struct skl_module_cfg *src, struct skl_module_cfg *dst) 881 struct skl_module_cfg *src, struct skl_module_cfg *dst)
995{ 882{
996 struct skl_module_deferred_bind *m_list, *modules; 883 struct skl_module_deferred_bind *m_list, *modules;
@@ -1028,26 +915,27 @@ static int skl_tplg_module_add_deferred_bind(struct skl *skl,
1028} 915}
1029 916
1030static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, 917static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
1031 struct skl *skl, 918 struct skl_dev *skl,
1032 struct snd_soc_dapm_widget *src_w, 919 struct snd_soc_dapm_widget *src_w,
1033 struct skl_module_cfg *src_mconfig) 920 struct skl_module_cfg *src_mconfig)
1034{ 921{
1035 struct snd_soc_dapm_path *p; 922 struct snd_soc_dapm_path *p;
1036 struct snd_soc_dapm_widget *sink = NULL, *next_sink = NULL; 923 struct snd_soc_dapm_widget *sink = NULL, *next_sink = NULL;
1037 struct skl_module_cfg *sink_mconfig; 924 struct skl_module_cfg *sink_mconfig;
1038 struct skl_sst *ctx = skl->skl_sst;
1039 int ret; 925 int ret;
1040 926
1041 snd_soc_dapm_widget_for_each_sink_path(w, p) { 927 snd_soc_dapm_widget_for_each_sink_path(w, p) {
1042 if (!p->connect) 928 if (!p->connect)
1043 continue; 929 continue;
1044 930
1045 dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name); 931 dev_dbg(skl->dev,
1046 dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name); 932 "%s: src widget=%s\n", __func__, w->name);
933 dev_dbg(skl->dev,
934 "%s: sink widget=%s\n", __func__, p->sink->name);
1047 935
1048 next_sink = p->sink; 936 next_sink = p->sink;
1049 937
1050 if (!is_skl_dsp_widget_type(p->sink, ctx->dev)) 938 if (!is_skl_dsp_widget_type(p->sink, skl->dev))
1051 return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig); 939 return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig);
1052 940
1053 /* 941 /*
@@ -1056,7 +944,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
1056 * they are ones used for SKL so check that first 944 * they are ones used for SKL so check that first
1057 */ 945 */
1058 if ((p->sink->priv != NULL) && 946 if ((p->sink->priv != NULL) &&
1059 is_skl_dsp_widget_type(p->sink, ctx->dev)) { 947 is_skl_dsp_widget_type(p->sink, skl->dev)) {
1060 948
1061 sink = p->sink; 949 sink = p->sink;
1062 sink_mconfig = sink->priv; 950 sink_mconfig = sink->priv;
@@ -1088,19 +976,21 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
1088 continue; 976 continue;
1089 977
1090 /* Bind source to sink, mixin is always source */ 978 /* Bind source to sink, mixin is always source */
1091 ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig); 979 ret = skl_bind_modules(skl, src_mconfig, sink_mconfig);
1092 if (ret) 980 if (ret)
1093 return ret; 981 return ret;
1094 982
1095 /* set module params after bind */ 983 /* set module params after bind */
1096 skl_tplg_set_module_bind_params(src_w, src_mconfig, ctx); 984 skl_tplg_set_module_bind_params(src_w,
1097 skl_tplg_set_module_bind_params(sink, sink_mconfig, ctx); 985 src_mconfig, skl);
986 skl_tplg_set_module_bind_params(sink,
987 sink_mconfig, skl);
1098 988
1099 /* Start sinks pipe first */ 989 /* Start sinks pipe first */
1100 if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) { 990 if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) {
1101 if (sink_mconfig->pipe->conn_type != 991 if (sink_mconfig->pipe->conn_type !=
1102 SKL_PIPE_CONN_TYPE_FE) 992 SKL_PIPE_CONN_TYPE_FE)
1103 ret = skl_run_pipe(ctx, 993 ret = skl_run_pipe(skl,
1104 sink_mconfig->pipe); 994 sink_mconfig->pipe);
1105 if (ret) 995 if (ret)
1106 return ret; 996 return ret;
@@ -1125,10 +1015,9 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
1125 * - Then run current pipe 1015 * - Then run current pipe
1126 */ 1016 */
1127static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, 1017static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
1128 struct skl *skl) 1018 struct skl_dev *skl)
1129{ 1019{
1130 struct skl_module_cfg *src_mconfig; 1020 struct skl_module_cfg *src_mconfig;
1131 struct skl_sst *ctx = skl->skl_sst;
1132 int ret = 0; 1021 int ret = 0;
1133 1022
1134 src_mconfig = w->priv; 1023 src_mconfig = w->priv;
@@ -1144,25 +1033,24 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
1144 1033
1145 /* Start source pipe last after starting all sinks */ 1034 /* Start source pipe last after starting all sinks */
1146 if (src_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE) 1035 if (src_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
1147 return skl_run_pipe(ctx, src_mconfig->pipe); 1036 return skl_run_pipe(skl, src_mconfig->pipe);
1148 1037
1149 return 0; 1038 return 0;
1150} 1039}
1151 1040
1152static struct snd_soc_dapm_widget *skl_get_src_dsp_widget( 1041static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
1153 struct snd_soc_dapm_widget *w, struct skl *skl) 1042 struct snd_soc_dapm_widget *w, struct skl_dev *skl)
1154{ 1043{
1155 struct snd_soc_dapm_path *p; 1044 struct snd_soc_dapm_path *p;
1156 struct snd_soc_dapm_widget *src_w = NULL; 1045 struct snd_soc_dapm_widget *src_w = NULL;
1157 struct skl_sst *ctx = skl->skl_sst;
1158 1046
1159 snd_soc_dapm_widget_for_each_source_path(w, p) { 1047 snd_soc_dapm_widget_for_each_source_path(w, p) {
1160 src_w = p->source; 1048 src_w = p->source;
1161 if (!p->connect) 1049 if (!p->connect)
1162 continue; 1050 continue;
1163 1051
1164 dev_dbg(ctx->dev, "sink widget=%s\n", w->name); 1052 dev_dbg(skl->dev, "sink widget=%s\n", w->name);
1165 dev_dbg(ctx->dev, "src widget=%s\n", p->source->name); 1053 dev_dbg(skl->dev, "src widget=%s\n", p->source->name);
1166 1054
1167 /* 1055 /*
1168 * here we will check widgets in sink pipelines, so that can 1056 * here we will check widgets in sink pipelines, so that can
@@ -1170,7 +1058,7 @@ static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
1170 * ones used for SKL so check that first 1058 * ones used for SKL so check that first
1171 */ 1059 */
1172 if ((p->source->priv != NULL) && 1060 if ((p->source->priv != NULL) &&
1173 is_skl_dsp_widget_type(p->source, ctx->dev)) { 1061 is_skl_dsp_widget_type(p->source, skl->dev)) {
1174 return p->source; 1062 return p->source;
1175 } 1063 }
1176 } 1064 }
@@ -1191,12 +1079,11 @@ static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
1191 * - start this pipeline 1079 * - start this pipeline
1192 */ 1080 */
1193static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, 1081static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
1194 struct skl *skl) 1082 struct skl_dev *skl)
1195{ 1083{
1196 int ret = 0; 1084 int ret = 0;
1197 struct snd_soc_dapm_widget *source, *sink; 1085 struct snd_soc_dapm_widget *source, *sink;
1198 struct skl_module_cfg *src_mconfig, *sink_mconfig; 1086 struct skl_module_cfg *src_mconfig, *sink_mconfig;
1199 struct skl_sst *ctx = skl->skl_sst;
1200 int src_pipe_started = 0; 1087 int src_pipe_started = 0;
1201 1088
1202 sink = w; 1089 sink = w;
@@ -1222,16 +1109,16 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
1222 } 1109 }
1223 1110
1224 if (src_pipe_started) { 1111 if (src_pipe_started) {
1225 ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig); 1112 ret = skl_bind_modules(skl, src_mconfig, sink_mconfig);
1226 if (ret) 1113 if (ret)
1227 return ret; 1114 return ret;
1228 1115
1229 /* set module params after bind */ 1116 /* set module params after bind */
1230 skl_tplg_set_module_bind_params(source, src_mconfig, ctx); 1117 skl_tplg_set_module_bind_params(source, src_mconfig, skl);
1231 skl_tplg_set_module_bind_params(sink, sink_mconfig, ctx); 1118 skl_tplg_set_module_bind_params(sink, sink_mconfig, skl);
1232 1119
1233 if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE) 1120 if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
1234 ret = skl_run_pipe(ctx, sink_mconfig->pipe); 1121 ret = skl_run_pipe(skl, sink_mconfig->pipe);
1235 } 1122 }
1236 1123
1237 return ret; 1124 return ret;
@@ -1244,16 +1131,15 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
1244 * - unbind with source pipelines if still connected 1131 * - unbind with source pipelines if still connected
1245 */ 1132 */
1246static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w, 1133static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
1247 struct skl *skl) 1134 struct skl_dev *skl)
1248{ 1135{
1249 struct skl_module_cfg *src_mconfig, *sink_mconfig; 1136 struct skl_module_cfg *src_mconfig, *sink_mconfig;
1250 int ret = 0, i; 1137 int ret = 0, i;
1251 struct skl_sst *ctx = skl->skl_sst;
1252 1138
1253 sink_mconfig = w->priv; 1139 sink_mconfig = w->priv;
1254 1140
1255 /* Stop the pipe */ 1141 /* Stop the pipe */
1256 ret = skl_stop_pipe(ctx, sink_mconfig->pipe); 1142 ret = skl_stop_pipe(skl, sink_mconfig->pipe);
1257 if (ret) 1143 if (ret)
1258 return ret; 1144 return ret;
1259 1145
@@ -1263,7 +1149,7 @@ static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
1263 if (!src_mconfig) 1149 if (!src_mconfig)
1264 continue; 1150 continue;
1265 1151
1266 ret = skl_unbind_modules(ctx, 1152 ret = skl_unbind_modules(skl,
1267 src_mconfig, sink_mconfig); 1153 src_mconfig, sink_mconfig);
1268 } 1154 }
1269 } 1155 }
@@ -1273,28 +1159,22 @@ static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
1273 1159
1274/* 1160/*
1275 * in the Post-PMD event of mixer we need to do following: 1161 * in the Post-PMD event of mixer we need to do following:
1276 * - Free the mcps used
1277 * - Free the mem used
1278 * - Unbind the modules within the pipeline 1162 * - Unbind the modules within the pipeline
1279 * - Delete the pipeline (modules are not required to be explicitly 1163 * - Delete the pipeline (modules are not required to be explicitly
1280 * deleted, pipeline delete is enough here 1164 * deleted, pipeline delete is enough here
1281 */ 1165 */
1282static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, 1166static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1283 struct skl *skl) 1167 struct skl_dev *skl)
1284{ 1168{
1285 struct skl_module_cfg *mconfig = w->priv; 1169 struct skl_module_cfg *mconfig = w->priv;
1286 struct skl_pipe_module *w_module; 1170 struct skl_pipe_module *w_module;
1287 struct skl_module_cfg *src_module = NULL, *dst_module; 1171 struct skl_module_cfg *src_module = NULL, *dst_module;
1288 struct skl_sst *ctx = skl->skl_sst;
1289 struct skl_pipe *s_pipe = mconfig->pipe; 1172 struct skl_pipe *s_pipe = mconfig->pipe;
1290 struct skl_module_deferred_bind *modules, *tmp; 1173 struct skl_module_deferred_bind *modules, *tmp;
1291 1174
1292 if (s_pipe->state == SKL_PIPE_INVALID) 1175 if (s_pipe->state == SKL_PIPE_INVALID)
1293 return -EINVAL; 1176 return -EINVAL;
1294 1177
1295 skl_tplg_free_pipe_mcps(skl, mconfig);
1296 skl_tplg_free_pipe_mem(skl, mconfig);
1297
1298 list_for_each_entry(w_module, &s_pipe->w_list, node) { 1178 list_for_each_entry(w_module, &s_pipe->w_list, node) {
1299 if (list_empty(&skl->bind_list)) 1179 if (list_empty(&skl->bind_list))
1300 break; 1180 break;
@@ -1307,7 +1187,7 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1307 * modules from deferred bind list. 1187 * modules from deferred bind list.
1308 */ 1188 */
1309 if (modules->dst == src_module) { 1189 if (modules->dst == src_module) {
1310 skl_unbind_modules(ctx, modules->src, 1190 skl_unbind_modules(skl, modules->src,
1311 modules->dst); 1191 modules->dst);
1312 } 1192 }
1313 1193
@@ -1327,44 +1207,40 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1327 list_for_each_entry(w_module, &s_pipe->w_list, node) { 1207 list_for_each_entry(w_module, &s_pipe->w_list, node) {
1328 dst_module = w_module->w->priv; 1208 dst_module = w_module->w->priv;
1329 1209
1330 if (mconfig->m_state >= SKL_MODULE_INIT_DONE)
1331 skl_tplg_free_pipe_mcps(skl, dst_module);
1332 if (src_module == NULL) { 1210 if (src_module == NULL) {
1333 src_module = dst_module; 1211 src_module = dst_module;
1334 continue; 1212 continue;
1335 } 1213 }
1336 1214
1337 skl_unbind_modules(ctx, src_module, dst_module); 1215 skl_unbind_modules(skl, src_module, dst_module);
1338 src_module = dst_module; 1216 src_module = dst_module;
1339 } 1217 }
1340 1218
1341 skl_delete_pipe(ctx, mconfig->pipe); 1219 skl_delete_pipe(skl, mconfig->pipe);
1342 1220
1343 list_for_each_entry(w_module, &s_pipe->w_list, node) { 1221 list_for_each_entry(w_module, &s_pipe->w_list, node) {
1344 src_module = w_module->w->priv; 1222 src_module = w_module->w->priv;
1345 src_module->m_state = SKL_MODULE_UNINIT; 1223 src_module->m_state = SKL_MODULE_UNINIT;
1346 } 1224 }
1347 1225
1348 return skl_tplg_unload_pipe_modules(ctx, s_pipe); 1226 return skl_tplg_unload_pipe_modules(skl, s_pipe);
1349} 1227}
1350 1228
1351/* 1229/*
1352 * in the Post-PMD event of PGA we need to do following: 1230 * in the Post-PMD event of PGA we need to do following:
1353 * - Free the mcps used
1354 * - Stop the pipeline 1231 * - Stop the pipeline
1355 * - In source pipe is connected, unbind with source pipelines 1232 * - In source pipe is connected, unbind with source pipelines
1356 */ 1233 */
1357static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, 1234static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1358 struct skl *skl) 1235 struct skl_dev *skl)
1359{ 1236{
1360 struct skl_module_cfg *src_mconfig, *sink_mconfig; 1237 struct skl_module_cfg *src_mconfig, *sink_mconfig;
1361 int ret = 0, i; 1238 int ret = 0, i;
1362 struct skl_sst *ctx = skl->skl_sst;
1363 1239
1364 src_mconfig = w->priv; 1240 src_mconfig = w->priv;
1365 1241
1366 /* Stop the pipe since this is a mixin module */ 1242 /* Stop the pipe since this is a mixin module */
1367 ret = skl_stop_pipe(ctx, src_mconfig->pipe); 1243 ret = skl_stop_pipe(skl, src_mconfig->pipe);
1368 if (ret) 1244 if (ret)
1369 return ret; 1245 return ret;
1370 1246
@@ -1377,7 +1253,7 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1377 * This is a connecter and if path is found that means 1253 * This is a connecter and if path is found that means
1378 * unbind between source and sink has not happened yet 1254 * unbind between source and sink has not happened yet
1379 */ 1255 */
1380 ret = skl_unbind_modules(ctx, src_mconfig, 1256 ret = skl_unbind_modules(skl, src_mconfig,
1381 sink_mconfig); 1257 sink_mconfig);
1382 } 1258 }
1383 } 1259 }
@@ -1395,7 +1271,7 @@ static int skl_tplg_mixer_event(struct snd_soc_dapm_widget *w,
1395 struct snd_kcontrol *k, int event) 1271 struct snd_kcontrol *k, int event)
1396{ 1272{
1397 struct snd_soc_dapm_context *dapm = w->dapm; 1273 struct snd_soc_dapm_context *dapm = w->dapm;
1398 struct skl *skl = get_skl_ctx(dapm->dev); 1274 struct skl_dev *skl = get_skl_ctx(dapm->dev);
1399 1275
1400 switch (event) { 1276 switch (event) {
1401 case SND_SOC_DAPM_PRE_PMU: 1277 case SND_SOC_DAPM_PRE_PMU:
@@ -1425,7 +1301,7 @@ static int skl_tplg_pga_event(struct snd_soc_dapm_widget *w,
1425 1301
1426{ 1302{
1427 struct snd_soc_dapm_context *dapm = w->dapm; 1303 struct snd_soc_dapm_context *dapm = w->dapm;
1428 struct skl *skl = get_skl_ctx(dapm->dev); 1304 struct skl_dev *skl = get_skl_ctx(dapm->dev);
1429 1305
1430 switch (event) { 1306 switch (event) {
1431 case SND_SOC_DAPM_PRE_PMU: 1307 case SND_SOC_DAPM_PRE_PMU:
@@ -1446,10 +1322,10 @@ static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol,
1446 struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private; 1322 struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private;
1447 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol); 1323 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
1448 struct skl_module_cfg *mconfig = w->priv; 1324 struct skl_module_cfg *mconfig = w->priv;
1449 struct skl *skl = get_skl_ctx(w->dapm->dev); 1325 struct skl_dev *skl = get_skl_ctx(w->dapm->dev);
1450 1326
1451 if (w->power) 1327 if (w->power)
1452 skl_get_module_params(skl->skl_sst, (u32 *)bc->params, 1328 skl_get_module_params(skl, (u32 *)bc->params,
1453 bc->size, bc->param_id, mconfig); 1329 bc->size, bc->param_id, mconfig);
1454 1330
1455 /* decrement size for TLV header */ 1331 /* decrement size for TLV header */
@@ -1481,7 +1357,7 @@ static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
1481 struct soc_bytes_ext *sb = 1357 struct soc_bytes_ext *sb =
1482 (struct soc_bytes_ext *)kcontrol->private_value; 1358 (struct soc_bytes_ext *)kcontrol->private_value;
1483 struct skl_algo_data *ac = (struct skl_algo_data *)sb->dobj.private; 1359 struct skl_algo_data *ac = (struct skl_algo_data *)sb->dobj.private;
1484 struct skl *skl = get_skl_ctx(w->dapm->dev); 1360 struct skl_dev *skl = get_skl_ctx(w->dapm->dev);
1485 1361
1486 if (ac->params) { 1362 if (ac->params) {
1487 /* 1363 /*
@@ -1498,7 +1374,7 @@ static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
1498 return -EFAULT; 1374 return -EFAULT;
1499 1375
1500 if (w->power) 1376 if (w->power)
1501 return skl_set_module_params(skl->skl_sst, 1377 return skl_set_module_params(skl,
1502 (u32 *)ac->params, ac->size, 1378 (u32 *)ac->params, ac->size,
1503 ac->param_id, mconfig); 1379 ac->param_id, mconfig);
1504 } 1380 }
@@ -1659,7 +1535,7 @@ int skl_tplg_update_pipe_params(struct device *dev,
1659 struct skl_pipe_params *params) 1535 struct skl_pipe_params *params)
1660{ 1536{
1661 struct skl_module_res *res = &mconfig->module->resources[0]; 1537 struct skl_module_res *res = &mconfig->module->resources[0];
1662 struct skl *skl = get_skl_ctx(dev); 1538 struct skl_dev *skl = get_skl_ctx(dev);
1663 struct skl_module_fmt *format = NULL; 1539 struct skl_module_fmt *format = NULL;
1664 u8 cfg_idx = mconfig->pipe->cur_config_idx; 1540 u8 cfg_idx = mconfig->pipe->cur_config_idx;
1665 1541
@@ -1856,7 +1732,7 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
1856 struct skl_pipe_params *params) 1732 struct skl_pipe_params *params)
1857{ 1733{
1858 struct nhlt_specific_cfg *cfg; 1734 struct nhlt_specific_cfg *cfg;
1859 struct skl *skl = get_skl_ctx(dai->dev); 1735 struct skl_dev *skl = get_skl_ctx(dai->dev);
1860 int link_type = skl_tplg_be_link_type(mconfig->dev_type); 1736 int link_type = skl_tplg_be_link_type(mconfig->dev_type);
1861 u8 dev_type = skl_tplg_be_dev_type(mconfig->dev_type); 1737 u8 dev_type = skl_tplg_be_dev_type(mconfig->dev_type);
1862 1738
@@ -2070,7 +1946,7 @@ static int skl_tplg_fill_pipe_tkn(struct device *dev,
2070 * Return an existing pipe if the pipe already exists. 1946 * Return an existing pipe if the pipe already exists.
2071 */ 1947 */
2072static int skl_tplg_add_pipe(struct device *dev, 1948static int skl_tplg_add_pipe(struct device *dev,
2073 struct skl_module_cfg *mconfig, struct skl *skl, 1949 struct skl_module_cfg *mconfig, struct skl_dev *skl,
2074 struct snd_soc_tplg_vendor_value_elem *tkn_elem) 1950 struct snd_soc_tplg_vendor_value_elem *tkn_elem)
2075{ 1951{
2076 struct skl_pipeline *ppl; 1952 struct skl_pipeline *ppl;
@@ -2330,10 +2206,6 @@ static int skl_tplg_fill_res_tkn(struct device *dev,
2330 return -EINVAL; 2206 return -EINVAL;
2331 2207
2332 switch (tkn_elem->token) { 2208 switch (tkn_elem->token) {
2333 case SKL_TKN_MM_U32_CPS:
2334 res->cps = tkn_elem->value;
2335 break;
2336
2337 case SKL_TKN_MM_U32_DMA_SIZE: 2209 case SKL_TKN_MM_U32_DMA_SIZE:
2338 res->dma_buffer_size = tkn_elem->value; 2210 res->dma_buffer_size = tkn_elem->value;
2339 break; 2211 break;
@@ -2354,10 +2226,6 @@ static int skl_tplg_fill_res_tkn(struct device *dev,
2354 res->ibs = tkn_elem->value; 2226 res->ibs = tkn_elem->value;
2355 break; 2227 break;
2356 2228
2357 case SKL_TKN_U32_MAX_MCPS:
2358 res->cps = tkn_elem->value;
2359 break;
2360
2361 case SKL_TKN_MM_U32_RES_PIN_ID: 2229 case SKL_TKN_MM_U32_RES_PIN_ID:
2362 case SKL_TKN_MM_U32_PIN_BUF: 2230 case SKL_TKN_MM_U32_PIN_BUF:
2363 ret = skl_tplg_manifest_pin_res_tkn(dev, tkn_elem, res, 2231 ret = skl_tplg_manifest_pin_res_tkn(dev, tkn_elem, res,
@@ -2366,6 +2234,11 @@ static int skl_tplg_fill_res_tkn(struct device *dev,
2366 return ret; 2234 return ret;
2367 break; 2235 break;
2368 2236
2237 case SKL_TKN_MM_U32_CPS:
2238 case SKL_TKN_U32_MAX_MCPS:
2239 /* ignore unused tokens */
2240 break;
2241
2369 default: 2242 default:
2370 dev_err(dev, "Not a res type token: %d", tkn_elem->token); 2243 dev_err(dev, "Not a res type token: %d", tkn_elem->token);
2371 return -EINVAL; 2244 return -EINVAL;
@@ -2381,7 +2254,7 @@ static int skl_tplg_fill_res_tkn(struct device *dev,
2381 */ 2254 */
2382static int skl_tplg_get_token(struct device *dev, 2255static int skl_tplg_get_token(struct device *dev,
2383 struct snd_soc_tplg_vendor_value_elem *tkn_elem, 2256 struct snd_soc_tplg_vendor_value_elem *tkn_elem,
2384 struct skl *skl, struct skl_module_cfg *mconfig) 2257 struct skl_dev *skl, struct skl_module_cfg *mconfig)
2385{ 2258{
2386 int tkn_count = 0; 2259 int tkn_count = 0;
2387 int ret; 2260 int ret;
@@ -2631,7 +2504,7 @@ static int skl_tplg_get_token(struct device *dev,
2631 * module private data 2504 * module private data
2632 */ 2505 */
2633static int skl_tplg_get_tokens(struct device *dev, 2506static int skl_tplg_get_tokens(struct device *dev,
2634 char *pvt_data, struct skl *skl, 2507 char *pvt_data, struct skl_dev *skl,
2635 struct skl_module_cfg *mconfig, int block_size) 2508 struct skl_module_cfg *mconfig, int block_size)
2636{ 2509{
2637 struct snd_soc_tplg_vendor_array *array; 2510 struct snd_soc_tplg_vendor_array *array;
@@ -2727,8 +2600,8 @@ static int skl_tplg_get_desc_blocks(struct device *dev,
2727 * Otherwise we create a new instance and add into driver list 2600 * Otherwise we create a new instance and add into driver list
2728 */ 2601 */
2729static int skl_tplg_add_pipe_v4(struct device *dev, 2602static int skl_tplg_add_pipe_v4(struct device *dev,
2730 struct skl_module_cfg *mconfig, struct skl *skl, 2603 struct skl_module_cfg *mconfig, struct skl_dev *skl,
2731 struct skl_dfw_v4_pipe *dfw_pipe) 2604 struct skl_dfw_v4_pipe *dfw_pipe)
2732{ 2605{
2733 struct skl_pipeline *ppl; 2606 struct skl_pipeline *ppl;
2734 struct skl_pipe *pipe; 2607 struct skl_pipe *pipe;
@@ -2804,7 +2677,7 @@ static void skl_tplg_fill_fmt_v4(struct skl_module_pin_fmt *dst_fmt,
2804} 2677}
2805 2678
2806static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w, 2679static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
2807 struct skl *skl, struct device *dev, 2680 struct skl_dev *skl, struct device *dev,
2808 struct skl_module_cfg *mconfig) 2681 struct skl_module_cfg *mconfig)
2809{ 2682{
2810 struct skl_dfw_v4_module *dfw = 2683 struct skl_dfw_v4_module *dfw =
@@ -2818,7 +2691,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
2818 return ret; 2691 return ret;
2819 mconfig->id.module_id = -1; 2692 mconfig->id.module_id = -1;
2820 mconfig->id.instance_id = dfw->instance_id; 2693 mconfig->id.instance_id = dfw->instance_id;
2821 mconfig->module->resources[0].cps = dfw->max_mcps; 2694 mconfig->module->resources[0].cpc = dfw->max_mcps / 1000;
2822 mconfig->module->resources[0].ibs = dfw->ibs; 2695 mconfig->module->resources[0].ibs = dfw->ibs;
2823 mconfig->module->resources[0].obs = dfw->obs; 2696 mconfig->module->resources[0].obs = dfw->obs;
2824 mconfig->core_id = dfw->core_id; 2697 mconfig->core_id = dfw->core_id;
@@ -2886,7 +2759,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
2886 * for the type and size of the suceeding data block. 2759 * for the type and size of the suceeding data block.
2887 */ 2760 */
2888static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w, 2761static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
2889 struct skl *skl, struct device *dev, 2762 struct skl_dev *skl, struct device *dev,
2890 struct skl_module_cfg *mconfig) 2763 struct skl_module_cfg *mconfig)
2891{ 2764{
2892 struct snd_soc_tplg_vendor_array *array; 2765 struct snd_soc_tplg_vendor_array *array;
@@ -2981,9 +2854,8 @@ static void skl_clear_pin_config(struct snd_soc_component *component,
2981 } 2854 }
2982} 2855}
2983 2856
2984void skl_cleanup_resources(struct skl *skl) 2857void skl_cleanup_resources(struct skl_dev *skl)
2985{ 2858{
2986 struct skl_sst *ctx = skl->skl_sst;
2987 struct snd_soc_component *soc_component = skl->component; 2859 struct snd_soc_component *soc_component = skl->component;
2988 struct snd_soc_dapm_widget *w; 2860 struct snd_soc_dapm_widget *w;
2989 struct snd_soc_card *card; 2861 struct snd_soc_card *card;
@@ -2995,15 +2867,12 @@ void skl_cleanup_resources(struct skl *skl)
2995 if (!card || !card->instantiated) 2867 if (!card || !card->instantiated)
2996 return; 2868 return;
2997 2869
2998 skl->resource.mem = 0;
2999 skl->resource.mcps = 0;
3000
3001 list_for_each_entry(w, &card->widgets, list) { 2870 list_for_each_entry(w, &card->widgets, list) {
3002 if (is_skl_dsp_widget_type(w, ctx->dev) && w->priv != NULL) 2871 if (is_skl_dsp_widget_type(w, skl->dev) && w->priv != NULL)
3003 skl_clear_pin_config(soc_component, w); 2872 skl_clear_pin_config(soc_component, w);
3004 } 2873 }
3005 2874
3006 skl_clear_module_cnt(ctx->dsp); 2875 skl_clear_module_cnt(skl->dsp);
3007} 2876}
3008 2877
3009/* 2878/*
@@ -3019,7 +2888,7 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, int index,
3019{ 2888{
3020 int ret; 2889 int ret;
3021 struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt); 2890 struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt);
3022 struct skl *skl = bus_to_skl(bus); 2891 struct skl_dev *skl = bus_to_skl(bus);
3023 struct skl_module_cfg *mconfig; 2892 struct skl_module_cfg *mconfig;
3024 2893
3025 if (!tplg_w->priv.size) 2894 if (!tplg_w->priv.size)
@@ -3163,21 +3032,21 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
3163 3032
3164static int skl_tplg_fill_str_mfest_tkn(struct device *dev, 3033static int skl_tplg_fill_str_mfest_tkn(struct device *dev,
3165 struct snd_soc_tplg_vendor_string_elem *str_elem, 3034 struct snd_soc_tplg_vendor_string_elem *str_elem,
3166 struct skl *skl) 3035 struct skl_dev *skl)
3167{ 3036{
3168 int tkn_count = 0; 3037 int tkn_count = 0;
3169 static int ref_count; 3038 static int ref_count;
3170 3039
3171 switch (str_elem->token) { 3040 switch (str_elem->token) {
3172 case SKL_TKN_STR_LIB_NAME: 3041 case SKL_TKN_STR_LIB_NAME:
3173 if (ref_count > skl->skl_sst->lib_count - 1) { 3042 if (ref_count > skl->lib_count - 1) {
3174 ref_count = 0; 3043 ref_count = 0;
3175 return -EINVAL; 3044 return -EINVAL;
3176 } 3045 }
3177 3046
3178 strncpy(skl->skl_sst->lib_info[ref_count].name, 3047 strncpy(skl->lib_info[ref_count].name,
3179 str_elem->string, 3048 str_elem->string,
3180 ARRAY_SIZE(skl->skl_sst->lib_info[ref_count].name)); 3049 ARRAY_SIZE(skl->lib_info[ref_count].name));
3181 ref_count++; 3050 ref_count++;
3182 break; 3051 break;
3183 3052
@@ -3192,7 +3061,7 @@ static int skl_tplg_fill_str_mfest_tkn(struct device *dev,
3192 3061
3193static int skl_tplg_get_str_tkn(struct device *dev, 3062static int skl_tplg_get_str_tkn(struct device *dev,
3194 struct snd_soc_tplg_vendor_array *array, 3063 struct snd_soc_tplg_vendor_array *array,
3195 struct skl *skl) 3064 struct skl_dev *skl)
3196{ 3065{
3197 int tkn_count = 0, ret; 3066 int tkn_count = 0, ret;
3198 struct snd_soc_tplg_vendor_string_elem *str_elem; 3067 struct snd_soc_tplg_vendor_string_elem *str_elem;
@@ -3299,7 +3168,7 @@ static int skl_tplg_fill_mod_info(struct device *dev,
3299 3168
3300static int skl_tplg_get_int_tkn(struct device *dev, 3169static int skl_tplg_get_int_tkn(struct device *dev,
3301 struct snd_soc_tplg_vendor_value_elem *tkn_elem, 3170 struct snd_soc_tplg_vendor_value_elem *tkn_elem,
3302 struct skl *skl) 3171 struct skl_dev *skl)
3303{ 3172{
3304 int tkn_count = 0, ret; 3173 int tkn_count = 0, ret;
3305 static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx; 3174 static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx;
@@ -3319,7 +3188,7 @@ static int skl_tplg_get_int_tkn(struct device *dev,
3319 3188
3320 switch (tkn_elem->token) { 3189 switch (tkn_elem->token) {
3321 case SKL_TKN_U32_LIB_COUNT: 3190 case SKL_TKN_U32_LIB_COUNT:
3322 skl->skl_sst->lib_count = tkn_elem->value; 3191 skl->lib_count = tkn_elem->value;
3323 break; 3192 break;
3324 3193
3325 case SKL_TKN_U8_NUM_MOD: 3194 case SKL_TKN_U8_NUM_MOD:
@@ -3465,35 +3334,17 @@ static int skl_tplg_get_int_tkn(struct device *dev,
3465 return tkn_count; 3334 return tkn_count;
3466} 3335}
3467 3336
3468static int skl_tplg_get_manifest_uuid(struct device *dev,
3469 struct skl *skl,
3470 struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
3471{
3472 static int ref_count;
3473 struct skl_module *mod;
3474
3475 if (uuid_tkn->token == SKL_TKN_UUID) {
3476 mod = skl->modules[ref_count];
3477 guid_copy(&mod->uuid, (guid_t *)&uuid_tkn->uuid);
3478 ref_count++;
3479 } else {
3480 dev_err(dev, "Not an UUID token tkn %d\n", uuid_tkn->token);
3481 return -EINVAL;
3482 }
3483
3484 return 0;
3485}
3486
3487/* 3337/*
3488 * Fill the manifest structure by parsing the tokens based on the 3338 * Fill the manifest structure by parsing the tokens based on the
3489 * type. 3339 * type.
3490 */ 3340 */
3491static int skl_tplg_get_manifest_tkn(struct device *dev, 3341static int skl_tplg_get_manifest_tkn(struct device *dev,
3492 char *pvt_data, struct skl *skl, 3342 char *pvt_data, struct skl_dev *skl,
3493 int block_size) 3343 int block_size)
3494{ 3344{
3495 int tkn_count = 0, ret; 3345 int tkn_count = 0, ret;
3496 int off = 0, tuple_size = 0; 3346 int off = 0, tuple_size = 0;
3347 u8 uuid_index = 0;
3497 struct snd_soc_tplg_vendor_array *array; 3348 struct snd_soc_tplg_vendor_array *array;
3498 struct snd_soc_tplg_vendor_value_elem *tkn_elem; 3349 struct snd_soc_tplg_vendor_value_elem *tkn_elem;
3499 3350
@@ -3516,9 +3367,17 @@ static int skl_tplg_get_manifest_tkn(struct device *dev,
3516 continue; 3367 continue;
3517 3368
3518 case SND_SOC_TPLG_TUPLE_TYPE_UUID: 3369 case SND_SOC_TPLG_TUPLE_TYPE_UUID:
3519 ret = skl_tplg_get_manifest_uuid(dev, skl, array->uuid); 3370 if (array->uuid->token != SKL_TKN_UUID) {
3520 if (ret < 0) 3371 dev_err(dev, "Not an UUID token: %d\n",
3521 return ret; 3372 array->uuid->token);
3373 return -EINVAL;
3374 }
3375 if (uuid_index >= skl->nr_modules) {
3376 dev_err(dev, "Too many UUID tokens\n");
3377 return -EINVAL;
3378 }
3379 guid_copy(&skl->modules[uuid_index++]->uuid,
3380 (guid_t *)&array->uuid->uuid);
3522 3381
3523 tuple_size += sizeof(*array->uuid); 3382 tuple_size += sizeof(*array->uuid);
3524 continue; 3383 continue;
@@ -3550,7 +3409,7 @@ static int skl_tplg_get_manifest_tkn(struct device *dev,
3550 * preceded by descriptors for type and size of data block. 3409 * preceded by descriptors for type and size of data block.
3551 */ 3410 */
3552static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, 3411static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest,
3553 struct device *dev, struct skl *skl) 3412 struct device *dev, struct skl_dev *skl)
3554{ 3413{
3555 struct snd_soc_tplg_vendor_array *array; 3414 struct snd_soc_tplg_vendor_array *array;
3556 int num_blocks, block_size = 0, block_type, off = 0; 3415 int num_blocks, block_size = 0, block_type, off = 0;
@@ -3612,7 +3471,7 @@ static int skl_manifest_load(struct snd_soc_component *cmpnt, int index,
3612 struct snd_soc_tplg_manifest *manifest) 3471 struct snd_soc_tplg_manifest *manifest)
3613{ 3472{
3614 struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt); 3473 struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt);
3615 struct skl *skl = bus_to_skl(bus); 3474 struct skl_dev *skl = bus_to_skl(bus);
3616 3475
3617 /* proceed only if we have private data defined */ 3476 /* proceed only if we have private data defined */
3618 if (manifest->priv.size == 0) 3477 if (manifest->priv.size == 0)
@@ -3620,9 +3479,9 @@ static int skl_manifest_load(struct snd_soc_component *cmpnt, int index,
3620 3479
3621 skl_tplg_get_manifest_data(manifest, bus->dev, skl); 3480 skl_tplg_get_manifest_data(manifest, bus->dev, skl);
3622 3481
3623 if (skl->skl_sst->lib_count > SKL_MAX_LIB) { 3482 if (skl->lib_count > SKL_MAX_LIB) {
3624 dev_err(bus->dev, "Exceeding max Library count. Got:%d\n", 3483 dev_err(bus->dev, "Exceeding max Library count. Got:%d\n",
3625 skl->skl_sst->lib_count); 3484 skl->lib_count);
3626 return -EINVAL; 3485 return -EINVAL;
3627 } 3486 }
3628 3487
@@ -3671,7 +3530,7 @@ static int skl_tplg_create_pipe_widget_list(struct snd_soc_component *component)
3671 return 0; 3530 return 0;
3672} 3531}
3673 3532
3674static void skl_tplg_set_pipe_type(struct skl *skl, struct skl_pipe *pipe) 3533static void skl_tplg_set_pipe_type(struct skl_dev *skl, struct skl_pipe *pipe)
3675{ 3534{
3676 struct skl_pipe_module *w_module; 3535 struct skl_pipe_module *w_module;
3677 struct snd_soc_dapm_widget *w; 3536 struct snd_soc_dapm_widget *w;
@@ -3694,10 +3553,6 @@ static void skl_tplg_set_pipe_type(struct skl *skl, struct skl_pipe *pipe)
3694 pipe->passthru = false; 3553 pipe->passthru = false;
3695} 3554}
3696 3555
3697/* This will be read from topology manifest, currently defined here */
3698#define SKL_MAX_MCPS 30000000
3699#define SKL_FW_MAX_MEM 1000000
3700
3701/* 3556/*
3702 * SKL topology init routine 3557 * SKL topology init routine
3703 */ 3558 */
@@ -3705,7 +3560,7 @@ int skl_tplg_init(struct snd_soc_component *component, struct hdac_bus *bus)
3705{ 3560{
3706 int ret; 3561 int ret;
3707 const struct firmware *fw; 3562 const struct firmware *fw;
3708 struct skl *skl = bus_to_skl(bus); 3563 struct skl_dev *skl = bus_to_skl(bus);
3709 struct skl_pipeline *ppl; 3564 struct skl_pipeline *ppl;
3710 3565
3711 ret = request_firmware(&fw, skl->tplg_name, bus->dev); 3566 ret = request_firmware(&fw, skl->tplg_name, bus->dev);
@@ -3724,31 +3579,30 @@ int skl_tplg_init(struct snd_soc_component *component, struct hdac_bus *bus)
3724 * The complete tplg for SKL is loaded as index 0, we don't use 3579 * The complete tplg for SKL is loaded as index 0, we don't use
3725 * any other index 3580 * any other index
3726 */ 3581 */
3727 ret = snd_soc_tplg_component_load(component, 3582 ret = snd_soc_tplg_component_load(component, &skl_tplg_ops, fw, 0);
3728 &skl_tplg_ops, fw, 0);
3729 if (ret < 0) { 3583 if (ret < 0) {
3730 dev_err(bus->dev, "tplg component load failed%d\n", ret); 3584 dev_err(bus->dev, "tplg component load failed%d\n", ret);
3731 release_firmware(fw); 3585 goto err;
3732 return -EINVAL;
3733 } 3586 }
3734 3587
3735 skl->resource.max_mcps = SKL_MAX_MCPS;
3736 skl->resource.max_mem = SKL_FW_MAX_MEM;
3737
3738 skl->tplg = fw;
3739 ret = skl_tplg_create_pipe_widget_list(component); 3588 ret = skl_tplg_create_pipe_widget_list(component);
3740 if (ret < 0) 3589 if (ret < 0) {
3741 return ret; 3590 dev_err(bus->dev, "tplg create pipe widget list failed%d\n",
3591 ret);
3592 goto err;
3593 }
3742 3594
3743 list_for_each_entry(ppl, &skl->ppl_list, node) 3595 list_for_each_entry(ppl, &skl->ppl_list, node)
3744 skl_tplg_set_pipe_type(skl, ppl->pipe); 3596 skl_tplg_set_pipe_type(skl, ppl->pipe);
3745 3597
3746 return 0; 3598err:
3599 release_firmware(fw);
3600 return ret;
3747} 3601}
3748 3602
3749void skl_tplg_exit(struct snd_soc_component *component, struct hdac_bus *bus) 3603void skl_tplg_exit(struct snd_soc_component *component, struct hdac_bus *bus)
3750{ 3604{
3751 struct skl *skl = bus_to_skl(bus); 3605 struct skl_dev *skl = bus_to_skl(bus);
3752 struct skl_pipeline *ppl, *tmp; 3606 struct skl_pipeline *ppl, *tmp;
3753 3607
3754 if (!list_empty(&skl->ppl_list)) 3608 if (!list_empty(&skl->ppl_list))
@@ -3757,6 +3611,4 @@ void skl_tplg_exit(struct snd_soc_component *component, struct hdac_bus *bus)
3757 3611
3758 /* clean up topology */ 3612 /* clean up topology */
3759 snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL); 3613 snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL);
3760
3761 release_firmware(skl->tplg);
3762} 3614}
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index 665e35cee50d..e967800dbb62 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -101,7 +101,7 @@ struct skl_audio_data_format {
101} __packed; 101} __packed;
102 102
103struct skl_base_cfg { 103struct skl_base_cfg {
104 u32 cps; 104 u32 cpc;
105 u32 ibs; 105 u32 ibs;
106 u32 obs; 106 u32 obs;
107 u32 is_pages; 107 u32 is_pages;
@@ -140,11 +140,6 @@ struct skl_src_module_cfg {
140 enum skl_s_freq src_cfg; 140 enum skl_s_freq src_cfg;
141} __packed; 141} __packed;
142 142
143struct notification_mask {
144 u32 notify;
145 u32 enable;
146} __packed;
147
148struct skl_up_down_mixer_cfg { 143struct skl_up_down_mixer_cfg {
149 struct skl_base_cfg base_cfg; 144 struct skl_base_cfg base_cfg;
150 enum skl_ch_cfg out_ch_cfg; 145 enum skl_ch_cfg out_ch_cfg;
@@ -348,7 +343,6 @@ struct skl_module_pin_resources {
348struct skl_module_res { 343struct skl_module_res {
349 u8 id; 344 u8 id;
350 u32 is_pages; 345 u32 is_pages;
351 u32 cps;
352 u32 ibs; 346 u32 ibs;
353 u32 obs; 347 u32 obs;
354 u32 dma_buffer_size; 348 u32 dma_buffer_size;
@@ -389,9 +383,6 @@ struct skl_module_cfg {
389 u8 out_queue_mask; 383 u8 out_queue_mask;
390 u8 in_queue; 384 u8 in_queue;
391 u8 out_queue; 385 u8 out_queue;
392 u32 mcps;
393 u32 ibs;
394 u32 obs;
395 u8 is_loadable; 386 u8 is_loadable;
396 u8 core_id; 387 u8 core_id;
397 u8 dev_type; 388 u8 dev_type;
@@ -447,7 +438,7 @@ enum skl_channel {
447 SKL_CH_QUATRO = 4, 438 SKL_CH_QUATRO = 4,
448}; 439};
449 440
450static inline struct skl *get_skl_ctx(struct device *dev) 441static inline struct skl_dev *get_skl_ctx(struct device *dev)
451{ 442{
452 struct hdac_bus *bus = dev_get_drvdata(dev); 443 struct hdac_bus *bus = dev_get_drvdata(dev);
453 444
@@ -456,7 +447,7 @@ static inline struct skl *get_skl_ctx(struct device *dev)
456 447
457int skl_tplg_be_update_params(struct snd_soc_dai *dai, 448int skl_tplg_be_update_params(struct snd_soc_dai *dai,
458 struct skl_pipe_params *params); 449 struct skl_pipe_params *params);
459int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps, 450int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps,
460 u32 caps_size, u32 node_id); 451 u32 caps_size, u32 node_id);
461void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai, 452void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,
462 struct skl_pipe_params *params, int stream); 453 struct skl_pipe_params *params, int stream);
@@ -469,32 +460,32 @@ struct skl_module_cfg *skl_tplg_fe_get_cpr_module(
469int skl_tplg_update_pipe_params(struct device *dev, 460int skl_tplg_update_pipe_params(struct device *dev,
470 struct skl_module_cfg *mconfig, struct skl_pipe_params *params); 461 struct skl_module_cfg *mconfig, struct skl_pipe_params *params);
471 462
472void skl_tplg_d0i3_get(struct skl *skl, enum d0i3_capability caps); 463void skl_tplg_d0i3_get(struct skl_dev *skl, enum d0i3_capability caps);
473void skl_tplg_d0i3_put(struct skl *skl, enum d0i3_capability caps); 464void skl_tplg_d0i3_put(struct skl_dev *skl, enum d0i3_capability caps);
474 465
475int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe); 466int skl_create_pipeline(struct skl_dev *skl, struct skl_pipe *pipe);
476 467
477int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); 468int skl_run_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
478 469
479int skl_pause_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); 470int skl_pause_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
480 471
481int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); 472int skl_delete_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
482 473
483int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); 474int skl_stop_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
484 475
485int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); 476int skl_reset_pipe(struct skl_dev *skl, struct skl_pipe *pipe);
486 477
487int skl_init_module(struct skl_sst *ctx, struct skl_module_cfg *module_config); 478int skl_init_module(struct skl_dev *skl, struct skl_module_cfg *module_config);
488 479
489int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg 480int skl_bind_modules(struct skl_dev *skl, struct skl_module_cfg
490 *src_module, struct skl_module_cfg *dst_module); 481 *src_module, struct skl_module_cfg *dst_module);
491 482
492int skl_unbind_modules(struct skl_sst *ctx, struct skl_module_cfg 483int skl_unbind_modules(struct skl_dev *skl, struct skl_module_cfg
493 *src_module, struct skl_module_cfg *dst_module); 484 *src_module, struct skl_module_cfg *dst_module);
494 485
495int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size, 486int skl_set_module_params(struct skl_dev *skl, u32 *params, int size,
496 u32 param_id, struct skl_module_cfg *mcfg); 487 u32 param_id, struct skl_module_cfg *mcfg);
497int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size, 488int skl_get_module_params(struct skl_dev *skl, u32 *params, int size,
498 u32 param_id, struct skl_module_cfg *mcfg); 489 u32 param_id, struct skl_module_cfg *mcfg);
499 490
500struct skl_module_cfg *skl_tplg_be_get_cpr_module(struct snd_soc_dai *dai, 491struct skl_module_cfg *skl_tplg_be_get_cpr_module(struct snd_soc_dai *dai,
@@ -508,6 +499,6 @@ int skl_pcm_link_dma_prepare(struct device *dev,
508int skl_dai_load(struct snd_soc_component *cmp, int index, 499int skl_dai_load(struct snd_soc_component *cmp, int index,
509 struct snd_soc_dai_driver *dai_drv, 500 struct snd_soc_dai_driver *dai_drv,
510 struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai); 501 struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai);
511void skl_tplg_add_moduleid_in_bind_params(struct skl *skl, 502void skl_tplg_add_moduleid_in_bind_params(struct skl_dev *skl,
512 struct snd_soc_dapm_widget *w); 503 struct snd_soc_dapm_widget *w);
513#endif 504#endif
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 3362e71b4563..141dbbf975ac 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -26,9 +26,11 @@
26#include <sound/hdaudio.h> 26#include <sound/hdaudio.h>
27#include <sound/hda_i915.h> 27#include <sound/hda_i915.h>
28#include <sound/hda_codec.h> 28#include <sound/hda_codec.h>
29#include <sound/intel-nhlt.h>
29#include "skl.h" 30#include "skl.h"
30#include "skl-sst-dsp.h" 31#include "skl-sst-dsp.h"
31#include "skl-sst-ipc.h" 32#include "skl-sst-ipc.h"
33
32#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) 34#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
33#include "../../../soc/codecs/hdac_hda.h" 35#include "../../../soc/codecs/hdac_hda.h"
34#endif 36#endif
@@ -50,7 +52,7 @@ static void skl_update_pci_byte(struct pci_dev *pci, unsigned int reg,
50 pci_write_config_byte(pci, reg, data); 52 pci_write_config_byte(pci, reg, data);
51} 53}
52 54
53static void skl_init_pci(struct skl *skl) 55static void skl_init_pci(struct skl_dev *skl)
54{ 56{
55 struct hdac_bus *bus = skl_to_bus(skl); 57 struct hdac_bus *bus = skl_to_bus(skl);
56 58
@@ -132,7 +134,7 @@ static int skl_init_chip(struct hdac_bus *bus, bool full_reset)
132 134
133 /* Reset stream-to-link mapping */ 135 /* Reset stream-to-link mapping */
134 list_for_each_entry(hlink, &bus->hlink_list, list) 136 list_for_each_entry(hlink, &bus->hlink_list, list)
135 bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV); 137 writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
136 138
137 skl_enable_miscbdcge(bus->dev, true); 139 skl_enable_miscbdcge(bus->dev, true);
138 140
@@ -252,7 +254,7 @@ static irqreturn_t skl_threaded_handler(int irq, void *dev_id)
252 254
253static int skl_acquire_irq(struct hdac_bus *bus, int do_disconnect) 255static int skl_acquire_irq(struct hdac_bus *bus, int do_disconnect)
254{ 256{
255 struct skl *skl = bus_to_skl(bus); 257 struct skl_dev *skl = bus_to_skl(bus);
256 int ret; 258 int ret;
257 259
258 ret = request_threaded_irq(skl->pci->irq, skl_interrupt, 260 ret = request_threaded_irq(skl->pci->irq, skl_interrupt,
@@ -276,7 +278,7 @@ static int skl_suspend_late(struct device *dev)
276{ 278{
277 struct pci_dev *pci = to_pci_dev(dev); 279 struct pci_dev *pci = to_pci_dev(dev);
278 struct hdac_bus *bus = pci_get_drvdata(pci); 280 struct hdac_bus *bus = pci_get_drvdata(pci);
279 struct skl *skl = bus_to_skl(bus); 281 struct skl_dev *skl = bus_to_skl(bus);
280 282
281 return skl_suspend_late_dsp(skl); 283 return skl_suspend_late_dsp(skl);
282} 284}
@@ -284,7 +286,7 @@ static int skl_suspend_late(struct device *dev)
284#ifdef CONFIG_PM 286#ifdef CONFIG_PM
285static int _skl_suspend(struct hdac_bus *bus) 287static int _skl_suspend(struct hdac_bus *bus)
286{ 288{
287 struct skl *skl = bus_to_skl(bus); 289 struct skl_dev *skl = bus_to_skl(bus);
288 struct pci_dev *pci = to_pci_dev(bus->dev); 290 struct pci_dev *pci = to_pci_dev(bus->dev);
289 int ret; 291 int ret;
290 292
@@ -307,7 +309,7 @@ static int _skl_suspend(struct hdac_bus *bus)
307 309
308static int _skl_resume(struct hdac_bus *bus) 310static int _skl_resume(struct hdac_bus *bus)
309{ 311{
310 struct skl *skl = bus_to_skl(bus); 312 struct skl_dev *skl = bus_to_skl(bus);
311 313
312 skl_init_pci(skl); 314 skl_init_pci(skl);
313 skl_dum_set(bus); 315 skl_dum_set(bus);
@@ -325,7 +327,7 @@ static int skl_suspend(struct device *dev)
325{ 327{
326 struct pci_dev *pci = to_pci_dev(dev); 328 struct pci_dev *pci = to_pci_dev(dev);
327 struct hdac_bus *bus = pci_get_drvdata(pci); 329 struct hdac_bus *bus = pci_get_drvdata(pci);
328 struct skl *skl = bus_to_skl(bus); 330 struct skl_dev *skl = bus_to_skl(bus);
329 int ret; 331 int ret;
330 332
331 /* 333 /*
@@ -345,7 +347,7 @@ static int skl_suspend(struct device *dev)
345 ret = _skl_suspend(bus); 347 ret = _skl_suspend(bus);
346 if (ret < 0) 348 if (ret < 0)
347 return ret; 349 return ret;
348 skl->skl_sst->fw_loaded = false; 350 skl->fw_loaded = false;
349 } 351 }
350 352
351 return 0; 353 return 0;
@@ -355,7 +357,7 @@ static int skl_resume(struct device *dev)
355{ 357{
356 struct pci_dev *pci = to_pci_dev(dev); 358 struct pci_dev *pci = to_pci_dev(dev);
357 struct hdac_bus *bus = pci_get_drvdata(pci); 359 struct hdac_bus *bus = pci_get_drvdata(pci);
358 struct skl *skl = bus_to_skl(bus); 360 struct skl_dev *skl = bus_to_skl(bus);
359 struct hdac_ext_link *hlink = NULL; 361 struct hdac_ext_link *hlink = NULL;
360 int ret; 362 int ret;
361 363
@@ -430,7 +432,7 @@ static const struct dev_pm_ops skl_pm = {
430 */ 432 */
431static int skl_free(struct hdac_bus *bus) 433static int skl_free(struct hdac_bus *bus)
432{ 434{
433 struct skl *skl = bus_to_skl(bus); 435 struct skl_dev *skl = bus_to_skl(bus);
434 436
435 skl->init_done = 0; /* to be sure */ 437 skl->init_done = 0; /* to be sure */
436 438
@@ -475,7 +477,7 @@ static struct skl_ssp_clk skl_ssp_clks[] = {
475 {.name = "ssp5_sclkfs"}, 477 {.name = "ssp5_sclkfs"},
476}; 478};
477 479
478static struct snd_soc_acpi_mach *skl_find_hda_machine(struct skl *skl, 480static struct snd_soc_acpi_mach *skl_find_hda_machine(struct skl_dev *skl,
479 struct snd_soc_acpi_mach *machines) 481 struct snd_soc_acpi_mach *machines)
480{ 482{
481 struct hdac_bus *bus = skl_to_bus(skl); 483 struct hdac_bus *bus = skl_to_bus(skl);
@@ -494,7 +496,7 @@ static struct snd_soc_acpi_mach *skl_find_hda_machine(struct skl *skl,
494 return mach; 496 return mach;
495} 497}
496 498
497static int skl_find_machine(struct skl *skl, void *driver_data) 499static int skl_find_machine(struct skl_dev *skl, void *driver_data)
498{ 500{
499 struct hdac_bus *bus = skl_to_bus(skl); 501 struct hdac_bus *bus = skl_to_bus(skl);
500 struct snd_soc_acpi_mach *mach = driver_data; 502 struct snd_soc_acpi_mach *mach = driver_data;
@@ -516,13 +518,15 @@ static int skl_find_machine(struct skl *skl, void *driver_data)
516 518
517 if (pdata) { 519 if (pdata) {
518 skl->use_tplg_pcm = pdata->use_tplg_pcm; 520 skl->use_tplg_pcm = pdata->use_tplg_pcm;
519 mach->mach_params.dmic_num = skl_get_dmic_geo(skl); 521 mach->mach_params.dmic_num =
522 intel_nhlt_get_dmic_geo(&skl->pci->dev,
523 skl->nhlt);
520 } 524 }
521 525
522 return 0; 526 return 0;
523} 527}
524 528
525static int skl_machine_device_register(struct skl *skl) 529static int skl_machine_device_register(struct skl_dev *skl)
526{ 530{
527 struct snd_soc_acpi_mach *mach = skl->mach; 531 struct snd_soc_acpi_mach *mach = skl->mach;
528 struct hdac_bus *bus = skl_to_bus(skl); 532 struct hdac_bus *bus = skl_to_bus(skl);
@@ -558,13 +562,13 @@ static int skl_machine_device_register(struct skl *skl)
558 return 0; 562 return 0;
559} 563}
560 564
561static void skl_machine_device_unregister(struct skl *skl) 565static void skl_machine_device_unregister(struct skl_dev *skl)
562{ 566{
563 if (skl->i2s_dev) 567 if (skl->i2s_dev)
564 platform_device_unregister(skl->i2s_dev); 568 platform_device_unregister(skl->i2s_dev);
565} 569}
566 570
567static int skl_dmic_device_register(struct skl *skl) 571static int skl_dmic_device_register(struct skl_dev *skl)
568{ 572{
569 struct hdac_bus *bus = skl_to_bus(skl); 573 struct hdac_bus *bus = skl_to_bus(skl);
570 struct platform_device *pdev; 574 struct platform_device *pdev;
@@ -588,7 +592,7 @@ static int skl_dmic_device_register(struct skl *skl)
588 return 0; 592 return 0;
589} 593}
590 594
591static void skl_dmic_device_unregister(struct skl *skl) 595static void skl_dmic_device_unregister(struct skl_dev *skl)
592{ 596{
593 if (skl->dmic_dev) 597 if (skl->dmic_dev)
594 platform_device_unregister(skl->dmic_dev); 598 platform_device_unregister(skl->dmic_dev);
@@ -626,7 +630,7 @@ static void init_skl_xtal_rate(int pci_id)
626 } 630 }
627} 631}
628 632
629static int skl_clock_device_register(struct skl *skl) 633static int skl_clock_device_register(struct skl_dev *skl)
630{ 634{
631 struct platform_device_info pdevinfo = {NULL}; 635 struct platform_device_info pdevinfo = {NULL};
632 struct skl_clk_pdata *clk_pdata; 636 struct skl_clk_pdata *clk_pdata;
@@ -656,7 +660,7 @@ static int skl_clock_device_register(struct skl *skl)
656 return PTR_ERR_OR_ZERO(skl->clk_dev); 660 return PTR_ERR_OR_ZERO(skl->clk_dev);
657} 661}
658 662
659static void skl_clock_device_unregister(struct skl *skl) 663static void skl_clock_device_unregister(struct skl_dev *skl)
660{ 664{
661 if (skl->clk_dev) 665 if (skl->clk_dev)
662 platform_device_unregister(skl->clk_dev); 666 platform_device_unregister(skl->clk_dev);
@@ -692,7 +696,7 @@ static int probe_codec(struct hdac_bus *bus, int addr)
692 unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) | 696 unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
693 (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; 697 (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
694 unsigned int res = -1; 698 unsigned int res = -1;
695 struct skl *skl = bus_to_skl(bus); 699 struct skl_dev *skl = bus_to_skl(bus);
696#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) 700#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
697 struct hdac_hda_priv *hda_codec; 701 struct hdac_hda_priv *hda_codec;
698 int err; 702 int err;
@@ -792,7 +796,7 @@ static int skl_i915_init(struct hdac_bus *bus)
792 796
793static void skl_probe_work(struct work_struct *work) 797static void skl_probe_work(struct work_struct *work)
794{ 798{
795 struct skl *skl = container_of(work, struct skl, probe_work); 799 struct skl_dev *skl = container_of(work, struct skl_dev, probe_work);
796 struct hdac_bus *bus = skl_to_bus(skl); 800 struct hdac_bus *bus = skl_to_bus(skl);
797 struct hdac_ext_link *hlink = NULL; 801 struct hdac_ext_link *hlink = NULL;
798 int err; 802 int err;
@@ -854,11 +858,10 @@ out_err:
854 * constructor 858 * constructor
855 */ 859 */
856static int skl_create(struct pci_dev *pci, 860static int skl_create(struct pci_dev *pci,
857 const struct hdac_io_ops *io_ops, 861 struct skl_dev **rskl)
858 struct skl **rskl)
859{ 862{
860 struct hdac_ext_bus_ops *ext_ops = NULL; 863 struct hdac_ext_bus_ops *ext_ops = NULL;
861 struct skl *skl; 864 struct skl_dev *skl;
862 struct hdac_bus *bus; 865 struct hdac_bus *bus;
863 struct hda_bus *hbus; 866 struct hda_bus *hbus;
864 int err; 867 int err;
@@ -884,7 +887,7 @@ static int skl_create(struct pci_dev *pci,
884#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) 887#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
885 ext_ops = snd_soc_hdac_hda_get_ops(); 888 ext_ops = snd_soc_hdac_hda_get_ops();
886#endif 889#endif
887 snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, io_ops, ext_ops); 890 snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, ext_ops);
888 bus->use_posbuf = 1; 891 bus->use_posbuf = 1;
889 skl->pci = pci; 892 skl->pci = pci;
890 INIT_WORK(&skl->probe_work, skl_probe_work); 893 INIT_WORK(&skl->probe_work, skl_probe_work);
@@ -902,7 +905,7 @@ static int skl_create(struct pci_dev *pci,
902 905
903static int skl_first_init(struct hdac_bus *bus) 906static int skl_first_init(struct hdac_bus *bus)
904{ 907{
905 struct skl *skl = bus_to_skl(bus); 908 struct skl_dev *skl = bus_to_skl(bus);
906 struct pci_dev *pci = skl->pci; 909 struct pci_dev *pci = skl->pci;
907 int err; 910 int err;
908 unsigned short gcap; 911 unsigned short gcap;
@@ -978,7 +981,7 @@ static int skl_first_init(struct hdac_bus *bus)
978static int skl_probe(struct pci_dev *pci, 981static int skl_probe(struct pci_dev *pci,
979 const struct pci_device_id *pci_id) 982 const struct pci_device_id *pci_id)
980{ 983{
981 struct skl *skl; 984 struct skl_dev *skl;
982 struct hdac_bus *bus = NULL; 985 struct hdac_bus *bus = NULL;
983 int err; 986 int err;
984 987
@@ -1013,7 +1016,7 @@ static int skl_probe(struct pci_dev *pci,
1013 } 1016 }
1014 1017
1015 /* we use ext core ops, so provide NULL for ops here */ 1018 /* we use ext core ops, so provide NULL for ops here */
1016 err = skl_create(pci, NULL, &skl); 1019 err = skl_create(pci, &skl);
1017 if (err < 0) 1020 if (err < 0)
1018 return err; 1021 return err;
1019 1022
@@ -1029,7 +1032,7 @@ static int skl_probe(struct pci_dev *pci,
1029 1032
1030 device_disable_async_suspend(bus->dev); 1033 device_disable_async_suspend(bus->dev);
1031 1034
1032 skl->nhlt = skl_nhlt_init(bus->dev); 1035 skl->nhlt = intel_nhlt_init(bus->dev);
1033 1036
1034 if (skl->nhlt == NULL) { 1037 if (skl->nhlt == NULL) {
1035#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) 1038#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
@@ -1071,8 +1074,8 @@ static int skl_probe(struct pci_dev *pci,
1071 dev_dbg(bus->dev, "error failed to register dsp\n"); 1074 dev_dbg(bus->dev, "error failed to register dsp\n");
1072 goto out_nhlt_free; 1075 goto out_nhlt_free;
1073 } 1076 }
1074 skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge; 1077 skl->enable_miscbdcge = skl_enable_miscbdcge;
1075 skl->skl_sst->clock_power_gating = skl_clock_power_gating; 1078 skl->clock_power_gating = skl_clock_power_gating;
1076 1079
1077 if (bus->mlcap) 1080 if (bus->mlcap)
1078 snd_hdac_ext_bus_get_ml_capabilities(bus); 1081 snd_hdac_ext_bus_get_ml_capabilities(bus);
@@ -1095,7 +1098,7 @@ out_dsp_free:
1095out_clk_free: 1098out_clk_free:
1096 skl_clock_device_unregister(skl); 1099 skl_clock_device_unregister(skl);
1097out_nhlt_free: 1100out_nhlt_free:
1098 skl_nhlt_free(skl->nhlt); 1101 intel_nhlt_free(skl->nhlt);
1099out_free: 1102out_free:
1100 skl_free(bus); 1103 skl_free(bus);
1101 1104
@@ -1107,7 +1110,7 @@ static void skl_shutdown(struct pci_dev *pci)
1107 struct hdac_bus *bus = pci_get_drvdata(pci); 1110 struct hdac_bus *bus = pci_get_drvdata(pci);
1108 struct hdac_stream *s; 1111 struct hdac_stream *s;
1109 struct hdac_ext_stream *stream; 1112 struct hdac_ext_stream *stream;
1110 struct skl *skl; 1113 struct skl_dev *skl;
1111 1114
1112 if (!bus) 1115 if (!bus)
1113 return; 1116 return;
@@ -1129,7 +1132,7 @@ static void skl_shutdown(struct pci_dev *pci)
1129static void skl_remove(struct pci_dev *pci) 1132static void skl_remove(struct pci_dev *pci)
1130{ 1133{
1131 struct hdac_bus *bus = pci_get_drvdata(pci); 1134 struct hdac_bus *bus = pci_get_drvdata(pci);
1132 struct skl *skl = bus_to_skl(bus); 1135 struct skl_dev *skl = bus_to_skl(bus);
1133 1136
1134 cancel_work_sync(&skl->probe_work); 1137 cancel_work_sync(&skl->probe_work);
1135 1138
@@ -1144,7 +1147,7 @@ static void skl_remove(struct pci_dev *pci)
1144 skl_dmic_device_unregister(skl); 1147 skl_dmic_device_unregister(skl);
1145 skl_clock_device_unregister(skl); 1148 skl_clock_device_unregister(skl);
1146 skl_nhlt_remove_sysfs(skl); 1149 skl_nhlt_remove_sysfs(skl);
1147 skl_nhlt_free(skl->nhlt); 1150 intel_nhlt_free(skl->nhlt);
1148 skl_free(bus); 1151 skl_free(bus);
1149 dev_set_drvdata(&pci->dev, NULL); 1152 dev_set_drvdata(&pci->dev, NULL);
1150} 1153}
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index 6070666a6392..2bfbf59277c4 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -16,8 +16,8 @@
16#include <sound/hdaudio_ext.h> 16#include <sound/hdaudio_ext.h>
17#include <sound/hda_codec.h> 17#include <sound/hda_codec.h>
18#include <sound/soc.h> 18#include <sound/soc.h>
19#include "skl-nhlt.h"
20#include "skl-ssp-clk.h" 19#include "skl-ssp-clk.h"
20#include "skl-sst-ipc.h"
21 21
22#define SKL_SUSPEND_DELAY 2000 22#define SKL_SUSPEND_DELAY 2000
23 23
@@ -40,13 +40,6 @@
40#define AZX_VS_EM2_DUM BIT(23) 40#define AZX_VS_EM2_DUM BIT(23)
41#define AZX_REG_VS_EM2_L1SEN BIT(13) 41#define AZX_REG_VS_EM2_L1SEN BIT(13)
42 42
43struct skl_dsp_resource {
44 u32 max_mcps;
45 u32 max_mem;
46 u32 mcps;
47 u32 mem;
48};
49
50struct skl_debug; 43struct skl_debug;
51 44
52struct skl_astate_param { 45struct skl_astate_param {
@@ -63,7 +56,7 @@ struct skl_fw_config {
63 struct skl_astate_config *astate_cfg; 56 struct skl_astate_config *astate_cfg;
64}; 57};
65 58
66struct skl { 59struct skl_dev {
67 struct hda_bus hbus; 60 struct hda_bus hbus;
68 struct pci_dev *pci; 61 struct pci_dev *pci;
69 62
@@ -75,16 +68,13 @@ struct skl {
75 struct snd_soc_dai_driver *dais; 68 struct snd_soc_dai_driver *dais;
76 69
77 struct nhlt_acpi_table *nhlt; /* nhlt ptr */ 70 struct nhlt_acpi_table *nhlt; /* nhlt ptr */
78 struct skl_sst *skl_sst; /* sst skl ctx */
79 71
80 struct skl_dsp_resource resource;
81 struct list_head ppl_list; 72 struct list_head ppl_list;
82 struct list_head bind_list; 73 struct list_head bind_list;
83 74
84 const char *fw_name; 75 const char *fw_name;
85 char tplg_name[64]; 76 char tplg_name[64];
86 unsigned short pci_id; 77 unsigned short pci_id;
87 const struct firmware *tplg;
88 78
89 int supend_active; 79 int supend_active;
90 80
@@ -96,13 +86,59 @@ struct skl {
96 bool use_tplg_pcm; 86 bool use_tplg_pcm;
97 struct skl_fw_config cfg; 87 struct skl_fw_config cfg;
98 struct snd_soc_acpi_mach *mach; 88 struct snd_soc_acpi_mach *mach;
89
90 struct device *dev;
91 struct sst_dsp *dsp;
92
93 /* boot */
94 wait_queue_head_t boot_wait;
95 bool boot_complete;
96
97 /* module load */
98 wait_queue_head_t mod_load_wait;
99 bool mod_load_complete;
100 bool mod_load_status;
101
102 /* IPC messaging */
103 struct sst_generic_ipc ipc;
104
105 /* callback for miscbdge */
106 void (*enable_miscbdcge)(struct device *dev, bool enable);
107 /* Is CGCTL.MISCBDCGE disabled */
108 bool miscbdcg_disabled;
109
110 /* Populate module information */
111 struct list_head uuid_list;
112
113 /* Is firmware loaded */
114 bool fw_loaded;
115
116 /* first boot ? */
117 bool is_first_boot;
118
119 /* multi-core */
120 struct skl_dsp_cores cores;
121
122 /* library info */
123 struct skl_lib_info lib_info[SKL_MAX_LIB];
124 int lib_count;
125
126 /* Callback to update D0i3C register */
127 void (*update_d0i3c)(struct device *dev, bool enable);
128
129 struct skl_d0i3_data d0i3;
130
131 const struct skl_dsp_ops *dsp_ops;
132
133 /* Callback to update dynamic clock and power gating registers */
134 void (*clock_power_gating)(struct device *dev, bool enable);
99}; 135};
100 136
101#define skl_to_bus(s) (&(s)->hbus.core) 137#define skl_to_bus(s) (&(s)->hbus.core)
102#define bus_to_skl(bus) container_of(bus, struct skl, hbus.core) 138#define bus_to_skl(bus) container_of(bus, struct skl_dev, hbus.core)
103 139
104#define skl_to_hbus(s) (&(s)->hbus) 140#define skl_to_hbus(s) (&(s)->hbus)
105#define hbus_to_skl(hbus) container_of((hbus), struct skl, (hbus)) 141#define hbus_to_skl(hbus) container_of((hbus), struct skl_dev, (hbus))
106 142
107/* to pass dai dma data */ 143/* to pass dai dma data */
108struct skl_dma_params { 144struct skl_dma_params {
@@ -121,52 +157,49 @@ struct skl_dsp_ops {
121 int (*init)(struct device *dev, void __iomem *mmio_base, 157 int (*init)(struct device *dev, void __iomem *mmio_base,
122 int irq, const char *fw_name, 158 int irq, const char *fw_name,
123 struct skl_dsp_loader_ops loader_ops, 159 struct skl_dsp_loader_ops loader_ops,
124 struct skl_sst **skl_sst); 160 struct skl_dev **skl_sst);
125 int (*init_fw)(struct device *dev, struct skl_sst *ctx); 161 int (*init_fw)(struct device *dev, struct skl_dev *skl);
126 void (*cleanup)(struct device *dev, struct skl_sst *ctx); 162 void (*cleanup)(struct device *dev, struct skl_dev *skl);
127}; 163};
128 164
129int skl_platform_unregister(struct device *dev); 165int skl_platform_unregister(struct device *dev);
130int skl_platform_register(struct device *dev); 166int skl_platform_register(struct device *dev);
131 167
132struct nhlt_acpi_table *skl_nhlt_init(struct device *dev); 168struct nhlt_specific_cfg *skl_get_ep_blob(struct skl_dev *skl, u32 instance,
133void skl_nhlt_free(struct nhlt_acpi_table *addr);
134struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance,
135 u8 link_type, u8 s_fmt, u8 no_ch, 169 u8 link_type, u8 s_fmt, u8 no_ch,
136 u32 s_rate, u8 dirn, u8 dev_type); 170 u32 s_rate, u8 dirn, u8 dev_type);
137 171
138int skl_get_dmic_geo(struct skl *skl); 172int skl_nhlt_update_topology_bin(struct skl_dev *skl);
139int skl_nhlt_update_topology_bin(struct skl *skl); 173int skl_init_dsp(struct skl_dev *skl);
140int skl_init_dsp(struct skl *skl); 174int skl_free_dsp(struct skl_dev *skl);
141int skl_free_dsp(struct skl *skl); 175int skl_suspend_late_dsp(struct skl_dev *skl);
142int skl_suspend_late_dsp(struct skl *skl); 176int skl_suspend_dsp(struct skl_dev *skl);
143int skl_suspend_dsp(struct skl *skl); 177int skl_resume_dsp(struct skl_dev *skl);
144int skl_resume_dsp(struct skl *skl); 178void skl_cleanup_resources(struct skl_dev *skl);
145void skl_cleanup_resources(struct skl *skl);
146const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id); 179const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id);
147void skl_update_d0i3c(struct device *dev, bool enable); 180void skl_update_d0i3c(struct device *dev, bool enable);
148int skl_nhlt_create_sysfs(struct skl *skl); 181int skl_nhlt_create_sysfs(struct skl_dev *skl);
149void skl_nhlt_remove_sysfs(struct skl *skl); 182void skl_nhlt_remove_sysfs(struct skl_dev *skl);
150void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks); 183void skl_get_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks);
151struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id); 184struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id);
152int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps, 185int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps,
153 u32 caps_size, u32 node_id); 186 u32 caps_size, u32 node_id);
154 187
155struct skl_module_cfg; 188struct skl_module_cfg;
156 189
157#ifdef CONFIG_DEBUG_FS 190#ifdef CONFIG_DEBUG_FS
158struct skl_debug *skl_debugfs_init(struct skl *skl); 191struct skl_debug *skl_debugfs_init(struct skl_dev *skl);
159void skl_debugfs_exit(struct skl *skl); 192void skl_debugfs_exit(struct skl_dev *skl);
160void skl_debug_init_module(struct skl_debug *d, 193void skl_debug_init_module(struct skl_debug *d,
161 struct snd_soc_dapm_widget *w, 194 struct snd_soc_dapm_widget *w,
162 struct skl_module_cfg *mconfig); 195 struct skl_module_cfg *mconfig);
163#else 196#else
164static inline struct skl_debug *skl_debugfs_init(struct skl *skl) 197static inline struct skl_debug *skl_debugfs_init(struct skl_dev *skl)
165{ 198{
166 return NULL; 199 return NULL;
167} 200}
168 201
169static inline void skl_debugfs_exit(struct skl *skl) 202static inline void skl_debugfs_exit(struct skl_dev *skl)
170{} 203{}
171 204
172static inline void skl_debug_init_module(struct skl_debug *d, 205static inline void skl_debug_init_module(struct skl_debug *d,
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 3446a113f482..61226fefe1c4 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -523,7 +523,6 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
523 struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; 523 struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data;
524 struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai; 524 struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai;
525 struct kirkwood_dma_data *priv; 525 struct kirkwood_dma_data *priv;
526 struct resource *mem;
527 struct device_node *np = pdev->dev.of_node; 526 struct device_node *np = pdev->dev.of_node;
528 int err; 527 int err;
529 528
@@ -533,16 +532,13 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
533 532
534 dev_set_drvdata(&pdev->dev, priv); 533 dev_set_drvdata(&pdev->dev, priv);
535 534
536 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 535 priv->io = devm_platform_ioremap_resource(pdev, 0);
537 priv->io = devm_ioremap_resource(&pdev->dev, mem);
538 if (IS_ERR(priv->io)) 536 if (IS_ERR(priv->io))
539 return PTR_ERR(priv->io); 537 return PTR_ERR(priv->io);
540 538
541 priv->irq = platform_get_irq(pdev, 0); 539 priv->irq = platform_get_irq(pdev, 0);
542 if (priv->irq < 0) { 540 if (priv->irq < 0)
543 dev_err(&pdev->dev, "platform_get_irq failed: %d\n", priv->irq);
544 return priv->irq; 541 return priv->irq;
545 }
546 542
547 if (np) { 543 if (np) {
548 priv->burst = 128; /* might be 32 or 128 */ 544 priv->burst = 128; /* might be 32 or 128 */
diff --git a/sound/soc/mediatek/common/mtk-btcvsd.c b/sound/soc/mediatek/common/mtk-btcvsd.c
index c7a81c4be068..d00608c73c6e 100644
--- a/sound/soc/mediatek/common/mtk-btcvsd.c
+++ b/sound/soc/mediatek/common/mtk-btcvsd.c
@@ -1335,10 +1335,8 @@ static int mtk_btcvsd_snd_probe(struct platform_device *pdev)
1335 1335
1336 /* irq */ 1336 /* irq */
1337 irq_id = platform_get_irq(pdev, 0); 1337 irq_id = platform_get_irq(pdev, 0);
1338 if (irq_id <= 0) { 1338 if (irq_id <= 0)
1339 dev_err(dev, "%pOFn no irq found\n", dev->of_node);
1340 return irq_id < 0 ? irq_id : -ENXIO; 1339 return irq_id < 0 ? irq_id : -ENXIO;
1341 }
1342 1340
1343 ret = devm_request_irq(dev, irq_id, mtk_btcvsd_snd_irq_handler, 1341 ret = devm_request_irq(dev, irq_id, mtk_btcvsd_snd_irq_handler,
1344 IRQF_TRIGGER_LOW, "BTCVSD_ISR_Handle", 1342 IRQF_TRIGGER_LOW, "BTCVSD_ISR_Handle",
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-common.h b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
index d44faba27d3c..32bef5e2a56d 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-common.h
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
@@ -63,27 +63,6 @@ enum audio_base_clock {
63 MT2701_BASE_CLK_NUM, 63 MT2701_BASE_CLK_NUM,
64}; 64};
65 65
66static const unsigned int mt2701_afe_backup_list[] = {
67 AUDIO_TOP_CON0,
68 AUDIO_TOP_CON4,
69 AUDIO_TOP_CON5,
70 ASYS_TOP_CON,
71 AFE_CONN0,
72 AFE_CONN1,
73 AFE_CONN2,
74 AFE_CONN3,
75 AFE_CONN15,
76 AFE_CONN16,
77 AFE_CONN17,
78 AFE_CONN18,
79 AFE_CONN19,
80 AFE_CONN20,
81 AFE_CONN21,
82 AFE_CONN22,
83 AFE_DAC_CON0,
84 AFE_MEMIF_PBUF_SIZE,
85};
86
87struct mt2701_i2s_data { 66struct mt2701_i2s_data {
88 int i2s_ctrl_reg; 67 int i2s_ctrl_reg;
89 int i2s_asrc_fs_shift; 68 int i2s_asrc_fs_shift;
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
index 7064a9fd6f74..76502ba261c8 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -60,6 +60,27 @@ static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = {
60 { .rate = 352800, .regvalue = 24 }, 60 { .rate = 352800, .regvalue = 24 },
61}; 61};
62 62
63static const unsigned int mt2701_afe_backup_list[] = {
64 AUDIO_TOP_CON0,
65 AUDIO_TOP_CON4,
66 AUDIO_TOP_CON5,
67 ASYS_TOP_CON,
68 AFE_CONN0,
69 AFE_CONN1,
70 AFE_CONN2,
71 AFE_CONN3,
72 AFE_CONN15,
73 AFE_CONN16,
74 AFE_CONN17,
75 AFE_CONN18,
76 AFE_CONN19,
77 AFE_CONN20,
78 AFE_CONN21,
79 AFE_CONN22,
80 AFE_DAC_CON0,
81 AFE_MEMIF_PBUF_SIZE,
82};
83
63static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num) 84static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num)
64{ 85{
65 struct mt2701_afe_private *afe_priv = afe->platform_priv; 86 struct mt2701_afe_private *afe_priv = afe->platform_priv;
@@ -796,14 +817,6 @@ static const struct snd_kcontrol_new mt2701_afe_o22_mix[] = {
796 SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0), 817 SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0),
797}; 818};
798 819
799static const struct snd_kcontrol_new mt2701_afe_o23_mix[] = {
800 SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN23, 20, 1, 0),
801};
802
803static const struct snd_kcontrol_new mt2701_afe_o24_mix[] = {
804 SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN24, 21, 1, 0),
805};
806
807static const struct snd_kcontrol_new mt2701_afe_o31_mix[] = { 820static const struct snd_kcontrol_new mt2701_afe_o31_mix[] = {
808 SOC_DAPM_SINGLE_AUTODISABLE("I35 Switch", AFE_CONN41, 9, 1, 0), 821 SOC_DAPM_SINGLE_AUTODISABLE("I35 Switch", AFE_CONN41, 9, 1, 0),
809}; 822};
@@ -832,11 +845,6 @@ static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s3[] = {
832 PWR2_TOP_CON, 18, 1, 0), 845 PWR2_TOP_CON, 18, 1, 0),
833}; 846};
834 847
835static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s4[] = {
836 SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S4 Out Switch",
837 PWR2_TOP_CON, 19, 1, 0),
838};
839
840static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = { 848static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = {
841 /* inter-connections */ 849 /* inter-connections */
842 SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0), 850 SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -1342,10 +1350,8 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
1342 return -ENOMEM; 1350 return -ENOMEM;
1343 1351
1344 irq_id = platform_get_irq_byname(pdev, "asys"); 1352 irq_id = platform_get_irq_byname(pdev, "asys");
1345 if (irq_id < 0) { 1353 if (irq_id < 0)
1346 dev_err(dev, "unable to get ASYS IRQ\n");
1347 return irq_id; 1354 return irq_id;
1348 }
1349 1355
1350 ret = devm_request_irq(dev, irq_id, mt2701_asys_isr, 1356 ret = devm_request_irq(dev, irq_id, mt2701_asys_isr,
1351 IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); 1357 IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
diff --git a/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
index 08a6532da322..e52c032d53aa 100644
--- a/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
+++ b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
@@ -749,7 +749,6 @@ static int mt6797_afe_pcm_dev_probe(struct platform_device *pdev)
749{ 749{
750 struct mtk_base_afe *afe; 750 struct mtk_base_afe *afe;
751 struct mt6797_afe_private *afe_priv; 751 struct mt6797_afe_private *afe_priv;
752 struct resource *res;
753 struct device *dev; 752 struct device *dev;
754 int i, irq_id, ret; 753 int i, irq_id, ret;
755 754
@@ -774,9 +773,7 @@ static int mt6797_afe_pcm_dev_probe(struct platform_device *pdev)
774 } 773 }
775 774
776 /* regmap init */ 775 /* regmap init */
777 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 776 afe->base_addr = devm_platform_ioremap_resource(pdev, 0);
778
779 afe->base_addr = devm_ioremap_resource(&pdev->dev, res);
780 if (IS_ERR(afe->base_addr)) 777 if (IS_ERR(afe->base_addr))
781 return PTR_ERR(afe->base_addr); 778 return PTR_ERR(afe->base_addr);
782 779
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
index 0382896c162e..0ee29255e731 100644
--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
@@ -1056,7 +1056,6 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
1056 int irq_id; 1056 int irq_id;
1057 struct mtk_base_afe *afe; 1057 struct mtk_base_afe *afe;
1058 struct mt8173_afe_private *afe_priv; 1058 struct mt8173_afe_private *afe_priv;
1059 struct resource *res;
1060 1059
1061 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33)); 1060 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
1062 if (ret) 1061 if (ret)
@@ -1075,10 +1074,8 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
1075 afe->dev = &pdev->dev; 1074 afe->dev = &pdev->dev;
1076 1075
1077 irq_id = platform_get_irq(pdev, 0); 1076 irq_id = platform_get_irq(pdev, 0);
1078 if (irq_id <= 0) { 1077 if (irq_id <= 0)
1079 dev_err(afe->dev, "np %pOFn no irq\n", afe->dev->of_node);
1080 return irq_id < 0 ? irq_id : -ENXIO; 1078 return irq_id < 0 ? irq_id : -ENXIO;
1081 }
1082 ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler, 1079 ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler,
1083 0, "Afe_ISR_Handle", (void *)afe); 1080 0, "Afe_ISR_Handle", (void *)afe);
1084 if (ret) { 1081 if (ret) {
@@ -1086,8 +1083,7 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
1086 return ret; 1083 return ret;
1087 } 1084 }
1088 1085
1089 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1086 afe->base_addr = devm_platform_ioremap_resource(pdev, 0);
1090 afe->base_addr = devm_ioremap_resource(&pdev->dev, res);
1091 if (IS_ERR(afe->base_addr)) 1087 if (IS_ERR(afe->base_addr))
1092 return PTR_ERR(afe->base_addr); 1088 return PTR_ERR(afe->base_addr);
1093 1089
diff --git a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
index 59076e21cb47..43f99e59a078 100644
--- a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
+++ b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
@@ -116,15 +116,6 @@ static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
116 return 0; 116 return 0;
117} 117}
118 118
119static const struct snd_soc_dapm_widget
120mt8183_da7219_max98357_dapm_widgets[] = {
121 SND_SOC_DAPM_OUTPUT("IT6505_8CH"),
122};
123
124static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = {
125 {"IT6505_8CH", NULL, "TDM"},
126};
127
128/* FE */ 119/* FE */
129SND_SOC_DAILINK_DEFS(playback1, 120SND_SOC_DAILINK_DEFS(playback1,
130 DAILINK_COMP_ARRAY(COMP_CPU("DL1")), 121 DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
@@ -370,7 +361,7 @@ static int
370mt8183_da7219_max98357_headset_init(struct snd_soc_component *component); 361mt8183_da7219_max98357_headset_init(struct snd_soc_component *component);
371 362
372static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = { 363static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = {
373 .name = "Headset Chip", 364 .dlc = COMP_EMPTY(),
374 .init = mt8183_da7219_max98357_headset_init, 365 .init = mt8183_da7219_max98357_headset_init,
375}; 366};
376 367
@@ -436,10 +427,10 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
436 dai_link->platforms->of_node = platform_node; 427 dai_link->platforms->of_node = platform_node;
437 } 428 }
438 429
439 mt8183_da7219_max98357_headset_dev.codec_of_node = 430 mt8183_da7219_max98357_headset_dev.dlc.of_node =
440 of_parse_phandle(pdev->dev.of_node, 431 of_parse_phandle(pdev->dev.of_node,
441 "mediatek,headset-codec", 0); 432 "mediatek,headset-codec", 0);
442 if (!mt8183_da7219_max98357_headset_dev.codec_of_node) { 433 if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) {
443 dev_err(&pdev->dev, 434 dev_err(&pdev->dev,
444 "Property 'mediatek,headset-codec' missing/invalid\n"); 435 "Property 'mediatek,headset-codec' missing/invalid\n");
445 return -EINVAL; 436 return -EINVAL;
diff --git a/sound/soc/mediatek/mt8183/mt8183-dai-tdm.c b/sound/soc/mediatek/mt8183/mt8183-dai-tdm.c
index 8983d54a9b67..0d69cf440407 100644
--- a/sound/soc/mediatek/mt8183/mt8183-dai-tdm.c
+++ b/sound/soc/mediatek/mt8183/mt8183-dai-tdm.c
@@ -15,7 +15,9 @@
15struct mtk_afe_tdm_priv { 15struct mtk_afe_tdm_priv {
16 int bck_id; 16 int bck_id;
17 int bck_rate; 17 int bck_rate;
18 18 int tdm_out_mode;
19 int bck_invert;
20 int lck_invert;
19 int mclk_id; 21 int mclk_id;
20 int mclk_multiple; /* according to sample rate */ 22 int mclk_multiple; /* according to sample rate */
21 int mclk_rate; 23 int mclk_rate;
@@ -23,6 +25,21 @@ struct mtk_afe_tdm_priv {
23}; 25};
24 26
25enum { 27enum {
28 TDM_OUT_I2S = 0,
29 TDM_OUT_TDM = 1,
30};
31
32enum {
33 TDM_BCK_NON_INV = 0,
34 TDM_BCK_INV = 1,
35};
36
37enum {
38 TDM_LCK_NON_INV = 0,
39 TDM_LCK_INV = 1,
40};
41
42enum {
26 TDM_WLEN_16_BIT = 1, 43 TDM_WLEN_16_BIT = 1,
27 TDM_WLEN_32_BIT = 2, 44 TDM_WLEN_32_BIT = 2,
28}; 45};
@@ -93,6 +110,25 @@ static unsigned int get_tdm_ch(unsigned int ch)
93 } 110 }
94} 111}
95 112
113static unsigned int get_tdm_ch_fixup(unsigned int channels)
114{
115 if (channels > 4)
116 return 8;
117 else if (channels > 2)
118 return 4;
119 else
120 return 2;
121}
122
123static unsigned int get_tdm_ch_per_sdata(unsigned int mode,
124 unsigned int channels)
125{
126 if (mode == TDM_OUT_TDM)
127 return get_tdm_ch_fixup(channels);
128 else
129 return 2;
130}
131
96/* interconnection */ 132/* interconnection */
97enum { 133enum {
98 HDMI_CONN_CH0 = 0, 134 HDMI_CONN_CH0 = 0,
@@ -433,8 +469,11 @@ static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream,
433 struct mt8183_afe_private *afe_priv = afe->platform_priv; 469 struct mt8183_afe_private *afe_priv = afe->platform_priv;
434 int tdm_id = dai->id; 470 int tdm_id = dai->id;
435 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[tdm_id]; 471 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[tdm_id];
472 unsigned int tdm_out_mode = tdm_priv->tdm_out_mode;
436 unsigned int rate = params_rate(params); 473 unsigned int rate = params_rate(params);
437 unsigned int channels = params_channels(params); 474 unsigned int channels = params_channels(params);
475 unsigned int out_channels_per_sdata =
476 get_tdm_ch_per_sdata(tdm_out_mode, channels);
438 snd_pcm_format_t format = params_format(params); 477 snd_pcm_format_t format = params_format(params);
439 unsigned int tdm_con = 0; 478 unsigned int tdm_con = 0;
440 479
@@ -448,7 +487,7 @@ static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream,
448 487
449 /* calculate bck */ 488 /* calculate bck */
450 tdm_priv->bck_rate = rate * 489 tdm_priv->bck_rate = rate *
451 channels * 490 out_channels_per_sdata *
452 snd_pcm_format_physical_width(format); 491 snd_pcm_format_physical_width(format);
453 492
454 if (tdm_priv->bck_rate > tdm_priv->mclk_rate) 493 if (tdm_priv->bck_rate > tdm_priv->mclk_rate)
@@ -461,50 +500,72 @@ static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream,
461 __func__, 500 __func__,
462 tdm_id, rate, channels, format, 501 tdm_id, rate, channels, format,
463 tdm_priv->mclk_rate, tdm_priv->bck_rate); 502 tdm_priv->mclk_rate, tdm_priv->bck_rate);
503 dev_info(afe->dev, "%s(), out_channels_per_sdata = %d\n",
504 __func__, out_channels_per_sdata);
464 505
465 /* set tdm */ 506 /* set tdm */
466 tdm_con = 1 << BCK_INVERSE_SFT; 507 if (tdm_priv->bck_invert)
467 tdm_con |= 1 << LRCK_INVERSE_SFT; 508 regmap_update_bits(afe->regmap, AUDIO_TOP_CON3,
468 tdm_con |= 1 << DELAY_DATA_SFT; 509 BCK_INVERSE_MASK_SFT,
510 0x1 << BCK_INVERSE_SFT);
511
512 if (tdm_priv->lck_invert)
513 tdm_con |= 1 << LRCK_INVERSE_SFT;
514
515 if (tdm_priv->tdm_out_mode == TDM_OUT_I2S) {
516 tdm_con |= 1 << DELAY_DATA_SFT;
517 tdm_con |= get_tdm_lrck_width(format) << LRCK_TDM_WIDTH_SFT;
518 } else if (tdm_priv->tdm_out_mode == TDM_OUT_TDM) {
519 tdm_con |= 0 << DELAY_DATA_SFT;
520 tdm_con |= 0 << LRCK_TDM_WIDTH_SFT;
521 }
522
469 tdm_con |= 1 << LEFT_ALIGN_SFT; 523 tdm_con |= 1 << LEFT_ALIGN_SFT;
470 tdm_con |= get_tdm_wlen(format) << WLEN_SFT; 524 tdm_con |= get_tdm_wlen(format) << WLEN_SFT;
471 tdm_con |= get_tdm_ch(channels) << CHANNEL_NUM_SFT; 525 tdm_con |= get_tdm_ch(out_channels_per_sdata) << CHANNEL_NUM_SFT;
472 tdm_con |= get_tdm_channel_bck(format) << CHANNEL_BCK_CYCLES_SFT; 526 tdm_con |= get_tdm_channel_bck(format) << CHANNEL_BCK_CYCLES_SFT;
473 tdm_con |= get_tdm_lrck_width(format) << LRCK_TDM_WIDTH_SFT;
474 regmap_write(afe->regmap, AFE_TDM_CON1, tdm_con); 527 regmap_write(afe->regmap, AFE_TDM_CON1, tdm_con);
475 528
476 switch (channels) { 529 if (out_channels_per_sdata == 2) {
477 case 1: 530 switch (channels) {
478 case 2: 531 case 1:
532 case 2:
533 tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
534 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT;
535 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT;
536 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
537 break;
538 case 3:
539 case 4:
540 tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
541 tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT;
542 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT;
543 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
544 break;
545 case 5:
546 case 6:
547 tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
548 tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT;
549 tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT;
550 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
551 break;
552 case 7:
553 case 8:
554 tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
555 tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT;
556 tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT;
557 tdm_con |= TDM_CH_START_O36_O37 << ST_CH_PAIR_SOUT3_SFT;
558 break;
559 default:
560 tdm_con = 0;
561 }
562 } else {
479 tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; 563 tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
480 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT; 564 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT;
481 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT; 565 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT;
482 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; 566 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
483 break;
484 case 3:
485 case 4:
486 tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
487 tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT;
488 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT;
489 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
490 break;
491 case 5:
492 case 6:
493 tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
494 tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT;
495 tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT;
496 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
497 break;
498 case 7:
499 case 8:
500 tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
501 tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT;
502 tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT;
503 tdm_con |= TDM_CH_START_O36_O37 << ST_CH_PAIR_SOUT3_SFT;
504 break;
505 default:
506 tdm_con = 0;
507 } 567 }
568
508 regmap_write(afe->regmap, AFE_TDM_CON2, tdm_con); 569 regmap_write(afe->regmap, AFE_TDM_CON2, tdm_con);
509 570
510 regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, 571 regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0,
@@ -573,10 +634,58 @@ static int mtk_dai_tdm_set_sysclk(struct snd_soc_dai *dai,
573 return mtk_dai_tdm_cal_mclk(afe, tdm_priv, freq); 634 return mtk_dai_tdm_cal_mclk(afe, tdm_priv, freq);
574} 635}
575 636
637static int mtk_dai_tdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
638{
639 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
640 struct mt8183_afe_private *afe_priv = afe->platform_priv;
641 struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id];
642
643 if (!tdm_priv) {
644 dev_warn(afe->dev, "%s(), tdm_priv == NULL", __func__);
645 return -EINVAL;
646 }
647
648 /* DAI mode*/
649 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
650 case SND_SOC_DAIFMT_I2S:
651 tdm_priv->tdm_out_mode = TDM_OUT_I2S;
652 break;
653 case SND_SOC_DAIFMT_DSP_A:
654 tdm_priv->tdm_out_mode = TDM_OUT_TDM;
655 break;
656 default:
657 tdm_priv->tdm_out_mode = TDM_OUT_I2S;
658 }
659
660 /* DAI clock inversion*/
661 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
662 case SND_SOC_DAIFMT_NB_NF:
663 tdm_priv->bck_invert = TDM_BCK_NON_INV;
664 tdm_priv->lck_invert = TDM_LCK_NON_INV;
665 break;
666 case SND_SOC_DAIFMT_NB_IF:
667 tdm_priv->bck_invert = TDM_BCK_NON_INV;
668 tdm_priv->lck_invert = TDM_LCK_INV;
669 break;
670 case SND_SOC_DAIFMT_IB_NF:
671 tdm_priv->bck_invert = TDM_BCK_INV;
672 tdm_priv->lck_invert = TDM_LCK_NON_INV;
673 break;
674 case SND_SOC_DAIFMT_IB_IF:
675 default:
676 tdm_priv->bck_invert = TDM_BCK_INV;
677 tdm_priv->lck_invert = TDM_LCK_INV;
678 break;
679 }
680
681 return 0;
682}
683
576static const struct snd_soc_dai_ops mtk_dai_tdm_ops = { 684static const struct snd_soc_dai_ops mtk_dai_tdm_ops = {
577 .hw_params = mtk_dai_tdm_hw_params, 685 .hw_params = mtk_dai_tdm_hw_params,
578 .trigger = mtk_dai_tdm_trigger, 686 .trigger = mtk_dai_tdm_trigger,
579 .set_sysclk = mtk_dai_tdm_set_sysclk, 687 .set_sysclk = mtk_dai_tdm_set_sysclk,
688 .set_fmt = mtk_dai_tdm_set_fmt,
580}; 689};
581 690
582/* dai driver */ 691/* dai driver */
diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
index 887c932229d0..bb9cdc0d6552 100644
--- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
+++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
@@ -15,7 +15,22 @@
15#include "mt8183-afe-common.h" 15#include "mt8183-afe-common.h"
16#include "../../codecs/ts3a227e.h" 16#include "../../codecs/ts3a227e.h"
17 17
18static struct snd_soc_jack headset_jack; 18enum PINCTRL_PIN_STATE {
19 PIN_STATE_DEFAULT = 0,
20 PIN_TDM_OUT_ON,
21 PIN_TDM_OUT_OFF,
22 PIN_STATE_MAX
23};
24
25static const char * const mt8183_pin_str[PIN_STATE_MAX] = {
26 "default", "aud_tdm_out_on", "aud_tdm_out_off",
27};
28
29struct mt8183_mt6358_ts3a227_max98357_priv {
30 struct pinctrl *pinctrl;
31 struct pinctrl_state *pin_states[PIN_STATE_MAX];
32 struct snd_soc_jack headset_jack;
33};
19 34
20static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream, 35static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
21 struct snd_pcm_hw_params *params) 36 struct snd_pcm_hw_params *params)
@@ -46,16 +61,6 @@ static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
46 return 0; 61 return 0;
47} 62}
48 63
49static const struct snd_soc_dapm_widget
50mt8183_mt6358_ts3a227_max98357_dapm_widgets[] = {
51 SND_SOC_DAPM_OUTPUT("IT6505_8CH"),
52};
53
54static const struct snd_soc_dapm_route
55mt8183_mt6358_ts3a227_max98357_dapm_routes[] = {
56 {"IT6505_8CH", NULL, "TDM"},
57};
58
59static int 64static int
60mt8183_mt6358_ts3a227_max98357_bt_sco_startup( 65mt8183_mt6358_ts3a227_max98357_bt_sco_startup(
61 struct snd_pcm_substream *substream) 66 struct snd_pcm_substream *substream)
@@ -183,6 +188,47 @@ SND_SOC_DAILINK_DEFS(tdm,
183 DAILINK_COMP_ARRAY(COMP_DUMMY()), 188 DAILINK_COMP_ARRAY(COMP_DUMMY()),
184 DAILINK_COMP_ARRAY(COMP_EMPTY())); 189 DAILINK_COMP_ARRAY(COMP_EMPTY()));
185 190
191static int mt8183_mt6358_tdm_startup(struct snd_pcm_substream *substream)
192{
193 struct snd_soc_pcm_runtime *rtd = substream->private_data;
194 struct mt8183_mt6358_ts3a227_max98357_priv *priv =
195 snd_soc_card_get_drvdata(rtd->card);
196 int ret;
197
198 if (IS_ERR(priv->pin_states[PIN_TDM_OUT_ON]))
199 return PTR_ERR(priv->pin_states[PIN_TDM_OUT_ON]);
200
201 ret = pinctrl_select_state(priv->pinctrl,
202 priv->pin_states[PIN_TDM_OUT_ON]);
203 if (ret)
204 dev_err(rtd->card->dev, "%s failed to select state %d\n",
205 __func__, ret);
206
207 return ret;
208}
209
210static void mt8183_mt6358_tdm_shutdown(struct snd_pcm_substream *substream)
211{
212 struct snd_soc_pcm_runtime *rtd = substream->private_data;
213 struct mt8183_mt6358_ts3a227_max98357_priv *priv =
214 snd_soc_card_get_drvdata(rtd->card);
215 int ret;
216
217 if (IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF]))
218 return;
219
220 ret = pinctrl_select_state(priv->pinctrl,
221 priv->pin_states[PIN_TDM_OUT_OFF]);
222 if (ret)
223 dev_err(rtd->card->dev, "%s failed to select state %d\n",
224 __func__, ret);
225}
226
227static struct snd_soc_ops mt8183_mt6358_tdm_ops = {
228 .startup = mt8183_mt6358_tdm_startup,
229 .shutdown = mt8183_mt6358_tdm_shutdown,
230};
231
186static struct snd_soc_dai_link 232static struct snd_soc_dai_link
187mt8183_mt6358_ts3a227_max98357_dai_links[] = { 233mt8183_mt6358_ts3a227_max98357_dai_links[] = {
188 /* FE */ 234 /* FE */
@@ -333,33 +379,30 @@ mt8183_mt6358_ts3a227_max98357_dai_links[] = {
333 { 379 {
334 .name = "TDM", 380 .name = "TDM",
335 .no_pcm = 1, 381 .no_pcm = 1,
382 .dai_fmt = SND_SOC_DAIFMT_I2S |
383 SND_SOC_DAIFMT_IB_IF |
384 SND_SOC_DAIFMT_CBM_CFM,
336 .dpcm_playback = 1, 385 .dpcm_playback = 1,
337 .ignore_suspend = 1, 386 .ignore_suspend = 1,
387 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
388 .ops = &mt8183_mt6358_tdm_ops,
338 SND_SOC_DAILINK_REG(tdm), 389 SND_SOC_DAILINK_REG(tdm),
339 }, 390 },
340}; 391};
341 392
342static int
343mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *cpnt);
344
345static struct snd_soc_aux_dev mt8183_mt6358_ts3a227_max98357_headset_dev = {
346 .name = "Headset Chip",
347 .init = mt8183_mt6358_ts3a227_max98357_headset_init,
348};
349
350static struct snd_soc_card mt8183_mt6358_ts3a227_max98357_card = { 393static struct snd_soc_card mt8183_mt6358_ts3a227_max98357_card = {
351 .name = "mt8183_mt6358_ts3a227_max98357", 394 .name = "mt8183_mt6358_ts3a227_max98357",
352 .owner = THIS_MODULE, 395 .owner = THIS_MODULE,
353 .dai_link = mt8183_mt6358_ts3a227_max98357_dai_links, 396 .dai_link = mt8183_mt6358_ts3a227_max98357_dai_links,
354 .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dai_links), 397 .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dai_links),
355 .aux_dev = &mt8183_mt6358_ts3a227_max98357_headset_dev,
356 .num_aux_devs = 1,
357}; 398};
358 399
359static int 400static int
360mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component) 401mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component)
361{ 402{
362 int ret; 403 int ret;
404 struct mt8183_mt6358_ts3a227_max98357_priv *priv =
405 snd_soc_card_get_drvdata(component->card);
363 406
364 /* Enable Headset and 4 Buttons Jack detection */ 407 /* Enable Headset and 4 Buttons Jack detection */
365 ret = snd_soc_card_jack_new(&mt8183_mt6358_ts3a227_max98357_card, 408 ret = snd_soc_card_jack_new(&mt8183_mt6358_ts3a227_max98357_card,
@@ -367,23 +410,29 @@ mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component)
367 SND_JACK_HEADSET | 410 SND_JACK_HEADSET |
368 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 411 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
369 SND_JACK_BTN_2 | SND_JACK_BTN_3, 412 SND_JACK_BTN_2 | SND_JACK_BTN_3,
370 &headset_jack, 413 &priv->headset_jack,
371 NULL, 0); 414 NULL, 0);
372 if (ret) 415 if (ret)
373 return ret; 416 return ret;
374 417
375 ret = ts3a227e_enable_jack_detect(component, &headset_jack); 418 ret = ts3a227e_enable_jack_detect(component, &priv->headset_jack);
376 419
377 return ret; 420 return ret;
378} 421}
379 422
423static struct snd_soc_aux_dev mt8183_mt6358_ts3a227_max98357_headset_dev = {
424 .dlc = COMP_EMPTY(),
425 .init = mt8183_mt6358_ts3a227_max98357_headset_init,
426};
427
380static int 428static int
381mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) 429mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
382{ 430{
383 struct snd_soc_card *card = &mt8183_mt6358_ts3a227_max98357_card; 431 struct snd_soc_card *card = &mt8183_mt6358_ts3a227_max98357_card;
384 struct device_node *platform_node; 432 struct device_node *platform_node;
385 struct snd_soc_dai_link *dai_link; 433 struct snd_soc_dai_link *dai_link;
386 struct pinctrl *default_pins; 434 struct mt8183_mt6358_ts3a227_max98357_priv *priv;
435 int ret;
387 int i; 436 int i;
388 437
389 card->dev = &pdev->dev; 438 card->dev = &pdev->dev;
@@ -401,21 +450,53 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
401 dai_link->platforms->of_node = platform_node; 450 dai_link->platforms->of_node = platform_node;
402 } 451 }
403 452
404 mt8183_mt6358_ts3a227_max98357_headset_dev.codec_of_node = 453 mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node =
405 of_parse_phandle(pdev->dev.of_node, 454 of_parse_phandle(pdev->dev.of_node,
406 "mediatek,headset-codec", 0); 455 "mediatek,headset-codec", 0);
407 if (!mt8183_mt6358_ts3a227_max98357_headset_dev.codec_of_node) { 456 if (mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node) {
408 dev_err(&pdev->dev, 457 card->aux_dev = &mt8183_mt6358_ts3a227_max98357_headset_dev;
409 "Property 'mediatek,headset-codec' missing/invalid\n"); 458 card->num_aux_devs = 1;
410 return -EINVAL;
411 } 459 }
412 460
413 default_pins = 461 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
414 devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT); 462 if (!priv)
415 if (IS_ERR(default_pins)) { 463 return -ENOMEM;
416 dev_err(&pdev->dev, "%s set pins failed\n", 464
465 snd_soc_card_set_drvdata(card, priv);
466
467 priv->pinctrl = devm_pinctrl_get(&pdev->dev);
468 if (IS_ERR(priv->pinctrl)) {
469 dev_err(&pdev->dev, "%s devm_pinctrl_get failed\n",
417 __func__); 470 __func__);
418 return PTR_ERR(default_pins); 471 return PTR_ERR(priv->pinctrl);
472 }
473
474 for (i = 0; i < PIN_STATE_MAX; i++) {
475 priv->pin_states[i] = pinctrl_lookup_state(priv->pinctrl,
476 mt8183_pin_str[i]);
477 if (IS_ERR(priv->pin_states[i])) {
478 ret = PTR_ERR(priv->pin_states[i]);
479 dev_info(&pdev->dev, "%s Can't find pin state %s %d\n",
480 __func__, mt8183_pin_str[i], ret);
481 }
482 }
483
484 if (!IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF])) {
485 ret = pinctrl_select_state(priv->pinctrl,
486 priv->pin_states[PIN_TDM_OUT_OFF]);
487 if (ret)
488 dev_info(&pdev->dev,
489 "%s failed to select state %d\n",
490 __func__, ret);
491 }
492
493 if (!IS_ERR(priv->pin_states[PIN_STATE_DEFAULT])) {
494 ret = pinctrl_select_state(priv->pinctrl,
495 priv->pin_states[PIN_STATE_DEFAULT]);
496 if (ret)
497 dev_info(&pdev->dev,
498 "%s failed to select state %d\n",
499 __func__, ret);
419 } 500 }
420 501
421 return devm_snd_soc_register_card(&pdev->dev, card); 502 return devm_snd_soc_register_card(&pdev->dev, card);
@@ -445,4 +526,3 @@ MODULE_DESCRIPTION("MT8183-MT6358-TS3A227-MAX98357 ALSA SoC machine driver");
445MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>"); 526MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");
446MODULE_LICENSE("GPL v2"); 527MODULE_LICENSE("GPL v2");
447MODULE_ALIAS("mt8183_mt6358_ts3a227_max98357 soc card"); 528MODULE_ALIAS("mt8183_mt6358_ts3a227_max98357 soc card");
448
diff --git a/sound/soc/mediatek/mt8183/mt8183-reg.h b/sound/soc/mediatek/mt8183/mt8183-reg.h
index e0482f2826da..e544a09e1913 100644
--- a/sound/soc/mediatek/mt8183/mt8183-reg.h
+++ b/sound/soc/mediatek/mt8183/mt8183-reg.h
@@ -413,6 +413,11 @@
413#define AFE_MAX_REGISTER AFE_GENERAL2_ASRC_2CH_CON13 413#define AFE_MAX_REGISTER AFE_GENERAL2_ASRC_2CH_CON13
414#define AFE_IRQ_STATUS_BITS 0x1fff 414#define AFE_IRQ_STATUS_BITS 0x1fff
415 415
416/* AUDIO_TOP_CON3 */
417#define BCK_INVERSE_SFT 3
418#define BCK_INVERSE_MASK 0x1
419#define BCK_INVERSE_MASK_SFT (0x1 << 3)
420
416/* AFE_DAC_CON0 */ 421/* AFE_DAC_CON0 */
417#define AWB2_ON_SFT 29 422#define AWB2_ON_SFT 29
418#define AWB2_ON_MASK 0x1 423#define AWB2_ON_MASK 0x1
@@ -1596,9 +1601,6 @@
1596#define TDM_EN_SFT 0 1601#define TDM_EN_SFT 0
1597#define TDM_EN_MASK 0x1 1602#define TDM_EN_MASK 0x1
1598#define TDM_EN_MASK_SFT (0x1 << 0) 1603#define TDM_EN_MASK_SFT (0x1 << 0)
1599#define BCK_INVERSE_SFT 1
1600#define BCK_INVERSE_MASK 0x1
1601#define BCK_INVERSE_MASK_SFT (0x1 << 1)
1602#define LRCK_INVERSE_SFT 2 1604#define LRCK_INVERSE_SFT 2
1603#define LRCK_INVERSE_MASK 0x1 1605#define LRCK_INVERSE_MASK 0x1
1604#define LRCK_INVERSE_MASK_SFT (0x1 << 2) 1606#define LRCK_INVERSE_MASK_SFT (0x1 << 2)
diff --git a/sound/soc/meson/axg-card.c b/sound/soc/meson/axg-card.c
index 14a8321744da..1f698adde506 100644
--- a/sound/soc/meson/axg-card.c
+++ b/sound/soc/meson/axg-card.c
@@ -111,6 +111,7 @@ static void axg_card_clean_references(struct axg_card *priv)
111 struct snd_soc_card *card = &priv->card; 111 struct snd_soc_card *card = &priv->card;
112 struct snd_soc_dai_link *link; 112 struct snd_soc_dai_link *link;
113 struct snd_soc_dai_link_component *codec; 113 struct snd_soc_dai_link_component *codec;
114 struct snd_soc_aux_dev *aux;
114 int i, j; 115 int i, j;
115 116
116 if (card->dai_link) { 117 if (card->dai_link) {
@@ -123,8 +124,8 @@ static void axg_card_clean_references(struct axg_card *priv)
123 } 124 }
124 125
125 if (card->aux_dev) { 126 if (card->aux_dev) {
126 for (i = 0; i < card->num_aux_devs; i++) 127 for_each_card_pre_auxs(card, i, aux)
127 of_node_put(card->aux_dev[i].codec_of_node); 128 of_node_put(aux->dlc.of_node);
128 } 129 }
129 130
130 kfree(card->dai_link); 131 kfree(card->dai_link);
@@ -157,10 +158,10 @@ static int axg_card_add_aux_devices(struct snd_soc_card *card)
157 card->aux_dev = aux; 158 card->aux_dev = aux;
158 card->num_aux_devs = num; 159 card->num_aux_devs = num;
159 160
160 for (i = 0; i < card->num_aux_devs; i++, aux++) { 161 for_each_card_pre_auxs(card, i, aux) {
161 aux->codec_of_node = 162 aux->dlc.of_node =
162 of_parse_phandle(node, "audio-aux-devs", i); 163 of_parse_phandle(node, "audio-aux-devs", i);
163 if (!aux->codec_of_node) 164 if (!aux->dlc.of_node)
164 return -EINVAL; 165 return -EINVAL;
165 } 166 }
166 167
diff --git a/sound/soc/meson/axg-fifo.c b/sound/soc/meson/axg-fifo.c
index 01c1c7db2510..5a3749938900 100644
--- a/sound/soc/meson/axg-fifo.c
+++ b/sound/soc/meson/axg-fifo.c
@@ -306,7 +306,7 @@ static const struct regmap_config axg_fifo_regmap_cfg = {
306 .reg_bits = 32, 306 .reg_bits = 32,
307 .val_bits = 32, 307 .val_bits = 32,
308 .reg_stride = 4, 308 .reg_stride = 4,
309 .max_register = FIFO_INIT_ADDR, 309 .max_register = FIFO_CTRL2,
310}; 310};
311 311
312int axg_fifo_probe(struct platform_device *pdev) 312int axg_fifo_probe(struct platform_device *pdev)
@@ -314,7 +314,6 @@ int axg_fifo_probe(struct platform_device *pdev)
314 struct device *dev = &pdev->dev; 314 struct device *dev = &pdev->dev;
315 const struct axg_fifo_match_data *data; 315 const struct axg_fifo_match_data *data;
316 struct axg_fifo *fifo; 316 struct axg_fifo *fifo;
317 struct resource *res;
318 void __iomem *regs; 317 void __iomem *regs;
319 318
320 data = of_device_get_match_data(dev); 319 data = of_device_get_match_data(dev);
@@ -328,8 +327,7 @@ int axg_fifo_probe(struct platform_device *pdev)
328 return -ENOMEM; 327 return -ENOMEM;
329 platform_set_drvdata(pdev, fifo); 328 platform_set_drvdata(pdev, fifo);
330 329
331 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 330 regs = devm_platform_ioremap_resource(pdev, 0);
332 regs = devm_ioremap_resource(dev, res);
333 if (IS_ERR(regs)) 331 if (IS_ERR(regs))
334 return PTR_ERR(regs); 332 return PTR_ERR(regs);
335 333
diff --git a/sound/soc/meson/axg-fifo.h b/sound/soc/meson/axg-fifo.h
index 5caf81241dfe..bb1e2ce50256 100644
--- a/sound/soc/meson/axg-fifo.h
+++ b/sound/soc/meson/axg-fifo.h
@@ -61,6 +61,7 @@ struct snd_soc_pcm_runtime;
61#define STATUS1_INT_STS(x) ((x) << 0) 61#define STATUS1_INT_STS(x) ((x) << 0)
62#define FIFO_STATUS2 0x18 62#define FIFO_STATUS2 0x18
63#define FIFO_INIT_ADDR 0x24 63#define FIFO_INIT_ADDR 0x24
64#define FIFO_CTRL2 0x28
64 65
65struct axg_fifo { 66struct axg_fifo {
66 struct regmap *map; 67 struct regmap *map;
diff --git a/sound/soc/meson/axg-frddr.c b/sound/soc/meson/axg-frddr.c
index 2b8807737b2b..6ab111c31b28 100644
--- a/sound/soc/meson/axg-frddr.c
+++ b/sound/soc/meson/axg-frddr.c
@@ -23,6 +23,12 @@
23#define CTRL0_SEL3_SHIFT 8 23#define CTRL0_SEL3_SHIFT 8
24#define CTRL0_SEL3_EN_SHIFT 11 24#define CTRL0_SEL3_EN_SHIFT 11
25#define CTRL1_FRDDR_FORCE_FINISH BIT(12) 25#define CTRL1_FRDDR_FORCE_FINISH BIT(12)
26#define CTRL2_SEL1_SHIFT 0
27#define CTRL2_SEL1_EN_SHIFT 4
28#define CTRL2_SEL2_SHIFT 8
29#define CTRL2_SEL2_EN_SHIFT 12
30#define CTRL2_SEL3_SHIFT 16
31#define CTRL2_SEL3_EN_SHIFT 20
26 32
27static int g12a_frddr_dai_prepare(struct snd_pcm_substream *substream, 33static int g12a_frddr_dai_prepare(struct snd_pcm_substream *substream,
28 struct snd_soc_dai *dai) 34 struct snd_soc_dai *dai)
@@ -104,7 +110,7 @@ static struct snd_soc_dai_driver axg_frddr_dai_drv = {
104}; 110};
105 111
106static const char * const axg_frddr_sel_texts[] = { 112static const char * const axg_frddr_sel_texts[] = {
107 "OUT 0", "OUT 1", "OUT 2", "OUT 3" 113 "OUT 0", "OUT 1", "OUT 2", "OUT 3", "OUT 4", "OUT 5", "OUT 6", "OUT 7",
108}; 114};
109 115
110static SOC_ENUM_SINGLE_DECL(axg_frddr_sel_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT, 116static SOC_ENUM_SINGLE_DECL(axg_frddr_sel_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT,
@@ -120,6 +126,10 @@ static const struct snd_soc_dapm_widget axg_frddr_dapm_widgets[] = {
120 SND_SOC_DAPM_AIF_OUT("OUT 1", NULL, 0, SND_SOC_NOPM, 0, 0), 126 SND_SOC_DAPM_AIF_OUT("OUT 1", NULL, 0, SND_SOC_NOPM, 0, 0),
121 SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0), 127 SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0),
122 SND_SOC_DAPM_AIF_OUT("OUT 3", NULL, 0, SND_SOC_NOPM, 0, 0), 128 SND_SOC_DAPM_AIF_OUT("OUT 3", NULL, 0, SND_SOC_NOPM, 0, 0),
129 SND_SOC_DAPM_AIF_OUT("OUT 4", NULL, 0, SND_SOC_NOPM, 0, 0),
130 SND_SOC_DAPM_AIF_OUT("OUT 5", NULL, 0, SND_SOC_NOPM, 0, 0),
131 SND_SOC_DAPM_AIF_OUT("OUT 6", NULL, 0, SND_SOC_NOPM, 0, 0),
132 SND_SOC_DAPM_AIF_OUT("OUT 7", NULL, 0, SND_SOC_NOPM, 0, 0),
123}; 133};
124 134
125static const struct snd_soc_dapm_route axg_frddr_dapm_routes[] = { 135static const struct snd_soc_dapm_route axg_frddr_dapm_routes[] = {
@@ -128,6 +138,10 @@ static const struct snd_soc_dapm_route axg_frddr_dapm_routes[] = {
128 { "OUT 1", "OUT 1", "SINK SEL" }, 138 { "OUT 1", "OUT 1", "SINK SEL" },
129 { "OUT 2", "OUT 2", "SINK SEL" }, 139 { "OUT 2", "OUT 2", "SINK SEL" },
130 { "OUT 3", "OUT 3", "SINK SEL" }, 140 { "OUT 3", "OUT 3", "SINK SEL" },
141 { "OUT 4", "OUT 4", "SINK SEL" },
142 { "OUT 5", "OUT 5", "SINK SEL" },
143 { "OUT 6", "OUT 6", "SINK SEL" },
144 { "OUT 7", "OUT 7", "SINK SEL" },
131}; 145};
132 146
133static const struct snd_soc_component_driver axg_frddr_component_drv = { 147static const struct snd_soc_component_driver axg_frddr_component_drv = {
@@ -162,16 +176,12 @@ static struct snd_soc_dai_driver g12a_frddr_dai_drv = {
162 .pcm_new = axg_frddr_pcm_new, 176 .pcm_new = axg_frddr_pcm_new,
163}; 177};
164 178
165static const char * const g12a_frddr_sel_texts[] = {
166 "OUT 0", "OUT 1", "OUT 2", "OUT 3", "OUT 4",
167};
168
169static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel1_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT, 179static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel1_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT,
170 g12a_frddr_sel_texts); 180 axg_frddr_sel_texts);
171static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel2_enum, FIFO_CTRL0, CTRL0_SEL2_SHIFT, 181static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel2_enum, FIFO_CTRL0, CTRL0_SEL2_SHIFT,
172 g12a_frddr_sel_texts); 182 axg_frddr_sel_texts);
173static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel3_enum, FIFO_CTRL0, CTRL0_SEL3_SHIFT, 183static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel3_enum, FIFO_CTRL0, CTRL0_SEL3_SHIFT,
174 g12a_frddr_sel_texts); 184 axg_frddr_sel_texts);
175 185
176static const struct snd_kcontrol_new g12a_frddr_out1_demux = 186static const struct snd_kcontrol_new g12a_frddr_out1_demux =
177 SOC_DAPM_ENUM("Output Src 1", g12a_frddr_sel1_enum); 187 SOC_DAPM_ENUM("Output Src 1", g12a_frddr_sel1_enum);
@@ -211,6 +221,9 @@ static const struct snd_soc_dapm_widget g12a_frddr_dapm_widgets[] = {
211 SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0), 221 SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0),
212 SND_SOC_DAPM_AIF_OUT("OUT 3", NULL, 0, SND_SOC_NOPM, 0, 0), 222 SND_SOC_DAPM_AIF_OUT("OUT 3", NULL, 0, SND_SOC_NOPM, 0, 0),
213 SND_SOC_DAPM_AIF_OUT("OUT 4", NULL, 0, SND_SOC_NOPM, 0, 0), 223 SND_SOC_DAPM_AIF_OUT("OUT 4", NULL, 0, SND_SOC_NOPM, 0, 0),
224 SND_SOC_DAPM_AIF_OUT("OUT 5", NULL, 0, SND_SOC_NOPM, 0, 0),
225 SND_SOC_DAPM_AIF_OUT("OUT 6", NULL, 0, SND_SOC_NOPM, 0, 0),
226 SND_SOC_DAPM_AIF_OUT("OUT 7", NULL, 0, SND_SOC_NOPM, 0, 0),
214}; 227};
215 228
216static const struct snd_soc_dapm_route g12a_frddr_dapm_routes[] = { 229static const struct snd_soc_dapm_route g12a_frddr_dapm_routes[] = {
@@ -228,16 +241,25 @@ static const struct snd_soc_dapm_route g12a_frddr_dapm_routes[] = {
228 { "OUT 2", "OUT 2", "SINK 1 SEL" }, 241 { "OUT 2", "OUT 2", "SINK 1 SEL" },
229 { "OUT 3", "OUT 3", "SINK 1 SEL" }, 242 { "OUT 3", "OUT 3", "SINK 1 SEL" },
230 { "OUT 4", "OUT 4", "SINK 1 SEL" }, 243 { "OUT 4", "OUT 4", "SINK 1 SEL" },
244 { "OUT 5", "OUT 5", "SINK 1 SEL" },
245 { "OUT 6", "OUT 6", "SINK 1 SEL" },
246 { "OUT 7", "OUT 7", "SINK 1 SEL" },
231 { "OUT 0", "OUT 0", "SINK 2 SEL" }, 247 { "OUT 0", "OUT 0", "SINK 2 SEL" },
232 { "OUT 1", "OUT 1", "SINK 2 SEL" }, 248 { "OUT 1", "OUT 1", "SINK 2 SEL" },
233 { "OUT 2", "OUT 2", "SINK 2 SEL" }, 249 { "OUT 2", "OUT 2", "SINK 2 SEL" },
234 { "OUT 3", "OUT 3", "SINK 2 SEL" }, 250 { "OUT 3", "OUT 3", "SINK 2 SEL" },
235 { "OUT 4", "OUT 4", "SINK 2 SEL" }, 251 { "OUT 4", "OUT 4", "SINK 2 SEL" },
252 { "OUT 5", "OUT 5", "SINK 2 SEL" },
253 { "OUT 6", "OUT 6", "SINK 2 SEL" },
254 { "OUT 7", "OUT 7", "SINK 2 SEL" },
236 { "OUT 0", "OUT 0", "SINK 3 SEL" }, 255 { "OUT 0", "OUT 0", "SINK 3 SEL" },
237 { "OUT 1", "OUT 1", "SINK 3 SEL" }, 256 { "OUT 1", "OUT 1", "SINK 3 SEL" },
238 { "OUT 2", "OUT 2", "SINK 3 SEL" }, 257 { "OUT 2", "OUT 2", "SINK 3 SEL" },
239 { "OUT 3", "OUT 3", "SINK 3 SEL" }, 258 { "OUT 3", "OUT 3", "SINK 3 SEL" },
240 { "OUT 4", "OUT 4", "SINK 3 SEL" }, 259 { "OUT 4", "OUT 4", "SINK 3 SEL" },
260 { "OUT 5", "OUT 5", "SINK 3 SEL" },
261 { "OUT 6", "OUT 6", "SINK 3 SEL" },
262 { "OUT 7", "OUT 7", "SINK 3 SEL" },
241}; 263};
242 264
243static const struct snd_soc_component_driver g12a_frddr_component_drv = { 265static const struct snd_soc_component_driver g12a_frddr_component_drv = {
@@ -253,6 +275,70 @@ static const struct axg_fifo_match_data g12a_frddr_match_data = {
253 .dai_drv = &g12a_frddr_dai_drv 275 .dai_drv = &g12a_frddr_dai_drv
254}; 276};
255 277
278/* On SM1, the output selection in on CTRL2 */
279static const struct snd_kcontrol_new sm1_frddr_out1_enable =
280 SOC_DAPM_SINGLE_AUTODISABLE("Switch", FIFO_CTRL2,
281 CTRL2_SEL1_EN_SHIFT, 1, 0);
282static const struct snd_kcontrol_new sm1_frddr_out2_enable =
283 SOC_DAPM_SINGLE_AUTODISABLE("Switch", FIFO_CTRL2,
284 CTRL2_SEL2_EN_SHIFT, 1, 0);
285static const struct snd_kcontrol_new sm1_frddr_out3_enable =
286 SOC_DAPM_SINGLE_AUTODISABLE("Switch", FIFO_CTRL2,
287 CTRL2_SEL3_EN_SHIFT, 1, 0);
288
289static SOC_ENUM_SINGLE_DECL(sm1_frddr_sel1_enum, FIFO_CTRL2, CTRL2_SEL1_SHIFT,
290 axg_frddr_sel_texts);
291static SOC_ENUM_SINGLE_DECL(sm1_frddr_sel2_enum, FIFO_CTRL2, CTRL2_SEL2_SHIFT,
292 axg_frddr_sel_texts);
293static SOC_ENUM_SINGLE_DECL(sm1_frddr_sel3_enum, FIFO_CTRL2, CTRL2_SEL3_SHIFT,
294 axg_frddr_sel_texts);
295
296static const struct snd_kcontrol_new sm1_frddr_out1_demux =
297 SOC_DAPM_ENUM("Output Src 1", sm1_frddr_sel1_enum);
298static const struct snd_kcontrol_new sm1_frddr_out2_demux =
299 SOC_DAPM_ENUM("Output Src 2", sm1_frddr_sel2_enum);
300static const struct snd_kcontrol_new sm1_frddr_out3_demux =
301 SOC_DAPM_ENUM("Output Src 3", sm1_frddr_sel3_enum);
302
303static const struct snd_soc_dapm_widget sm1_frddr_dapm_widgets[] = {
304 SND_SOC_DAPM_AIF_OUT("SRC 1", NULL, 0, SND_SOC_NOPM, 0, 0),
305 SND_SOC_DAPM_AIF_OUT("SRC 2", NULL, 0, SND_SOC_NOPM, 0, 0),
306 SND_SOC_DAPM_AIF_OUT("SRC 3", NULL, 0, SND_SOC_NOPM, 0, 0),
307 SND_SOC_DAPM_SWITCH("SRC 1 EN", SND_SOC_NOPM, 0, 0,
308 &sm1_frddr_out1_enable),
309 SND_SOC_DAPM_SWITCH("SRC 2 EN", SND_SOC_NOPM, 0, 0,
310 &sm1_frddr_out2_enable),
311 SND_SOC_DAPM_SWITCH("SRC 3 EN", SND_SOC_NOPM, 0, 0,
312 &sm1_frddr_out3_enable),
313 SND_SOC_DAPM_DEMUX("SINK 1 SEL", SND_SOC_NOPM, 0, 0,
314 &sm1_frddr_out1_demux),
315 SND_SOC_DAPM_DEMUX("SINK 2 SEL", SND_SOC_NOPM, 0, 0,
316 &sm1_frddr_out2_demux),
317 SND_SOC_DAPM_DEMUX("SINK 3 SEL", SND_SOC_NOPM, 0, 0,
318 &sm1_frddr_out3_demux),
319 SND_SOC_DAPM_AIF_OUT("OUT 0", NULL, 0, SND_SOC_NOPM, 0, 0),
320 SND_SOC_DAPM_AIF_OUT("OUT 1", NULL, 0, SND_SOC_NOPM, 0, 0),
321 SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0),
322 SND_SOC_DAPM_AIF_OUT("OUT 3", NULL, 0, SND_SOC_NOPM, 0, 0),
323 SND_SOC_DAPM_AIF_OUT("OUT 4", NULL, 0, SND_SOC_NOPM, 0, 0),
324 SND_SOC_DAPM_AIF_OUT("OUT 5", NULL, 0, SND_SOC_NOPM, 0, 0),
325 SND_SOC_DAPM_AIF_OUT("OUT 6", NULL, 0, SND_SOC_NOPM, 0, 0),
326 SND_SOC_DAPM_AIF_OUT("OUT 7", NULL, 0, SND_SOC_NOPM, 0, 0),
327};
328
329static const struct snd_soc_component_driver sm1_frddr_component_drv = {
330 .dapm_widgets = sm1_frddr_dapm_widgets,
331 .num_dapm_widgets = ARRAY_SIZE(sm1_frddr_dapm_widgets),
332 .dapm_routes = g12a_frddr_dapm_routes,
333 .num_dapm_routes = ARRAY_SIZE(g12a_frddr_dapm_routes),
334 .ops = &g12a_fifo_pcm_ops
335};
336
337static const struct axg_fifo_match_data sm1_frddr_match_data = {
338 .component_drv = &sm1_frddr_component_drv,
339 .dai_drv = &g12a_frddr_dai_drv
340};
341
256static const struct of_device_id axg_frddr_of_match[] = { 342static const struct of_device_id axg_frddr_of_match[] = {
257 { 343 {
258 .compatible = "amlogic,axg-frddr", 344 .compatible = "amlogic,axg-frddr",
@@ -260,6 +346,9 @@ static const struct of_device_id axg_frddr_of_match[] = {
260 }, { 346 }, {
261 .compatible = "amlogic,g12a-frddr", 347 .compatible = "amlogic,g12a-frddr",
262 .data = &g12a_frddr_match_data, 348 .data = &g12a_frddr_match_data,
349 }, {
350 .compatible = "amlogic,sm1-frddr",
351 .data = &sm1_frddr_match_data,
263 }, {} 352 }, {}
264}; 353};
265MODULE_DEVICE_TABLE(of, axg_frddr_of_match); 354MODULE_DEVICE_TABLE(of, axg_frddr_of_match);
diff --git a/sound/soc/meson/axg-pdm.c b/sound/soc/meson/axg-pdm.c
index 9d5684493ffc..bfd37d49a73e 100644
--- a/sound/soc/meson/axg-pdm.c
+++ b/sound/soc/meson/axg-pdm.c
@@ -585,7 +585,6 @@ static int axg_pdm_probe(struct platform_device *pdev)
585{ 585{
586 struct device *dev = &pdev->dev; 586 struct device *dev = &pdev->dev;
587 struct axg_pdm *priv; 587 struct axg_pdm *priv;
588 struct resource *res;
589 void __iomem *regs; 588 void __iomem *regs;
590 int ret; 589 int ret;
591 590
@@ -600,8 +599,7 @@ static int axg_pdm_probe(struct platform_device *pdev)
600 return -ENODEV; 599 return -ENODEV;
601 } 600 }
602 601
603 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 602 regs = devm_platform_ioremap_resource(pdev, 0);
604 regs = devm_ioremap_resource(dev, res);
605 if (IS_ERR(regs)) 603 if (IS_ERR(regs))
606 return PTR_ERR(regs); 604 return PTR_ERR(regs);
607 605
diff --git a/sound/soc/meson/axg-spdifin.c b/sound/soc/meson/axg-spdifin.c
index 01b2035fa841..d0d09f945b48 100644
--- a/sound/soc/meson/axg-spdifin.c
+++ b/sound/soc/meson/axg-spdifin.c
@@ -453,7 +453,6 @@ static int axg_spdifin_probe(struct platform_device *pdev)
453 struct device *dev = &pdev->dev; 453 struct device *dev = &pdev->dev;
454 struct axg_spdifin *priv; 454 struct axg_spdifin *priv;
455 struct snd_soc_dai_driver *dai_drv; 455 struct snd_soc_dai_driver *dai_drv;
456 struct resource *res;
457 void __iomem *regs; 456 void __iomem *regs;
458 int ret; 457 int ret;
459 458
@@ -468,8 +467,7 @@ static int axg_spdifin_probe(struct platform_device *pdev)
468 return -ENODEV; 467 return -ENODEV;
469 } 468 }
470 469
471 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 470 regs = devm_platform_ioremap_resource(pdev, 0);
472 regs = devm_ioremap_resource(dev, res);
473 if (IS_ERR(regs)) 471 if (IS_ERR(regs))
474 return PTR_ERR(regs); 472 return PTR_ERR(regs);
475 473
diff --git a/sound/soc/meson/axg-spdifout.c b/sound/soc/meson/axg-spdifout.c
index 9dea528053ad..7ce6aa97ddf7 100644
--- a/sound/soc/meson/axg-spdifout.c
+++ b/sound/soc/meson/axg-spdifout.c
@@ -401,7 +401,6 @@ static int axg_spdifout_probe(struct platform_device *pdev)
401{ 401{
402 struct device *dev = &pdev->dev; 402 struct device *dev = &pdev->dev;
403 struct axg_spdifout *priv; 403 struct axg_spdifout *priv;
404 struct resource *res;
405 void __iomem *regs; 404 void __iomem *regs;
406 int ret; 405 int ret;
407 406
@@ -410,8 +409,7 @@ static int axg_spdifout_probe(struct platform_device *pdev)
410 return -ENOMEM; 409 return -ENOMEM;
411 platform_set_drvdata(pdev, priv); 410 platform_set_drvdata(pdev, priv);
412 411
413 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 412 regs = devm_platform_ioremap_resource(pdev, 0);
414 regs = devm_ioremap_resource(dev, res);
415 if (IS_ERR(regs)) 413 if (IS_ERR(regs))
416 return PTR_ERR(regs); 414 return PTR_ERR(regs);
417 415
diff --git a/sound/soc/meson/axg-tdm-formatter.c b/sound/soc/meson/axg-tdm-formatter.c
index 1a0bf9d3836d..358c8c0d861c 100644
--- a/sound/soc/meson/axg-tdm-formatter.c
+++ b/sound/soc/meson/axg-tdm-formatter.c
@@ -253,7 +253,6 @@ int axg_tdm_formatter_probe(struct platform_device *pdev)
253 struct device *dev = &pdev->dev; 253 struct device *dev = &pdev->dev;
254 const struct axg_tdm_formatter_driver *drv; 254 const struct axg_tdm_formatter_driver *drv;
255 struct axg_tdm_formatter *formatter; 255 struct axg_tdm_formatter *formatter;
256 struct resource *res;
257 void __iomem *regs; 256 void __iomem *regs;
258 int ret; 257 int ret;
259 258
@@ -269,8 +268,7 @@ int axg_tdm_formatter_probe(struct platform_device *pdev)
269 platform_set_drvdata(pdev, formatter); 268 platform_set_drvdata(pdev, formatter);
270 formatter->drv = drv; 269 formatter->drv = drv;
271 270
272 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 271 regs = devm_platform_ioremap_resource(pdev, 0);
273 regs = devm_ioremap_resource(dev, res);
274 if (IS_ERR(regs)) 272 if (IS_ERR(regs))
275 return PTR_ERR(regs); 273 return PTR_ERR(regs);
276 274
diff --git a/sound/soc/meson/axg-tdmin.c b/sound/soc/meson/axg-tdmin.c
index cb87f17f3e95..973d4c02ef8d 100644
--- a/sound/soc/meson/axg-tdmin.c
+++ b/sound/soc/meson/axg-tdmin.c
@@ -43,7 +43,8 @@ static const struct regmap_config axg_tdmin_regmap_cfg = {
43}; 43};
44 44
45static const char * const axg_tdmin_sel_texts[] = { 45static const char * const axg_tdmin_sel_texts[] = {
46 "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", 46 "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", "IN 6", "IN 7",
47 "IN 8", "IN 9", "IN 10", "IN 11", "IN 12", "IN 13", "IN 14", "IN 15",
47}; 48};
48 49
49/* Change to special mux control to reset dapm */ 50/* Change to special mux control to reset dapm */
@@ -164,12 +165,22 @@ static int axg_tdmin_prepare(struct regmap *map,
164} 165}
165 166
166static const struct snd_soc_dapm_widget axg_tdmin_dapm_widgets[] = { 167static const struct snd_soc_dapm_widget axg_tdmin_dapm_widgets[] = {
167 SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), 168 SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0),
168 SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0), 169 SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0),
169 SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), 170 SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0),
170 SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), 171 SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0),
171 SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0), 172 SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0),
172 SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0), 173 SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0),
174 SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0),
175 SND_SOC_DAPM_AIF_IN("IN 7", NULL, 0, SND_SOC_NOPM, 0, 0),
176 SND_SOC_DAPM_AIF_IN("IN 8", NULL, 0, SND_SOC_NOPM, 0, 0),
177 SND_SOC_DAPM_AIF_IN("IN 9", NULL, 0, SND_SOC_NOPM, 0, 0),
178 SND_SOC_DAPM_AIF_IN("IN 10", NULL, 0, SND_SOC_NOPM, 0, 0),
179 SND_SOC_DAPM_AIF_IN("IN 11", NULL, 0, SND_SOC_NOPM, 0, 0),
180 SND_SOC_DAPM_AIF_IN("IN 12", NULL, 0, SND_SOC_NOPM, 0, 0),
181 SND_SOC_DAPM_AIF_IN("IN 13", NULL, 0, SND_SOC_NOPM, 0, 0),
182 SND_SOC_DAPM_AIF_IN("IN 14", NULL, 0, SND_SOC_NOPM, 0, 0),
183 SND_SOC_DAPM_AIF_IN("IN 15", NULL, 0, SND_SOC_NOPM, 0, 0),
173 SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &axg_tdmin_in_mux), 184 SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &axg_tdmin_in_mux),
174 SND_SOC_DAPM_PGA_E("DEC", SND_SOC_NOPM, 0, 0, NULL, 0, 185 SND_SOC_DAPM_PGA_E("DEC", SND_SOC_NOPM, 0, 0, NULL, 0,
175 axg_tdm_formatter_event, 186 axg_tdm_formatter_event,
@@ -178,12 +189,22 @@ static const struct snd_soc_dapm_widget axg_tdmin_dapm_widgets[] = {
178}; 189};
179 190
180static const struct snd_soc_dapm_route axg_tdmin_dapm_routes[] = { 191static const struct snd_soc_dapm_route axg_tdmin_dapm_routes[] = {
181 { "SRC SEL", "IN 0", "IN 0" }, 192 { "SRC SEL", "IN 0", "IN 0" },
182 { "SRC SEL", "IN 1", "IN 1" }, 193 { "SRC SEL", "IN 1", "IN 1" },
183 { "SRC SEL", "IN 2", "IN 2" }, 194 { "SRC SEL", "IN 2", "IN 2" },
184 { "SRC SEL", "IN 3", "IN 3" }, 195 { "SRC SEL", "IN 3", "IN 3" },
185 { "SRC SEL", "IN 4", "IN 4" }, 196 { "SRC SEL", "IN 4", "IN 4" },
186 { "SRC SEL", "IN 5", "IN 5" }, 197 { "SRC SEL", "IN 5", "IN 5" },
198 { "SRC SEL", "IN 6", "IN 6" },
199 { "SRC SEL", "IN 7", "IN 7" },
200 { "SRC SEL", "IN 8", "IN 8" },
201 { "SRC SEL", "IN 9", "IN 9" },
202 { "SRC SEL", "IN 10", "IN 10" },
203 { "SRC SEL", "IN 11", "IN 11" },
204 { "SRC SEL", "IN 12", "IN 12" },
205 { "SRC SEL", "IN 13", "IN 13" },
206 { "SRC SEL", "IN 14", "IN 14" },
207 { "SRC SEL", "IN 15", "IN 15" },
187 { "DEC", NULL, "SRC SEL" }, 208 { "DEC", NULL, "SRC SEL" },
188 { "OUT", NULL, "DEC" }, 209 { "OUT", NULL, "DEC" },
189}; 210};
diff --git a/sound/soc/meson/axg-tdmout.c b/sound/soc/meson/axg-tdmout.c
index 86537fc0ecb5..418ec314b37d 100644
--- a/sound/soc/meson/axg-tdmout.c
+++ b/sound/soc/meson/axg-tdmout.c
@@ -24,6 +24,7 @@
24#define TDMOUT_CTRL1 0x04 24#define TDMOUT_CTRL1 0x04
25#define TDMOUT_CTRL1_TYPE_MASK GENMASK(6, 4) 25#define TDMOUT_CTRL1_TYPE_MASK GENMASK(6, 4)
26#define TDMOUT_CTRL1_TYPE(x) ((x) << 4) 26#define TDMOUT_CTRL1_TYPE(x) ((x) << 4)
27#define SM1_TDMOUT_CTRL1_GAIN_EN 7
27#define TDMOUT_CTRL1_MSB_POS_MASK GENMASK(12, 8) 28#define TDMOUT_CTRL1_MSB_POS_MASK GENMASK(12, 8)
28#define TDMOUT_CTRL1_MSB_POS(x) ((x) << 8) 29#define TDMOUT_CTRL1_MSB_POS(x) ((x) << 8)
29#define TDMOUT_CTRL1_SEL_SHIFT 24 30#define TDMOUT_CTRL1_SEL_SHIFT 24
@@ -51,25 +52,6 @@ static const struct regmap_config axg_tdmout_regmap_cfg = {
51 .max_register = TDMOUT_MASK_VAL, 52 .max_register = TDMOUT_MASK_VAL,
52}; 53};
53 54
54static const struct snd_kcontrol_new axg_tdmout_controls[] = {
55 SOC_DOUBLE("Lane 0 Volume", TDMOUT_GAIN0, 0, 8, 255, 0),
56 SOC_DOUBLE("Lane 1 Volume", TDMOUT_GAIN0, 16, 24, 255, 0),
57 SOC_DOUBLE("Lane 2 Volume", TDMOUT_GAIN1, 0, 8, 255, 0),
58 SOC_DOUBLE("Lane 3 Volume", TDMOUT_GAIN1, 16, 24, 255, 0),
59 SOC_SINGLE("Gain Enable Switch", TDMOUT_CTRL1,
60 TDMOUT_CTRL1_GAIN_EN, 1, 0),
61};
62
63static const char * const tdmout_sel_texts[] = {
64 "IN 0", "IN 1", "IN 2",
65};
66
67static SOC_ENUM_SINGLE_DECL(axg_tdmout_sel_enum, TDMOUT_CTRL1,
68 TDMOUT_CTRL1_SEL_SHIFT, tdmout_sel_texts);
69
70static const struct snd_kcontrol_new axg_tdmout_in_mux =
71 SOC_DAPM_ENUM("Input Source", axg_tdmout_sel_enum);
72
73static struct snd_soc_dai * 55static struct snd_soc_dai *
74axg_tdmout_get_be(struct snd_soc_dapm_widget *w) 56axg_tdmout_get_be(struct snd_soc_dapm_widget *w)
75{ 57{
@@ -197,6 +179,25 @@ static int axg_tdmout_prepare(struct regmap *map,
197 return axg_tdm_formatter_set_channel_masks(map, ts, TDMOUT_MASK0); 179 return axg_tdm_formatter_set_channel_masks(map, ts, TDMOUT_MASK0);
198} 180}
199 181
182static const struct snd_kcontrol_new axg_tdmout_controls[] = {
183 SOC_DOUBLE("Lane 0 Volume", TDMOUT_GAIN0, 0, 8, 255, 0),
184 SOC_DOUBLE("Lane 1 Volume", TDMOUT_GAIN0, 16, 24, 255, 0),
185 SOC_DOUBLE("Lane 2 Volume", TDMOUT_GAIN1, 0, 8, 255, 0),
186 SOC_DOUBLE("Lane 3 Volume", TDMOUT_GAIN1, 16, 24, 255, 0),
187 SOC_SINGLE("Gain Enable Switch", TDMOUT_CTRL1,
188 TDMOUT_CTRL1_GAIN_EN, 1, 0),
189};
190
191static const char * const axg_tdmout_sel_texts[] = {
192 "IN 0", "IN 1", "IN 2",
193};
194
195static SOC_ENUM_SINGLE_DECL(axg_tdmout_sel_enum, TDMOUT_CTRL1,
196 TDMOUT_CTRL1_SEL_SHIFT, axg_tdmout_sel_texts);
197
198static const struct snd_kcontrol_new axg_tdmout_in_mux =
199 SOC_DAPM_ENUM("Input Source", axg_tdmout_sel_enum);
200
200static const struct snd_soc_dapm_widget axg_tdmout_dapm_widgets[] = { 201static const struct snd_soc_dapm_widget axg_tdmout_dapm_widgets[] = {
201 SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), 202 SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0),
202 SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0), 203 SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0),
@@ -252,6 +253,67 @@ static const struct axg_tdm_formatter_driver g12a_tdmout_drv = {
252 }, 253 },
253}; 254};
254 255
256static const struct snd_kcontrol_new sm1_tdmout_controls[] = {
257 SOC_DOUBLE("Lane 0 Volume", TDMOUT_GAIN0, 0, 8, 255, 0),
258 SOC_DOUBLE("Lane 1 Volume", TDMOUT_GAIN0, 16, 24, 255, 0),
259 SOC_DOUBLE("Lane 2 Volume", TDMOUT_GAIN1, 0, 8, 255, 0),
260 SOC_DOUBLE("Lane 3 Volume", TDMOUT_GAIN1, 16, 24, 255, 0),
261 SOC_SINGLE("Gain Enable Switch", TDMOUT_CTRL1,
262 SM1_TDMOUT_CTRL1_GAIN_EN, 1, 0),
263};
264
265static const char * const sm1_tdmout_sel_texts[] = {
266 "IN 0", "IN 1", "IN 2", "IN 3", "IN 4",
267};
268
269static SOC_ENUM_SINGLE_DECL(sm1_tdmout_sel_enum, TDMOUT_CTRL1,
270 TDMOUT_CTRL1_SEL_SHIFT, sm1_tdmout_sel_texts);
271
272static const struct snd_kcontrol_new sm1_tdmout_in_mux =
273 SOC_DAPM_ENUM("Input Source", sm1_tdmout_sel_enum);
274
275static const struct snd_soc_dapm_widget sm1_tdmout_dapm_widgets[] = {
276 SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0),
277 SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0),
278 SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0),
279 SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0),
280 SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0),
281 SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &sm1_tdmout_in_mux),
282 SND_SOC_DAPM_PGA_E("ENC", SND_SOC_NOPM, 0, 0, NULL, 0,
283 axg_tdm_formatter_event,
284 (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD)),
285 SND_SOC_DAPM_AIF_OUT("OUT", NULL, 0, SND_SOC_NOPM, 0, 0),
286};
287
288static const struct snd_soc_dapm_route sm1_tdmout_dapm_routes[] = {
289 { "SRC SEL", "IN 0", "IN 0" },
290 { "SRC SEL", "IN 1", "IN 1" },
291 { "SRC SEL", "IN 2", "IN 2" },
292 { "SRC SEL", "IN 3", "IN 3" },
293 { "SRC SEL", "IN 4", "IN 4" },
294 { "ENC", NULL, "SRC SEL" },
295 { "OUT", NULL, "ENC" },
296};
297
298static const struct snd_soc_component_driver sm1_tdmout_component_drv = {
299 .controls = sm1_tdmout_controls,
300 .num_controls = ARRAY_SIZE(sm1_tdmout_controls),
301 .dapm_widgets = sm1_tdmout_dapm_widgets,
302 .num_dapm_widgets = ARRAY_SIZE(sm1_tdmout_dapm_widgets),
303 .dapm_routes = sm1_tdmout_dapm_routes,
304 .num_dapm_routes = ARRAY_SIZE(sm1_tdmout_dapm_routes),
305};
306
307static const struct axg_tdm_formatter_driver sm1_tdmout_drv = {
308 .component_drv = &sm1_tdmout_component_drv,
309 .regmap_cfg = &axg_tdmout_regmap_cfg,
310 .ops = &axg_tdmout_ops,
311 .quirks = &(const struct axg_tdm_formatter_hw) {
312 .invert_sclk = true,
313 .skew_offset = 2,
314 },
315};
316
255static const struct of_device_id axg_tdmout_of_match[] = { 317static const struct of_device_id axg_tdmout_of_match[] = {
256 { 318 {
257 .compatible = "amlogic,axg-tdmout", 319 .compatible = "amlogic,axg-tdmout",
@@ -259,6 +321,9 @@ static const struct of_device_id axg_tdmout_of_match[] = {
259 }, { 321 }, {
260 .compatible = "amlogic,g12a-tdmout", 322 .compatible = "amlogic,g12a-tdmout",
261 .data = &g12a_tdmout_drv, 323 .data = &g12a_tdmout_drv,
324 }, {
325 .compatible = "amlogic,sm1-tdmout",
326 .data = &sm1_tdmout_drv,
262 }, {} 327 }, {}
263}; 328};
264MODULE_DEVICE_TABLE(of, axg_tdmout_of_match); 329MODULE_DEVICE_TABLE(of, axg_tdmout_of_match);
diff --git a/sound/soc/meson/axg-toddr.c b/sound/soc/meson/axg-toddr.c
index 4f63e434fad4..c8ea2145f576 100644
--- a/sound/soc/meson/axg-toddr.c
+++ b/sound/soc/meson/axg-toddr.c
@@ -25,6 +25,7 @@
25#define CTRL0_TODDR_LSB_POS_MASK GENMASK(7, 3) 25#define CTRL0_TODDR_LSB_POS_MASK GENMASK(7, 3)
26#define CTRL0_TODDR_LSB_POS(x) ((x) << 3) 26#define CTRL0_TODDR_LSB_POS(x) ((x) << 3)
27#define CTRL1_TODDR_FORCE_FINISH BIT(25) 27#define CTRL1_TODDR_FORCE_FINISH BIT(25)
28#define CTRL1_SEL_SHIFT 28
28 29
29#define TODDR_MSB_POS 31 30#define TODDR_MSB_POS 31
30 31
@@ -142,16 +143,11 @@ static struct snd_soc_dai_driver axg_toddr_dai_drv = {
142}; 143};
143 144
144static const char * const axg_toddr_sel_texts[] = { 145static const char * const axg_toddr_sel_texts[] = {
145 "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 6" 146 "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", "IN 6", "IN 7"
146}; 147};
147 148
148static const unsigned int axg_toddr_sel_values[] = { 149static SOC_ENUM_SINGLE_DECL(axg_toddr_sel_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT,
149 0, 1, 2, 3, 4, 6 150 axg_toddr_sel_texts);
150};
151
152static SOC_VALUE_ENUM_SINGLE_DECL(axg_toddr_sel_enum, FIFO_CTRL0,
153 CTRL0_SEL_SHIFT, CTRL0_SEL_MASK,
154 axg_toddr_sel_texts, axg_toddr_sel_values);
155 151
156static const struct snd_kcontrol_new axg_toddr_in_mux = 152static const struct snd_kcontrol_new axg_toddr_in_mux =
157 SOC_DAPM_ENUM("Input Source", axg_toddr_sel_enum); 153 SOC_DAPM_ENUM("Input Source", axg_toddr_sel_enum);
@@ -163,7 +159,9 @@ static const struct snd_soc_dapm_widget axg_toddr_dapm_widgets[] = {
163 SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), 159 SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0),
164 SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), 160 SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0),
165 SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0), 161 SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0),
162 SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0),
166 SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0), 163 SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0),
164 SND_SOC_DAPM_AIF_IN("IN 7", NULL, 0, SND_SOC_NOPM, 0, 0),
167}; 165};
168 166
169static const struct snd_soc_dapm_route axg_toddr_dapm_routes[] = { 167static const struct snd_soc_dapm_route axg_toddr_dapm_routes[] = {
@@ -173,7 +171,9 @@ static const struct snd_soc_dapm_route axg_toddr_dapm_routes[] = {
173 { "SRC SEL", "IN 2", "IN 2" }, 171 { "SRC SEL", "IN 2", "IN 2" },
174 { "SRC SEL", "IN 3", "IN 3" }, 172 { "SRC SEL", "IN 3", "IN 3" },
175 { "SRC SEL", "IN 4", "IN 4" }, 173 { "SRC SEL", "IN 4", "IN 4" },
174 { "SRC SEL", "IN 5", "IN 5" },
176 { "SRC SEL", "IN 6", "IN 6" }, 175 { "SRC SEL", "IN 6", "IN 6" },
176 { "SRC SEL", "IN 7", "IN 7" },
177}; 177};
178 178
179static const struct snd_soc_component_driver axg_toddr_component_drv = { 179static const struct snd_soc_component_driver axg_toddr_component_drv = {
@@ -222,6 +222,70 @@ static const struct axg_fifo_match_data g12a_toddr_match_data = {
222 .dai_drv = &g12a_toddr_dai_drv 222 .dai_drv = &g12a_toddr_dai_drv
223}; 223};
224 224
225static const char * const sm1_toddr_sel_texts[] = {
226 "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", "IN 6", "IN 7",
227 "IN 8", "IN 9", "IN 10", "IN 11", "IN 12", "IN 13", "IN 14", "IN 15"
228};
229
230static SOC_ENUM_SINGLE_DECL(sm1_toddr_sel_enum, FIFO_CTRL1, CTRL1_SEL_SHIFT,
231 sm1_toddr_sel_texts);
232
233static const struct snd_kcontrol_new sm1_toddr_in_mux =
234 SOC_DAPM_ENUM("Input Source", sm1_toddr_sel_enum);
235
236static const struct snd_soc_dapm_widget sm1_toddr_dapm_widgets[] = {
237 SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &sm1_toddr_in_mux),
238 SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0),
239 SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0),
240 SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0),
241 SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0),
242 SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0),
243 SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0),
244 SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0),
245 SND_SOC_DAPM_AIF_IN("IN 7", NULL, 0, SND_SOC_NOPM, 0, 0),
246 SND_SOC_DAPM_AIF_IN("IN 8", NULL, 0, SND_SOC_NOPM, 0, 0),
247 SND_SOC_DAPM_AIF_IN("IN 9", NULL, 0, SND_SOC_NOPM, 0, 0),
248 SND_SOC_DAPM_AIF_IN("IN 10", NULL, 0, SND_SOC_NOPM, 0, 0),
249 SND_SOC_DAPM_AIF_IN("IN 11", NULL, 0, SND_SOC_NOPM, 0, 0),
250 SND_SOC_DAPM_AIF_IN("IN 12", NULL, 0, SND_SOC_NOPM, 0, 0),
251 SND_SOC_DAPM_AIF_IN("IN 13", NULL, 0, SND_SOC_NOPM, 0, 0),
252 SND_SOC_DAPM_AIF_IN("IN 14", NULL, 0, SND_SOC_NOPM, 0, 0),
253 SND_SOC_DAPM_AIF_IN("IN 15", NULL, 0, SND_SOC_NOPM, 0, 0),
254};
255
256static const struct snd_soc_dapm_route sm1_toddr_dapm_routes[] = {
257 { "Capture", NULL, "SRC SEL" },
258 { "SRC SEL", "IN 0", "IN 0" },
259 { "SRC SEL", "IN 1", "IN 1" },
260 { "SRC SEL", "IN 2", "IN 2" },
261 { "SRC SEL", "IN 3", "IN 3" },
262 { "SRC SEL", "IN 4", "IN 4" },
263 { "SRC SEL", "IN 5", "IN 5" },
264 { "SRC SEL", "IN 6", "IN 6" },
265 { "SRC SEL", "IN 7", "IN 7" },
266 { "SRC SEL", "IN 8", "IN 8" },
267 { "SRC SEL", "IN 9", "IN 9" },
268 { "SRC SEL", "IN 10", "IN 10" },
269 { "SRC SEL", "IN 11", "IN 11" },
270 { "SRC SEL", "IN 12", "IN 12" },
271 { "SRC SEL", "IN 13", "IN 13" },
272 { "SRC SEL", "IN 14", "IN 14" },
273 { "SRC SEL", "IN 15", "IN 15" },
274};
275
276static const struct snd_soc_component_driver sm1_toddr_component_drv = {
277 .dapm_widgets = sm1_toddr_dapm_widgets,
278 .num_dapm_widgets = ARRAY_SIZE(sm1_toddr_dapm_widgets),
279 .dapm_routes = sm1_toddr_dapm_routes,
280 .num_dapm_routes = ARRAY_SIZE(sm1_toddr_dapm_routes),
281 .ops = &g12a_fifo_pcm_ops
282};
283
284static const struct axg_fifo_match_data sm1_toddr_match_data = {
285 .component_drv = &sm1_toddr_component_drv,
286 .dai_drv = &g12a_toddr_dai_drv
287};
288
225static const struct of_device_id axg_toddr_of_match[] = { 289static const struct of_device_id axg_toddr_of_match[] = {
226 { 290 {
227 .compatible = "amlogic,axg-toddr", 291 .compatible = "amlogic,axg-toddr",
@@ -229,6 +293,9 @@ static const struct of_device_id axg_toddr_of_match[] = {
229 }, { 293 }, {
230 .compatible = "amlogic,g12a-toddr", 294 .compatible = "amlogic,g12a-toddr",
231 .data = &g12a_toddr_match_data, 295 .data = &g12a_toddr_match_data,
296 }, {
297 .compatible = "amlogic,sm1-toddr",
298 .data = &sm1_toddr_match_data,
232 }, {} 299 }, {}
233}; 300};
234MODULE_DEVICE_TABLE(of, axg_toddr_of_match); 301MODULE_DEVICE_TABLE(of, axg_toddr_of_match);
diff --git a/sound/soc/meson/g12a-tohdmitx.c b/sound/soc/meson/g12a-tohdmitx.c
index 707ccb192e4c..9cfbd343a00c 100644
--- a/sound/soc/meson/g12a-tohdmitx.c
+++ b/sound/soc/meson/g12a-tohdmitx.c
@@ -28,7 +28,7 @@
28#define CTRL0_SPDIF_CLK_SEL BIT(0) 28#define CTRL0_SPDIF_CLK_SEL BIT(0)
29 29
30struct g12a_tohdmitx_input { 30struct g12a_tohdmitx_input {
31 struct snd_pcm_hw_params params; 31 struct snd_soc_pcm_stream params;
32 unsigned int fmt; 32 unsigned int fmt;
33}; 33};
34 34
@@ -225,26 +225,17 @@ static int g12a_tohdmitx_input_hw_params(struct snd_pcm_substream *substream,
225{ 225{
226 struct g12a_tohdmitx_input *data = dai->playback_dma_data; 226 struct g12a_tohdmitx_input *data = dai->playback_dma_data;
227 227
228 /* Save the stream params for the downstream link */ 228 data->params.rates = snd_pcm_rate_to_rate_bit(params_rate(params));
229 memcpy(&data->params, params, sizeof(*params)); 229 data->params.rate_min = params_rate(params);
230 data->params.rate_max = params_rate(params);
231 data->params.formats = 1 << params_format(params);
232 data->params.channels_min = params_channels(params);
233 data->params.channels_max = params_channels(params);
234 data->params.sig_bits = dai->driver->playback.sig_bits;
230 235
231 return 0; 236 return 0;
232} 237}
233 238
234static int g12a_tohdmitx_output_hw_params(struct snd_pcm_substream *substream,
235 struct snd_pcm_hw_params *params,
236 struct snd_soc_dai *dai)
237{
238 struct g12a_tohdmitx_input *in_data =
239 g12a_tohdmitx_get_input_data(dai->capture_widget);
240
241 if (!in_data)
242 return -ENODEV;
243
244 memcpy(params, &in_data->params, sizeof(*params));
245
246 return 0;
247}
248 239
249static int g12a_tohdmitx_input_set_fmt(struct snd_soc_dai *dai, 240static int g12a_tohdmitx_input_set_fmt(struct snd_soc_dai *dai,
250 unsigned int fmt) 241 unsigned int fmt)
@@ -266,6 +257,14 @@ static int g12a_tohdmitx_output_startup(struct snd_pcm_substream *substream,
266 if (!in_data) 257 if (!in_data)
267 return -ENODEV; 258 return -ENODEV;
268 259
260 if (WARN_ON(!rtd->dai_link->params)) {
261 dev_warn(dai->dev, "codec2codec link expected\n");
262 return -EINVAL;
263 }
264
265 /* Replace link params with the input params */
266 rtd->dai_link->params = &in_data->params;
267
269 if (!in_data->fmt) 268 if (!in_data->fmt)
270 return 0; 269 return 0;
271 270
@@ -278,7 +277,6 @@ static const struct snd_soc_dai_ops g12a_tohdmitx_input_ops = {
278}; 277};
279 278
280static const struct snd_soc_dai_ops g12a_tohdmitx_output_ops = { 279static const struct snd_soc_dai_ops g12a_tohdmitx_output_ops = {
281 .hw_params = g12a_tohdmitx_output_hw_params,
282 .startup = g12a_tohdmitx_output_startup, 280 .startup = g12a_tohdmitx_output_startup,
283}; 281};
284 282
@@ -378,12 +376,10 @@ MODULE_DEVICE_TABLE(of, g12a_tohdmitx_of_match);
378static int g12a_tohdmitx_probe(struct platform_device *pdev) 376static int g12a_tohdmitx_probe(struct platform_device *pdev)
379{ 377{
380 struct device *dev = &pdev->dev; 378 struct device *dev = &pdev->dev;
381 struct resource *res;
382 void __iomem *regs; 379 void __iomem *regs;
383 struct regmap *map; 380 struct regmap *map;
384 381
385 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 382 regs = devm_platform_ioremap_resource(pdev, 0);
386 regs = devm_ioremap_resource(dev, res);
387 if (IS_ERR(regs)) 383 if (IS_ERR(regs))
388 return PTR_ERR(regs); 384 return PTR_ERR(regs);
389 385
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index 269b6d6df250..1e38ce858326 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -732,7 +732,6 @@ static int mxs_saif_mclk_init(struct platform_device *pdev)
732static int mxs_saif_probe(struct platform_device *pdev) 732static int mxs_saif_probe(struct platform_device *pdev)
733{ 733{
734 struct device_node *np = pdev->dev.of_node; 734 struct device_node *np = pdev->dev.of_node;
735 struct resource *iores;
736 struct mxs_saif *saif; 735 struct mxs_saif *saif;
737 int irq, ret = 0; 736 int irq, ret = 0;
738 struct device_node *master; 737 struct device_node *master;
@@ -786,19 +785,13 @@ static int mxs_saif_probe(struct platform_device *pdev)
786 return ret; 785 return ret;
787 } 786 }
788 787
789 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 788 saif->base = devm_platform_ioremap_resource(pdev, 0);
790
791 saif->base = devm_ioremap_resource(&pdev->dev, iores);
792 if (IS_ERR(saif->base)) 789 if (IS_ERR(saif->base))
793 return PTR_ERR(saif->base); 790 return PTR_ERR(saif->base);
794 791
795 irq = platform_get_irq(pdev, 0); 792 irq = platform_get_irq(pdev, 0);
796 if (irq < 0) { 793 if (irq < 0)
797 ret = irq; 794 return irq;
798 dev_err(&pdev->dev, "failed to get irq resource: %d\n",
799 ret);
800 return ret;
801 }
802 795
803 saif->dev = &pdev->dev; 796 saif->dev = &pdev->dev;
804 ret = devm_request_irq(&pdev->dev, irq, mxs_saif_irq, 0, 797 ret = devm_request_irq(&pdev->dev, irq, mxs_saif_irq, 0,
diff --git a/sound/soc/nuc900/Kconfig b/sound/soc/nuc900/Kconfig
deleted file mode 100644
index e1b22fbcb159..000000000000
--- a/sound/soc/nuc900/Kconfig
+++ /dev/null
@@ -1,29 +0,0 @@
1# SPDX-License-Identifier: GPL-2.0-only
2##
3## NUC900 series AC97 API
4##
5config SND_SOC_NUC900
6 tristate "SoC Audio for NUC900 series"
7 depends on ARCH_W90X900
8 select SND_SOC_NUC900_AC97
9 help
10 This option enables support for AC97 mode on the NUC900 SoC.
11
12config SND_SOC_NUC900_AC97
13 tristate
14 select AC97_BUS
15 select SND_AC97_CODEC
16 select SND_SOC_AC97_BUS
17
18
19##
20## Boards
21##
22config SND_SOC_NUC900EVB
23 tristate "NUC900 AC97 support for demo board"
24 depends on SND_SOC_NUC900
25 select SND_SOC_NUC900_AC97
26 select SND_SOC_AC97_CODEC
27 help
28 Select this option to enable audio (AC97) on the
29 NUC900 demoboard.
diff --git a/sound/soc/nuc900/Makefile b/sound/soc/nuc900/Makefile
deleted file mode 100644
index c7ba2b9549d2..000000000000
--- a/sound/soc/nuc900/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
1# SPDX-License-Identifier: GPL-2.0
2# NUC900 series audio
3snd-soc-nuc900-pcm-objs := nuc900-pcm.o
4snd-soc-nuc900-ac97-objs := nuc900-ac97.o
5
6obj-$(CONFIG_SND_SOC_NUC900) += snd-soc-nuc900-pcm.o
7obj-$(CONFIG_SND_SOC_NUC900_AC97) += snd-soc-nuc900-ac97.o
8
9# Boards
10snd-soc-nuc900-audio-objs := nuc900-audio.o
11
12obj-$(CONFIG_SND_SOC_NUC900EVB) += snd-soc-nuc900-audio.o
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c
deleted file mode 100644
index 5f2e5c069377..000000000000
--- a/sound/soc/nuc900/nuc900-ac97.c
+++ /dev/null
@@ -1,391 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2009-2010 Nuvoton technology corporation.
4 *
5 * Wan ZongShun <mcuos.com@gmail.com>
6 */
7
8#include <linux/init.h>
9#include <linux/module.h>
10#include <linux/slab.h>
11#include <linux/device.h>
12#include <linux/delay.h>
13#include <linux/mutex.h>
14#include <linux/suspend.h>
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/initval.h>
18#include <sound/soc.h>
19#include <linux/clk.h>
20
21#include <mach/mfp.h>
22
23#include "nuc900-audio.h"
24
25static DEFINE_MUTEX(ac97_mutex);
26struct nuc900_audio *nuc900_ac97_data;
27EXPORT_SYMBOL_GPL(nuc900_ac97_data);
28
29static int nuc900_checkready(void)
30{
31 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
32
33 if (!(AUDIO_READ(nuc900_audio->mmio + ACTL_ACIS0) & CODEC_READY))
34 return -EPERM;
35
36 return 0;
37}
38
39/* AC97 controller reads codec register */
40static unsigned short nuc900_ac97_read(struct snd_ac97 *ac97,
41 unsigned short reg)
42{
43 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
44 unsigned long timeout = 0x10000, val;
45
46 mutex_lock(&ac97_mutex);
47
48 val = nuc900_checkready();
49 if (val) {
50 dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
51 goto out;
52 }
53
54 /* set the R_WB bit and write register index */
55 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS1, R_WB | reg);
56
57 /* set the valid frame bit and valid slots */
58 val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
59 val |= (VALID_FRAME | SLOT1_VALID);
60 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, val);
61
62 udelay(100);
63
64 /* polling the AC_R_FINISH */
65 while (!(AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_R_FINISH)
66 && --timeout)
67 mdelay(1);
68
69 if (!timeout) {
70 dev_err(nuc900_audio->dev, "AC97 read register time out !\n");
71 val = -EPERM;
72 goto out;
73 }
74
75 val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0) ;
76 val &= ~SLOT1_VALID;
77 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, val);
78
79 if (AUDIO_READ(nuc900_audio->mmio + ACTL_ACIS1) >> 2 != reg) {
80 dev_err(nuc900_audio->dev,
81 "R_INDEX of REG_ACTL_ACIS1 not match!\n");
82 }
83
84 udelay(100);
85 val = (AUDIO_READ(nuc900_audio->mmio + ACTL_ACIS2) & 0xFFFF);
86
87out:
88 mutex_unlock(&ac97_mutex);
89 return val;
90}
91
92/* AC97 controller writes to codec register */
93static void nuc900_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
94 unsigned short val)
95{
96 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
97 unsigned long tmp, timeout = 0x10000;
98
99 mutex_lock(&ac97_mutex);
100
101 tmp = nuc900_checkready();
102 if (tmp)
103 dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
104
105 /* clear the R_WB bit and write register index */
106 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS1, reg);
107
108 /* write register value */
109 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS2, val);
110
111 /* set the valid frame bit and valid slots */
112 tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
113 tmp |= SLOT1_VALID | SLOT2_VALID | VALID_FRAME;
114 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp);
115
116 udelay(100);
117
118 /* polling the AC_W_FINISH */
119 while ((AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_W_FINISH)
120 && --timeout)
121 mdelay(1);
122
123 if (!timeout)
124 dev_err(nuc900_audio->dev, "AC97 write register time out !\n");
125
126 tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
127 tmp &= ~(SLOT1_VALID | SLOT2_VALID);
128 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp);
129
130 mutex_unlock(&ac97_mutex);
131
132}
133
134static void nuc900_ac97_warm_reset(struct snd_ac97 *ac97)
135{
136 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
137 unsigned long val;
138
139 mutex_lock(&ac97_mutex);
140
141 /* warm reset AC 97 */
142 val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON);
143 val |= AC_W_RES;
144 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACCON, val);
145
146 udelay(100);
147
148 val = nuc900_checkready();
149 if (val)
150 dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
151
152 mutex_unlock(&ac97_mutex);
153}
154
155static void nuc900_ac97_cold_reset(struct snd_ac97 *ac97)
156{
157 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
158 unsigned long val;
159
160 mutex_lock(&ac97_mutex);
161
162 /* reset Audio Controller */
163 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
164 val |= ACTL_RESET_BIT;
165 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
166
167 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
168 val &= (~ACTL_RESET_BIT);
169 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
170
171 /* reset AC-link interface */
172
173 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
174 val |= AC_RESET;
175 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
176
177 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
178 val &= ~AC_RESET;
179 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
180
181 /* cold reset AC 97 */
182 val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON);
183 val |= AC_C_RES;
184 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACCON, val);
185
186 val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON);
187 val &= (~AC_C_RES);
188 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACCON, val);
189
190 udelay(100);
191
192 mutex_unlock(&ac97_mutex);
193
194}
195
196/* AC97 controller operations */
197static struct snd_ac97_bus_ops nuc900_ac97_ops = {
198 .read = nuc900_ac97_read,
199 .write = nuc900_ac97_write,
200 .reset = nuc900_ac97_cold_reset,
201 .warm_reset = nuc900_ac97_warm_reset,
202};
203
204static int nuc900_ac97_trigger(struct snd_pcm_substream *substream,
205 int cmd, struct snd_soc_dai *dai)
206{
207 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
208 int ret;
209 unsigned long val, tmp;
210
211 ret = 0;
212
213 switch (cmd) {
214 case SNDRV_PCM_TRIGGER_START:
215 case SNDRV_PCM_TRIGGER_RESUME:
216 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
217 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
218 tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
219 tmp |= (SLOT3_VALID | SLOT4_VALID | VALID_FRAME);
220 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp);
221
222 tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_PSR);
223 tmp |= (P_DMA_END_IRQ | P_DMA_MIDDLE_IRQ);
224 AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, tmp);
225 val |= AC_PLAY;
226 } else {
227 tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_RSR);
228 tmp |= (R_DMA_END_IRQ | R_DMA_MIDDLE_IRQ);
229
230 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, tmp);
231 val |= AC_RECORD;
232 }
233
234 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
235
236 break;
237 case SNDRV_PCM_TRIGGER_STOP:
238 case SNDRV_PCM_TRIGGER_SUSPEND:
239 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
240 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
241 tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
242 tmp &= ~(SLOT3_VALID | SLOT4_VALID);
243 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp);
244
245 AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, RESET_PRSR);
246 val &= ~AC_PLAY;
247 } else {
248 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, RESET_PRSR);
249 val &= ~AC_RECORD;
250 }
251
252 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
253
254 break;
255 default:
256 ret = -EINVAL;
257 }
258
259 return ret;
260}
261
262static int nuc900_ac97_probe(struct snd_soc_dai *dai)
263{
264 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
265 unsigned long val;
266
267 mutex_lock(&ac97_mutex);
268
269 /* enable unit clock */
270 clk_enable(nuc900_audio->clk);
271
272 /* enable audio controller and AC-link interface */
273 val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON);
274 val |= (IIS_AC_PIN_SEL | ACLINK_EN);
275 AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val);
276
277 mutex_unlock(&ac97_mutex);
278
279 return 0;
280}
281
282static int nuc900_ac97_remove(struct snd_soc_dai *dai)
283{
284 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
285
286 clk_disable(nuc900_audio->clk);
287 return 0;
288}
289
290static const struct snd_soc_dai_ops nuc900_ac97_dai_ops = {
291 .trigger = nuc900_ac97_trigger,
292};
293
294static struct snd_soc_dai_driver nuc900_ac97_dai = {
295 .probe = nuc900_ac97_probe,
296 .remove = nuc900_ac97_remove,
297 .bus_control = true,
298 .playback = {
299 .rates = SNDRV_PCM_RATE_8000_48000,
300 .formats = SNDRV_PCM_FMTBIT_S16_LE,
301 .channels_min = 1,
302 .channels_max = 2,
303 },
304 .capture = {
305 .rates = SNDRV_PCM_RATE_8000_48000,
306 .formats = SNDRV_PCM_FMTBIT_S16_LE,
307 .channels_min = 1,
308 .channels_max = 2,
309 },
310 .ops = &nuc900_ac97_dai_ops,
311};
312
313static const struct snd_soc_component_driver nuc900_ac97_component = {
314 .name = "nuc900-ac97",
315};
316
317static int nuc900_ac97_drvprobe(struct platform_device *pdev)
318{
319 struct nuc900_audio *nuc900_audio;
320 int ret;
321
322 if (nuc900_ac97_data)
323 return -EBUSY;
324
325 nuc900_audio = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_audio),
326 GFP_KERNEL);
327 if (!nuc900_audio)
328 return -ENOMEM;
329
330 spin_lock_init(&nuc900_audio->lock);
331
332 nuc900_audio->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
333 nuc900_audio->mmio = devm_ioremap_resource(&pdev->dev,
334 nuc900_audio->res);
335 if (IS_ERR(nuc900_audio->mmio))
336 return PTR_ERR(nuc900_audio->mmio);
337
338 nuc900_audio->clk = devm_clk_get(&pdev->dev, NULL);
339 if (IS_ERR(nuc900_audio->clk)) {
340 ret = PTR_ERR(nuc900_audio->clk);
341 goto out;
342 }
343
344 ret = platform_get_irq(pdev, 0);
345 if (ret < 0)
346 goto out;
347 nuc900_audio->irq_num = ret;
348
349 nuc900_ac97_data = nuc900_audio;
350
351 ret = snd_soc_set_ac97_ops(&nuc900_ac97_ops);
352 if (ret)
353 goto out;
354
355 ret = devm_snd_soc_register_component(&pdev->dev, &nuc900_ac97_component,
356 &nuc900_ac97_dai, 1);
357 if (ret)
358 goto out;
359
360 /* enbale ac97 multifunction pin */
361 mfp_set_groupg(nuc900_audio->dev, NULL);
362
363 return 0;
364
365out:
366 snd_soc_set_ac97_ops(NULL);
367 return ret;
368}
369
370static int nuc900_ac97_drvremove(struct platform_device *pdev)
371{
372 nuc900_ac97_data = NULL;
373 snd_soc_set_ac97_ops(NULL);
374
375 return 0;
376}
377
378static struct platform_driver nuc900_ac97_driver = {
379 .driver = {
380 .name = "nuc900-ac97",
381 },
382 .probe = nuc900_ac97_drvprobe,
383 .remove = nuc900_ac97_drvremove,
384};
385
386module_platform_driver(nuc900_ac97_driver);
387
388MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
389MODULE_DESCRIPTION("NUC900 AC97 SoC driver!");
390MODULE_LICENSE("GPL");
391MODULE_ALIAS("platform:nuc900-ac97");
diff --git a/sound/soc/nuc900/nuc900-audio.c b/sound/soc/nuc900/nuc900-audio.c
deleted file mode 100644
index 19146690d514..000000000000
--- a/sound/soc/nuc900/nuc900-audio.c
+++ /dev/null
@@ -1,73 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2010 Nuvoton technology corporation.
4 *
5 * Wan ZongShun <mcuos.com@gmail.com>
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/timer.h>
11#include <linux/interrupt.h>
12#include <linux/platform_device.h>
13
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/soc.h>
17
18#include "nuc900-audio.h"
19
20SND_SOC_DAILINK_DEFS(ac97,
21 DAILINK_COMP_ARRAY(COMP_CPU("nuc900-ac97")),
22 DAILINK_COMP_ARRAY(COMP_CODEC("ac97-codec", "ac97-hifi")),
23 DAILINK_COMP_ARRAY(COMP_PLATFORM("nuc900-pcm-audio")));
24
25static struct snd_soc_dai_link nuc900evb_ac97_dai = {
26 .name = "AC97",
27 .stream_name = "AC97 HiFi",
28 SND_SOC_DAILINK_REG(ac97),
29};
30
31static struct snd_soc_card nuc900evb_audio_machine = {
32 .name = "NUC900EVB_AC97",
33 .owner = THIS_MODULE,
34 .dai_link = &nuc900evb_ac97_dai,
35 .num_links = 1,
36};
37
38static struct platform_device *nuc900evb_asoc_dev;
39
40static int __init nuc900evb_audio_init(void)
41{
42 int ret;
43
44 ret = -ENOMEM;
45 nuc900evb_asoc_dev = platform_device_alloc("soc-audio", -1);
46 if (!nuc900evb_asoc_dev)
47 goto out;
48
49 /* nuc900 board audio device */
50 platform_set_drvdata(nuc900evb_asoc_dev, &nuc900evb_audio_machine);
51
52 ret = platform_device_add(nuc900evb_asoc_dev);
53
54 if (ret) {
55 platform_device_put(nuc900evb_asoc_dev);
56 nuc900evb_asoc_dev = NULL;
57 }
58
59out:
60 return ret;
61}
62
63static void __exit nuc900evb_audio_exit(void)
64{
65 platform_device_unregister(nuc900evb_asoc_dev);
66}
67
68module_init(nuc900evb_audio_init);
69module_exit(nuc900evb_audio_exit);
70
71MODULE_LICENSE("GPL");
72MODULE_DESCRIPTION("NUC900 Series ASoC audio support");
73MODULE_AUTHOR("Wan ZongShun");
diff --git a/sound/soc/nuc900/nuc900-audio.h b/sound/soc/nuc900/nuc900-audio.h
deleted file mode 100644
index 90ffa7bbce01..000000000000
--- a/sound/soc/nuc900/nuc900-audio.h
+++ /dev/null
@@ -1,108 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (c) 2010 Nuvoton technology corporation.
4 *
5 * Wan ZongShun <mcuos.com@gmail.com>
6 */
7
8#ifndef _NUC900_AUDIO_H
9#define _NUC900_AUDIO_H
10
11#include <linux/io.h>
12
13/* Audio Control Registers */
14#define ACTL_CON 0x00
15#define ACTL_RESET 0x04
16#define ACTL_RDSTB 0x08
17#define ACTL_RDST_LENGTH 0x0C
18#define ACTL_RDSTC 0x10
19#define ACTL_RSR 0x14
20#define ACTL_PDSTB 0x18
21#define ACTL_PDST_LENGTH 0x1C
22#define ACTL_PDSTC 0x20
23#define ACTL_PSR 0x24
24#define ACTL_IISCON 0x28
25#define ACTL_ACCON 0x2C
26#define ACTL_ACOS0 0x30
27#define ACTL_ACOS1 0x34
28#define ACTL_ACOS2 0x38
29#define ACTL_ACIS0 0x3C
30#define ACTL_ACIS1 0x40
31#define ACTL_ACIS2 0x44
32#define ACTL_COUNTER 0x48
33
34/* bit definition of REG_ACTL_CON register */
35#define R_DMA_IRQ 0x1000
36#define T_DMA_IRQ 0x0800
37#define IIS_AC_PIN_SEL 0x0100
38#define FIFO_TH 0x0080
39#define ADC_EN 0x0010
40#define M80_EN 0x0008
41#define ACLINK_EN 0x0004
42#define IIS_EN 0x0002
43
44/* bit definition of REG_ACTL_RESET register */
45#define W5691_PLAY 0x20000
46#define ACTL_RESET_BIT 0x10000
47#define RECORD_RIGHT_CHNNEL 0x08000
48#define RECORD_LEFT_CHNNEL 0x04000
49#define PLAY_RIGHT_CHNNEL 0x02000
50#define PLAY_LEFT_CHNNEL 0x01000
51#define DAC_PLAY 0x00800
52#define ADC_RECORD 0x00400
53#define M80_PLAY 0x00200
54#define AC_RECORD 0x00100
55#define AC_PLAY 0x00080
56#define IIS_RECORD 0x00040
57#define IIS_PLAY 0x00020
58#define DAC_RESET 0x00010
59#define ADC_RESET 0x00008
60#define M80_RESET 0x00004
61#define AC_RESET 0x00002
62#define IIS_RESET 0x00001
63
64/* bit definition of REG_ACTL_ACCON register */
65#define AC_BCLK_PU_EN 0x20
66#define AC_R_FINISH 0x10
67#define AC_W_FINISH 0x08
68#define AC_W_RES 0x04
69#define AC_C_RES 0x02
70
71/* bit definition of ACTL_RSR register */
72#define R_FIFO_EMPTY 0x04
73#define R_DMA_END_IRQ 0x02
74#define R_DMA_MIDDLE_IRQ 0x01
75
76/* bit definition of ACTL_PSR register */
77#define P_FIFO_EMPTY 0x04
78#define P_DMA_END_IRQ 0x02
79#define P_DMA_MIDDLE_IRQ 0x01
80
81/* bit definition of ACTL_ACOS0 register */
82#define SLOT1_VALID 0x01
83#define SLOT2_VALID 0x02
84#define SLOT3_VALID 0x04
85#define SLOT4_VALID 0x08
86#define VALID_FRAME 0x10
87
88/* bit definition of ACTL_ACOS1 register */
89#define R_WB 0x80
90
91#define CODEC_READY 0x10
92#define RESET_PRSR 0x00
93#define AUDIO_WRITE(addr, val) __raw_writel(val, addr)
94#define AUDIO_READ(addr) __raw_readl(addr)
95
96struct nuc900_audio {
97 void __iomem *mmio;
98 spinlock_t lock;
99 unsigned long irq_num;
100 struct resource *res;
101 struct clk *clk;
102 struct device *dev;
103
104};
105
106extern struct nuc900_audio *nuc900_ac97_data;
107
108#endif /*end _NUC900_AUDIO_H */
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
deleted file mode 100644
index 4442a26e9502..000000000000
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ /dev/null
@@ -1,321 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2010 Nuvoton technology corporation.
4 *
5 * Wan ZongShun <mcuos.com@gmail.com>
6 */
7
8#include <linux/module.h>
9#include <linux/init.h>
10#include <linux/io.h>
11#include <linux/platform_device.h>
12#include <linux/slab.h>
13#include <linux/dma-mapping.h>
14
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h>
19
20#include <mach/hardware.h>
21
22#include "nuc900-audio.h"
23
24static const struct snd_pcm_hardware nuc900_pcm_hardware = {
25 .info = SNDRV_PCM_INFO_INTERLEAVED |
26 SNDRV_PCM_INFO_BLOCK_TRANSFER |
27 SNDRV_PCM_INFO_MMAP |
28 SNDRV_PCM_INFO_MMAP_VALID |
29 SNDRV_PCM_INFO_PAUSE |
30 SNDRV_PCM_INFO_RESUME,
31 .buffer_bytes_max = 4*1024,
32 .period_bytes_min = 1*1024,
33 .period_bytes_max = 4*1024,
34 .periods_min = 1,
35 .periods_max = 1024,
36};
37
38static int nuc900_dma_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
42}
43
44static void nuc900_update_dma_register(struct snd_pcm_substream *substream)
45{
46 struct snd_pcm_runtime *runtime = substream->runtime;
47 struct nuc900_audio *nuc900_audio = runtime->private_data;
48 void __iomem *mmio_addr, *mmio_len;
49
50 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
51 mmio_addr = nuc900_audio->mmio + ACTL_PDSTB;
52 mmio_len = nuc900_audio->mmio + ACTL_PDST_LENGTH;
53 } else {
54 mmio_addr = nuc900_audio->mmio + ACTL_RDSTB;
55 mmio_len = nuc900_audio->mmio + ACTL_RDST_LENGTH;
56 }
57
58 AUDIO_WRITE(mmio_addr, runtime->dma_addr);
59 AUDIO_WRITE(mmio_len, runtime->dma_bytes);
60}
61
62static void nuc900_dma_start(struct snd_pcm_substream *substream)
63{
64 struct snd_pcm_runtime *runtime = substream->runtime;
65 struct nuc900_audio *nuc900_audio = runtime->private_data;
66 unsigned long val;
67
68 val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON);
69 val |= (T_DMA_IRQ | R_DMA_IRQ);
70 AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val);
71}
72
73static void nuc900_dma_stop(struct snd_pcm_substream *substream)
74{
75 struct snd_pcm_runtime *runtime = substream->runtime;
76 struct nuc900_audio *nuc900_audio = runtime->private_data;
77 unsigned long val;
78
79 val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON);
80 val &= ~(T_DMA_IRQ | R_DMA_IRQ);
81 AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val);
82}
83
84static irqreturn_t nuc900_dma_interrupt(int irq, void *dev_id)
85{
86 struct snd_pcm_substream *substream = dev_id;
87 struct nuc900_audio *nuc900_audio = substream->runtime->private_data;
88 unsigned long val;
89
90 spin_lock(&nuc900_audio->lock);
91
92 val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON);
93
94 if (val & R_DMA_IRQ) {
95 AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val | R_DMA_IRQ);
96
97 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RSR);
98
99 if (val & R_DMA_MIDDLE_IRQ) {
100 val |= R_DMA_MIDDLE_IRQ;
101 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, val);
102 }
103
104 if (val & R_DMA_END_IRQ) {
105 val |= R_DMA_END_IRQ;
106 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, val);
107 }
108 } else if (val & T_DMA_IRQ) {
109 AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val | T_DMA_IRQ);
110
111 val = AUDIO_READ(nuc900_audio->mmio + ACTL_PSR);
112
113 if (val & P_DMA_MIDDLE_IRQ) {
114 val |= P_DMA_MIDDLE_IRQ;
115 AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, val);
116 }
117
118 if (val & P_DMA_END_IRQ) {
119 val |= P_DMA_END_IRQ;
120 AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, val);
121 }
122 } else {
123 dev_err(nuc900_audio->dev, "Wrong DMA interrupt status!\n");
124 spin_unlock(&nuc900_audio->lock);
125 return IRQ_HANDLED;
126 }
127
128 spin_unlock(&nuc900_audio->lock);
129
130 snd_pcm_period_elapsed(substream);
131
132 return IRQ_HANDLED;
133}
134
135static int nuc900_dma_hw_free(struct snd_pcm_substream *substream)
136{
137 snd_pcm_lib_free_pages(substream);
138 return 0;
139}
140
141static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
142{
143 struct snd_pcm_runtime *runtime = substream->runtime;
144 struct nuc900_audio *nuc900_audio = runtime->private_data;
145 unsigned long flags, val;
146 int ret = 0;
147
148 spin_lock_irqsave(&nuc900_audio->lock, flags);
149
150 nuc900_update_dma_register(substream);
151
152 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
153
154 switch (runtime->channels) {
155 case 1:
156 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
157 val &= ~(PLAY_LEFT_CHNNEL | PLAY_RIGHT_CHNNEL);
158 val |= PLAY_RIGHT_CHNNEL;
159 } else {
160 val &= ~(RECORD_LEFT_CHNNEL | RECORD_RIGHT_CHNNEL);
161 val |= RECORD_RIGHT_CHNNEL;
162 }
163 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
164 break;
165 case 2:
166 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
167 val |= (PLAY_LEFT_CHNNEL | PLAY_RIGHT_CHNNEL);
168 else
169 val |= (RECORD_LEFT_CHNNEL | RECORD_RIGHT_CHNNEL);
170 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
171 break;
172 default:
173 ret = -EINVAL;
174 }
175 spin_unlock_irqrestore(&nuc900_audio->lock, flags);
176 return ret;
177}
178
179static int nuc900_dma_trigger(struct snd_pcm_substream *substream, int cmd)
180{
181 int ret = 0;
182
183 switch (cmd) {
184 case SNDRV_PCM_TRIGGER_START:
185 case SNDRV_PCM_TRIGGER_RESUME:
186 nuc900_dma_start(substream);
187 break;
188
189 case SNDRV_PCM_TRIGGER_STOP:
190 case SNDRV_PCM_TRIGGER_SUSPEND:
191 nuc900_dma_stop(substream);
192 break;
193
194 default:
195 ret = -EINVAL;
196 break;
197 }
198
199 return ret;
200}
201
202static int nuc900_dma_getposition(struct snd_pcm_substream *substream,
203 dma_addr_t *src, dma_addr_t *dst)
204{
205 struct snd_pcm_runtime *runtime = substream->runtime;
206 struct nuc900_audio *nuc900_audio = runtime->private_data;
207
208 if (src != NULL)
209 *src = AUDIO_READ(nuc900_audio->mmio + ACTL_PDSTC);
210
211 if (dst != NULL)
212 *dst = AUDIO_READ(nuc900_audio->mmio + ACTL_RDSTC);
213
214 return 0;
215}
216
217static snd_pcm_uframes_t nuc900_dma_pointer(struct snd_pcm_substream *substream)
218{
219 struct snd_pcm_runtime *runtime = substream->runtime;
220 dma_addr_t src, dst;
221 unsigned long res;
222
223 nuc900_dma_getposition(substream, &src, &dst);
224
225 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
226 res = dst - runtime->dma_addr;
227 else
228 res = src - runtime->dma_addr;
229
230 return bytes_to_frames(substream->runtime, res);
231}
232
233static int nuc900_dma_open(struct snd_pcm_substream *substream)
234{
235 struct snd_pcm_runtime *runtime = substream->runtime;
236 struct nuc900_audio *nuc900_audio;
237
238 snd_soc_set_runtime_hwparams(substream, &nuc900_pcm_hardware);
239
240 nuc900_audio = nuc900_ac97_data;
241
242 if (request_irq(nuc900_audio->irq_num, nuc900_dma_interrupt,
243 0, "nuc900-dma", substream))
244 return -EBUSY;
245
246 runtime->private_data = nuc900_audio;
247
248 return 0;
249}
250
251static int nuc900_dma_close(struct snd_pcm_substream *substream)
252{
253 struct snd_pcm_runtime *runtime = substream->runtime;
254 struct nuc900_audio *nuc900_audio = runtime->private_data;
255
256 free_irq(nuc900_audio->irq_num, substream);
257
258 return 0;
259}
260
261static int nuc900_dma_mmap(struct snd_pcm_substream *substream,
262 struct vm_area_struct *vma)
263{
264 struct snd_pcm_runtime *runtime = substream->runtime;
265
266 return dma_mmap_wc(substream->pcm->card->dev, vma, runtime->dma_area,
267 runtime->dma_addr, runtime->dma_bytes);
268}
269
270static const struct snd_pcm_ops nuc900_dma_ops = {
271 .open = nuc900_dma_open,
272 .close = nuc900_dma_close,
273 .ioctl = snd_pcm_lib_ioctl,
274 .hw_params = nuc900_dma_hw_params,
275 .hw_free = nuc900_dma_hw_free,
276 .prepare = nuc900_dma_prepare,
277 .trigger = nuc900_dma_trigger,
278 .pointer = nuc900_dma_pointer,
279 .mmap = nuc900_dma_mmap,
280};
281
282static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd)
283{
284 struct snd_card *card = rtd->card->snd_card;
285 struct snd_pcm *pcm = rtd->pcm;
286 int ret;
287
288 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
289 if (ret)
290 return ret;
291
292 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
293 card->dev, 4 * 1024, (4 * 1024) - 1);
294
295 return 0;
296}
297
298static const struct snd_soc_component_driver nuc900_soc_component = {
299 .ops = &nuc900_dma_ops,
300 .pcm_new = nuc900_dma_new,
301};
302
303static int nuc900_soc_platform_probe(struct platform_device *pdev)
304{
305 return devm_snd_soc_register_component(&pdev->dev, &nuc900_soc_component,
306 NULL, 0);
307}
308
309static struct platform_driver nuc900_pcm_driver = {
310 .driver = {
311 .name = "nuc900-pcm-audio",
312 },
313
314 .probe = nuc900_soc_platform_probe,
315};
316
317module_platform_driver(nuc900_pcm_driver);
318
319MODULE_AUTHOR("Wan ZongShun, <mcuos.com@gmail.com>");
320MODULE_DESCRIPTION("nuc900 Audio DMA module");
321MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
index 72f4364b2d20..e3e5425b5c62 100644
--- a/sound/soc/pxa/mmp-sspa.c
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -399,7 +399,6 @@ static const struct snd_soc_component_driver mmp_sspa_component = {
399static int asoc_mmp_sspa_probe(struct platform_device *pdev) 399static int asoc_mmp_sspa_probe(struct platform_device *pdev)
400{ 400{
401 struct sspa_priv *priv; 401 struct sspa_priv *priv;
402 struct resource *res;
403 402
404 priv = devm_kzalloc(&pdev->dev, 403 priv = devm_kzalloc(&pdev->dev,
405 sizeof(struct sspa_priv), GFP_KERNEL); 404 sizeof(struct sspa_priv), GFP_KERNEL);
@@ -417,8 +416,7 @@ static int asoc_mmp_sspa_probe(struct platform_device *pdev)
417 if (priv->dma_params == NULL) 416 if (priv->dma_params == NULL)
418 return -ENOMEM; 417 return -ENOMEM;
419 418
420 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 419 priv->sspa->mmio_base = devm_platform_ioremap_resource(pdev, 0);
421 priv->sspa->mmio_base = devm_ioremap_resource(&pdev->dev, res);
422 if (IS_ERR(priv->sspa->mmio_base)) 420 if (IS_ERR(priv->sspa->mmio_base))
423 return PTR_ERR(priv->sspa->mmio_base); 421 return PTR_ERR(priv->sspa->mmio_base);
424 422
diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c
index 2c7348ddbbb3..6c20bdd850f3 100644
--- a/sound/soc/qcom/common.c
+++ b/sound/soc/qcom/common.c
@@ -53,12 +53,18 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
53 link->num_cpus = 1; 53 link->num_cpus = 1;
54 link->num_platforms = 1; 54 link->num_platforms = 1;
55 55
56 ret = of_property_read_string(np, "link-name", &link->name);
57 if (ret) {
58 dev_err(card->dev, "error getting codec dai_link name\n");
59 goto err;
60 }
61
56 cpu = of_get_child_by_name(np, "cpu"); 62 cpu = of_get_child_by_name(np, "cpu");
57 platform = of_get_child_by_name(np, "platform"); 63 platform = of_get_child_by_name(np, "platform");
58 codec = of_get_child_by_name(np, "codec"); 64 codec = of_get_child_by_name(np, "codec");
59 65
60 if (!cpu) { 66 if (!cpu) {
61 dev_err(dev, "Can't find cpu DT node\n"); 67 dev_err(dev, "%s: Can't find cpu DT node\n", link->name);
62 ret = -EINVAL; 68 ret = -EINVAL;
63 goto err; 69 goto err;
64 } 70 }
@@ -66,7 +72,7 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
66 ret = of_parse_phandle_with_args(cpu, "sound-dai", 72 ret = of_parse_phandle_with_args(cpu, "sound-dai",
67 "#sound-dai-cells", 0, &args); 73 "#sound-dai-cells", 0, &args);
68 if (ret) { 74 if (ret) {
69 dev_err(card->dev, "error getting cpu phandle\n"); 75 dev_err(card->dev, "%s: error getting cpu phandle\n", link->name);
70 goto err; 76 goto err;
71 } 77 }
72 link->cpus->of_node = args.np; 78 link->cpus->of_node = args.np;
@@ -74,7 +80,7 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
74 80
75 ret = snd_soc_of_get_dai_name(cpu, &link->cpus->dai_name); 81 ret = snd_soc_of_get_dai_name(cpu, &link->cpus->dai_name);
76 if (ret) { 82 if (ret) {
77 dev_err(card->dev, "error getting cpu dai name\n"); 83 dev_err(card->dev, "%s: error getting cpu dai name\n", link->name);
78 goto err; 84 goto err;
79 } 85 }
80 86
@@ -83,14 +89,14 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
83 "sound-dai", 89 "sound-dai",
84 0); 90 0);
85 if (!link->platforms->of_node) { 91 if (!link->platforms->of_node) {
86 dev_err(card->dev, "platform dai not found\n"); 92 dev_err(card->dev, "%s: platform dai not found\n", link->name);
87 ret = -EINVAL; 93 ret = -EINVAL;
88 goto err; 94 goto err;
89 } 95 }
90 96
91 ret = snd_soc_of_get_dai_link_codecs(dev, codec, link); 97 ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
92 if (ret < 0) { 98 if (ret < 0) {
93 dev_err(card->dev, "codec dai not found\n"); 99 dev_err(card->dev, "%s: codec dai not found\n", link->name);
94 goto err; 100 goto err;
95 } 101 }
96 link->no_pcm = 1; 102 link->no_pcm = 1;
@@ -110,12 +116,6 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
110 } 116 }
111 117
112 link->ignore_suspend = 1; 118 link->ignore_suspend = 1;
113 ret = of_property_read_string(np, "link-name", &link->name);
114 if (ret) {
115 dev_err(card->dev, "error getting codec dai_link name\n");
116 goto err;
117 }
118
119 link->nonatomic = 1; 119 link->nonatomic = 1;
120 link->dpcm_playback = 1; 120 link->dpcm_playback = 1;
121 link->dpcm_capture = 1; 121 link->dpcm_capture = 1;
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
index cf7a299f4547..4c745baa39f7 100644
--- a/sound/soc/qcom/lpass-platform.c
+++ b/sound/soc/qcom/lpass-platform.c
@@ -564,11 +564,8 @@ int asoc_qcom_lpass_platform_register(struct platform_device *pdev)
564 int ret; 564 int ret;
565 565
566 drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif"); 566 drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif");
567 if (drvdata->lpaif_irq < 0) { 567 if (drvdata->lpaif_irq < 0)
568 dev_err(&pdev->dev, "error getting irq handle: %d\n",
569 drvdata->lpaif_irq);
570 return -ENODEV; 568 return -ENODEV;
571 }
572 569
573 /* ensure audio hardware is disabled */ 570 /* ensure audio hardware is disabled */
574 ret = regmap_write(drvdata->lpaif_map, 571 ret = regmap_write(drvdata->lpaif_map,
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index 88ebaf6e1880..af2d5a6124c8 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -419,6 +419,9 @@ static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
419 struct rk_i2s_dev *i2s = to_info(cpu_dai); 419 struct rk_i2s_dev *i2s = to_info(cpu_dai);
420 int ret; 420 int ret;
421 421
422 if (freq == 0)
423 return 0;
424
422 ret = clk_set_rate(i2s->mclk, freq); 425 ret = clk_set_rate(i2s->mclk, freq);
423 if (ret) 426 if (ret)
424 dev_err(i2s->dev, "Fail to set mclk %d\n", ret); 427 dev_err(i2s->dev, "Fail to set mclk %d\n", ret);
diff --git a/sound/soc/rockchip/rockchip_max98090.c b/sound/soc/rockchip/rockchip_max98090.c
index d54f672d38d8..0097df1fae66 100644
--- a/sound/soc/rockchip/rockchip_max98090.c
+++ b/sound/soc/rockchip/rockchip_max98090.c
@@ -45,7 +45,6 @@ static const struct snd_soc_dapm_widget rk_dapm_widgets[] = {
45 45
46static const struct snd_soc_dapm_route rk_audio_map[] = { 46static const struct snd_soc_dapm_route rk_audio_map[] = {
47 {"IN34", NULL, "Headset Mic"}, 47 {"IN34", NULL, "Headset Mic"},
48 {"IN34", NULL, "MICBIAS"},
49 {"Headset Mic", NULL, "MICBIAS"}, 48 {"Headset Mic", NULL, "MICBIAS"},
50 {"DMICL", NULL, "Int Mic"}, 49 {"DMICL", NULL, "Int Mic"},
51 {"Headphone", NULL, "HPL"}, 50 {"Headphone", NULL, "HPL"},
@@ -172,7 +171,7 @@ static struct snd_soc_dai_link rk_dailink = {
172static int rk_98090_headset_init(struct snd_soc_component *component); 171static int rk_98090_headset_init(struct snd_soc_component *component);
173 172
174static struct snd_soc_aux_dev rk_98090_headset_dev = { 173static struct snd_soc_aux_dev rk_98090_headset_dev = {
175 .name = "Headset Chip", 174 .dlc = COMP_EMPTY(),
176 .init = rk_98090_headset_init, 175 .init = rk_98090_headset_init,
177}; 176};
178 177
@@ -238,9 +237,9 @@ static int snd_rk_mc_probe(struct platform_device *pdev)
238 237
239 rk_dailink.platforms->of_node = rk_dailink.cpus->of_node; 238 rk_dailink.platforms->of_node = rk_dailink.cpus->of_node;
240 239
241 rk_98090_headset_dev.codec_of_node = of_parse_phandle(np, 240 rk_98090_headset_dev.dlc.of_node = of_parse_phandle(np,
242 "rockchip,headset-codec", 0); 241 "rockchip,headset-codec", 0);
243 if (!rk_98090_headset_dev.codec_of_node) { 242 if (!rk_98090_headset_dev.dlc.of_node) {
244 dev_err(&pdev->dev, 243 dev_err(&pdev->dev,
245 "Property 'rockchip,headset-codec' missing/invalid\n"); 244 "Property 'rockchip,headset-codec' missing/invalid\n");
246 return -EINVAL; 245 return -EINVAL;
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index 396776ffd670..38f536bafa09 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -297,8 +297,7 @@ static struct snd_soc_dai_link neo1973_dai[] = {
297 297
298static struct snd_soc_aux_dev neo1973_aux_devs[] = { 298static struct snd_soc_aux_dev neo1973_aux_devs[] = {
299 { 299 {
300 .name = "dfbmcs320", 300 .dlc = COMP_AUX("dfbmcs320.0"),
301 .codec_name = "dfbmcs320.0",
302 }, 301 },
303}; 302};
304 303
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index 51e4c976c8be..9e58cbed942a 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -240,8 +240,7 @@ static int speyside_wm9081_init(struct snd_soc_component *component)
240 240
241static struct snd_soc_aux_dev speyside_aux_dev[] = { 241static struct snd_soc_aux_dev speyside_aux_dev[] = {
242 { 242 {
243 .name = "wm9081", 243 .dlc = COMP_AUX("wm9081.1-006c"),
244 .codec_name = "wm9081.1-006c",
245 .init = speyside_wm9081_init, 244 .init = speyside_wm9081_init,
246 }, 245 },
247}; 246};
diff --git a/sound/soc/samsung/tm2_wm5110.c b/sound/soc/samsung/tm2_wm5110.c
index c091033d17ad..bb9910d4cbe2 100644
--- a/sound/soc/samsung/tm2_wm5110.c
+++ b/sound/soc/samsung/tm2_wm5110.c
@@ -307,7 +307,6 @@ static struct snd_soc_aux_dev tm2_speaker_amp_dev;
307static int tm2_late_probe(struct snd_soc_card *card) 307static int tm2_late_probe(struct snd_soc_card *card)
308{ 308{
309 struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card); 309 struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card);
310 struct snd_soc_dai_link_component dlc = { 0 };
311 unsigned int ch_map[] = { 0, 1 }; 310 unsigned int ch_map[] = { 0, 1 };
312 struct snd_soc_dai *amp_pdm_dai; 311 struct snd_soc_dai *amp_pdm_dai;
313 struct snd_soc_pcm_runtime *rtd; 312 struct snd_soc_pcm_runtime *rtd;
@@ -334,8 +333,7 @@ static int tm2_late_probe(struct snd_soc_card *card)
334 return ret; 333 return ret;
335 } 334 }
336 335
337 dlc.of_node = tm2_speaker_amp_dev.codec_of_node; 336 amp_pdm_dai = snd_soc_find_dai(&tm2_speaker_amp_dev.dlc);
338 amp_pdm_dai = snd_soc_find_dai(&dlc);
339 if (!amp_pdm_dai) 337 if (!amp_pdm_dai)
340 return -ENODEV; 338 return -ENODEV;
341 339
@@ -532,9 +530,9 @@ static int tm2_probe(struct platform_device *pdev)
532 return ret; 530 return ret;
533 } 531 }
534 532
535 card->aux_dev[0].codec_of_node = of_parse_phandle(dev->of_node, 533 card->aux_dev[0].dlc.of_node = of_parse_phandle(dev->of_node,
536 "audio-amplifier", 0); 534 "audio-amplifier", 0);
537 if (!card->aux_dev[0].codec_of_node) { 535 if (!card->aux_dev[0].dlc.of_node) {
538 dev_err(dev, "audio-amplifier property invalid or missing\n"); 536 dev_err(dev, "audio-amplifier property invalid or missing\n");
539 return -EINVAL; 537 return -EINVAL;
540 } 538 }
@@ -623,7 +621,7 @@ dai_node_put:
623 of_node_put(cpu_dai_node[i]); 621 of_node_put(cpu_dai_node[i]);
624 } 622 }
625 623
626 of_node_put(card->aux_dev[0].codec_of_node); 624 of_node_put(card->aux_dev[0].dlc.of_node);
627 625
628 return ret; 626 return ret;
629} 627}
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 56e8dae9a15c..bda5b958d0dc 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -1421,6 +1421,20 @@ static int rsnd_hw_params(struct snd_pcm_substream *substream,
1421 params_buffer_bytes(hw_params)); 1421 params_buffer_bytes(hw_params));
1422} 1422}
1423 1423
1424static int rsnd_hw_free(struct snd_pcm_substream *substream)
1425{
1426 struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
1427 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
1428 struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
1429 int ret;
1430
1431 ret = rsnd_dai_call(hw_free, io, substream);
1432 if (ret)
1433 return ret;
1434
1435 return snd_pcm_lib_free_pages(substream);
1436}
1437
1424static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream) 1438static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream)
1425{ 1439{
1426 struct snd_soc_dai *dai = rsnd_substream_to_dai(substream); 1440 struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
@@ -1436,7 +1450,7 @@ static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream)
1436static const struct snd_pcm_ops rsnd_pcm_ops = { 1450static const struct snd_pcm_ops rsnd_pcm_ops = {
1437 .ioctl = snd_pcm_lib_ioctl, 1451 .ioctl = snd_pcm_lib_ioctl,
1438 .hw_params = rsnd_hw_params, 1452 .hw_params = rsnd_hw_params,
1439 .hw_free = snd_pcm_lib_free_pages, 1453 .hw_free = rsnd_hw_free,
1440 .pointer = rsnd_pointer, 1454 .pointer = rsnd_pointer,
1441}; 1455};
1442 1456
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 7727add3eb1a..ea6cbaa9743e 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -327,6 +327,9 @@ struct rsnd_mod_ops {
327 int (*cleanup)(struct rsnd_mod *mod, 327 int (*cleanup)(struct rsnd_mod *mod,
328 struct rsnd_dai_stream *io, 328 struct rsnd_dai_stream *io,
329 struct rsnd_priv *priv); 329 struct rsnd_priv *priv);
330 int (*hw_free)(struct rsnd_mod *mod,
331 struct rsnd_dai_stream *io,
332 struct snd_pcm_substream *substream);
330 u32 *(*get_status)(struct rsnd_mod *mod, 333 u32 *(*get_status)(struct rsnd_mod *mod,
331 struct rsnd_dai_stream *io, 334 struct rsnd_dai_stream *io,
332 enum rsnd_mod_type type); 335 enum rsnd_mod_type type);
@@ -351,12 +354,12 @@ struct rsnd_mod {
351 * 354 *
352 * B 0: init 1: quit 355 * B 0: init 1: quit
353 * C 0: start 1: stop 356 * C 0: start 1: stop
357 * D 0: hw_params 1: hw_free
354 * 358 *
355 * H is always called (see __rsnd_mod_call) 359 * H is always called (see __rsnd_mod_call)
356 * H 0: probe 1: remove 360 * H 0: probe 1: remove
357 * H 0: pcm_new 361 * H 0: pcm_new
358 * H 0: fallback 362 * H 0: fallback
359 * H 0: hw_params
360 * H 0: pointer 363 * H 0: pointer
361 * H 0: prepare 364 * H 0: prepare
362 * H 0: cleanup 365 * H 0: cleanup
@@ -365,12 +368,13 @@ struct rsnd_mod {
365#define __rsnd_mod_shift_quit 4 368#define __rsnd_mod_shift_quit 4
366#define __rsnd_mod_shift_start 8 369#define __rsnd_mod_shift_start 8
367#define __rsnd_mod_shift_stop 8 370#define __rsnd_mod_shift_stop 8
371#define __rsnd_mod_shift_hw_params 12
372#define __rsnd_mod_shift_hw_free 12
368#define __rsnd_mod_shift_probe 28 /* always called */ 373#define __rsnd_mod_shift_probe 28 /* always called */
369#define __rsnd_mod_shift_remove 28 /* always called */ 374#define __rsnd_mod_shift_remove 28 /* always called */
370#define __rsnd_mod_shift_irq 28 /* always called */ 375#define __rsnd_mod_shift_irq 28 /* always called */
371#define __rsnd_mod_shift_pcm_new 28 /* always called */ 376#define __rsnd_mod_shift_pcm_new 28 /* always called */
372#define __rsnd_mod_shift_fallback 28 /* always called */ 377#define __rsnd_mod_shift_fallback 28 /* always called */
373#define __rsnd_mod_shift_hw_params 28 /* always called */
374#define __rsnd_mod_shift_pointer 28 /* always called */ 378#define __rsnd_mod_shift_pointer 28 /* always called */
375#define __rsnd_mod_shift_prepare 28 /* always called */ 379#define __rsnd_mod_shift_prepare 28 /* always called */
376#define __rsnd_mod_shift_cleanup 28 /* always called */ 380#define __rsnd_mod_shift_cleanup 28 /* always called */
@@ -383,10 +387,11 @@ struct rsnd_mod {
383#define __rsnd_mod_add_quit -1 387#define __rsnd_mod_add_quit -1
384#define __rsnd_mod_add_start 1 388#define __rsnd_mod_add_start 1
385#define __rsnd_mod_add_stop -1 389#define __rsnd_mod_add_stop -1
390#define __rsnd_mod_add_hw_params 1
391#define __rsnd_mod_add_hw_free -1
386#define __rsnd_mod_add_irq 0 392#define __rsnd_mod_add_irq 0
387#define __rsnd_mod_add_pcm_new 0 393#define __rsnd_mod_add_pcm_new 0
388#define __rsnd_mod_add_fallback 0 394#define __rsnd_mod_add_fallback 0
389#define __rsnd_mod_add_hw_params 0
390#define __rsnd_mod_add_pointer 0 395#define __rsnd_mod_add_pointer 0
391 396
392#define __rsnd_mod_call_probe 0 397#define __rsnd_mod_call_probe 0
@@ -402,6 +407,7 @@ struct rsnd_mod {
402#define __rsnd_mod_call_fallback 0 407#define __rsnd_mod_call_fallback 0
403#define __rsnd_mod_call_hw_params 0 408#define __rsnd_mod_call_hw_params 0
404#define __rsnd_mod_call_pointer 0 409#define __rsnd_mod_call_pointer 0
410#define __rsnd_mod_call_hw_free 1
405 411
406#define rsnd_mod_to_priv(mod) ((mod)->priv) 412#define rsnd_mod_to_priv(mod) ((mod)->priv)
407#define rsnd_mod_power_on(mod) clk_enable((mod)->clk) 413#define rsnd_mod_power_on(mod) clk_enable((mod)->clk)
diff --git a/sound/soc/sirf/sirf-usp.c b/sound/soc/sirf/sirf-usp.c
index 8bab119c753a..2af0c6f14ee6 100644
--- a/sound/soc/sirf/sirf-usp.c
+++ b/sound/soc/sirf/sirf-usp.c
@@ -359,7 +359,6 @@ static int sirf_usp_pcm_probe(struct platform_device *pdev)
359 int ret; 359 int ret;
360 struct sirf_usp *usp; 360 struct sirf_usp *usp;
361 void __iomem *base; 361 void __iomem *base;
362 struct resource *mem_res;
363 362
364 usp = devm_kzalloc(&pdev->dev, sizeof(struct sirf_usp), 363 usp = devm_kzalloc(&pdev->dev, sizeof(struct sirf_usp),
365 GFP_KERNEL); 364 GFP_KERNEL);
@@ -368,8 +367,7 @@ static int sirf_usp_pcm_probe(struct platform_device *pdev)
368 367
369 platform_set_drvdata(pdev, usp); 368 platform_set_drvdata(pdev, usp);
370 369
371 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 370 base = devm_platform_ioremap_resource(pdev, 0);
372 base = devm_ioremap_resource(&pdev->dev, mem_res);
373 if (IS_ERR(base)) 371 if (IS_ERR(base))
374 return PTR_ERR(base); 372 return PTR_ERR(base);
375 usp->regmap = devm_regmap_init_mmio(&pdev->dev, base, 373 usp->regmap = devm_regmap_init_mmio(&pdev->dev, base,
diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c
new file mode 100644
index 000000000000..79ffc2820ba9
--- /dev/null
+++ b/sound/soc/soc-component.c
@@ -0,0 +1,561 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// soc-component.c
4//
5// Copyright (C) 2019 Renesas Electronics Corp.
6// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7//
8#include <linux/module.h>
9#include <sound/soc.h>
10
11/**
12 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
13 * @component: COMPONENT
14 * @clk_id: DAI specific clock ID
15 * @source: Source for the clock
16 * @freq: new clock frequency in Hz
17 * @dir: new clock direction - input/output.
18 *
19 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
20 */
21int snd_soc_component_set_sysclk(struct snd_soc_component *component,
22 int clk_id, int source, unsigned int freq,
23 int dir)
24{
25 if (component->driver->set_sysclk)
26 return component->driver->set_sysclk(component, clk_id, source,
27 freq, dir);
28
29 return -ENOTSUPP;
30}
31EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
32
33/*
34 * snd_soc_component_set_pll - configure component PLL.
35 * @component: COMPONENT
36 * @pll_id: DAI specific PLL ID
37 * @source: DAI specific source for the PLL
38 * @freq_in: PLL input clock frequency in Hz
39 * @freq_out: requested PLL output clock frequency in Hz
40 *
41 * Configures and enables PLL to generate output clock based on input clock.
42 */
43int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
44 int source, unsigned int freq_in,
45 unsigned int freq_out)
46{
47 if (component->driver->set_pll)
48 return component->driver->set_pll(component, pll_id, source,
49 freq_in, freq_out);
50
51 return -EINVAL;
52}
53EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
54
55void snd_soc_component_seq_notifier(struct snd_soc_component *component,
56 enum snd_soc_dapm_type type, int subseq)
57{
58 if (component->driver->seq_notifier)
59 component->driver->seq_notifier(component, type, subseq);
60}
61
62int snd_soc_component_stream_event(struct snd_soc_component *component,
63 int event)
64{
65 if (component->driver->stream_event)
66 return component->driver->stream_event(component, event);
67
68 return 0;
69}
70
71int snd_soc_component_set_bias_level(struct snd_soc_component *component,
72 enum snd_soc_bias_level level)
73{
74 if (component->driver->set_bias_level)
75 return component->driver->set_bias_level(component, level);
76
77 return 0;
78}
79
80int snd_soc_component_enable_pin(struct snd_soc_component *component,
81 const char *pin)
82{
83 struct snd_soc_dapm_context *dapm =
84 snd_soc_component_get_dapm(component);
85 char *full_name;
86 int ret;
87
88 if (!component->name_prefix)
89 return snd_soc_dapm_enable_pin(dapm, pin);
90
91 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
92 if (!full_name)
93 return -ENOMEM;
94
95 ret = snd_soc_dapm_enable_pin(dapm, full_name);
96 kfree(full_name);
97
98 return ret;
99}
100EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
101
102int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
103 const char *pin)
104{
105 struct snd_soc_dapm_context *dapm =
106 snd_soc_component_get_dapm(component);
107 char *full_name;
108 int ret;
109
110 if (!component->name_prefix)
111 return snd_soc_dapm_enable_pin_unlocked(dapm, pin);
112
113 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
114 if (!full_name)
115 return -ENOMEM;
116
117 ret = snd_soc_dapm_enable_pin_unlocked(dapm, full_name);
118 kfree(full_name);
119
120 return ret;
121}
122EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
123
124int snd_soc_component_disable_pin(struct snd_soc_component *component,
125 const char *pin)
126{
127 struct snd_soc_dapm_context *dapm =
128 snd_soc_component_get_dapm(component);
129 char *full_name;
130 int ret;
131
132 if (!component->name_prefix)
133 return snd_soc_dapm_disable_pin(dapm, pin);
134
135 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
136 if (!full_name)
137 return -ENOMEM;
138
139 ret = snd_soc_dapm_disable_pin(dapm, full_name);
140 kfree(full_name);
141
142 return ret;
143}
144EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
145
146int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
147 const char *pin)
148{
149 struct snd_soc_dapm_context *dapm =
150 snd_soc_component_get_dapm(component);
151 char *full_name;
152 int ret;
153
154 if (!component->name_prefix)
155 return snd_soc_dapm_disable_pin_unlocked(dapm, pin);
156
157 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
158 if (!full_name)
159 return -ENOMEM;
160
161 ret = snd_soc_dapm_disable_pin_unlocked(dapm, full_name);
162 kfree(full_name);
163
164 return ret;
165}
166EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
167
168int snd_soc_component_nc_pin(struct snd_soc_component *component,
169 const char *pin)
170{
171 struct snd_soc_dapm_context *dapm =
172 snd_soc_component_get_dapm(component);
173 char *full_name;
174 int ret;
175
176 if (!component->name_prefix)
177 return snd_soc_dapm_nc_pin(dapm, pin);
178
179 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
180 if (!full_name)
181 return -ENOMEM;
182
183 ret = snd_soc_dapm_nc_pin(dapm, full_name);
184 kfree(full_name);
185
186 return ret;
187}
188EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
189
190int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
191 const char *pin)
192{
193 struct snd_soc_dapm_context *dapm =
194 snd_soc_component_get_dapm(component);
195 char *full_name;
196 int ret;
197
198 if (!component->name_prefix)
199 return snd_soc_dapm_nc_pin_unlocked(dapm, pin);
200
201 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
202 if (!full_name)
203 return -ENOMEM;
204
205 ret = snd_soc_dapm_nc_pin_unlocked(dapm, full_name);
206 kfree(full_name);
207
208 return ret;
209}
210EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
211
212int snd_soc_component_get_pin_status(struct snd_soc_component *component,
213 const char *pin)
214{
215 struct snd_soc_dapm_context *dapm =
216 snd_soc_component_get_dapm(component);
217 char *full_name;
218 int ret;
219
220 if (!component->name_prefix)
221 return snd_soc_dapm_get_pin_status(dapm, pin);
222
223 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
224 if (!full_name)
225 return -ENOMEM;
226
227 ret = snd_soc_dapm_get_pin_status(dapm, full_name);
228 kfree(full_name);
229
230 return ret;
231}
232EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
233
234int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
235 const char *pin)
236{
237 struct snd_soc_dapm_context *dapm =
238 snd_soc_component_get_dapm(component);
239 char *full_name;
240 int ret;
241
242 if (!component->name_prefix)
243 return snd_soc_dapm_force_enable_pin(dapm, pin);
244
245 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
246 if (!full_name)
247 return -ENOMEM;
248
249 ret = snd_soc_dapm_force_enable_pin(dapm, full_name);
250 kfree(full_name);
251
252 return ret;
253}
254EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
255
256int snd_soc_component_force_enable_pin_unlocked(
257 struct snd_soc_component *component,
258 const char *pin)
259{
260 struct snd_soc_dapm_context *dapm =
261 snd_soc_component_get_dapm(component);
262 char *full_name;
263 int ret;
264
265 if (!component->name_prefix)
266 return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
267
268 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
269 if (!full_name)
270 return -ENOMEM;
271
272 ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, full_name);
273 kfree(full_name);
274
275 return ret;
276}
277EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
278
279/**
280 * snd_soc_component_set_jack - configure component jack.
281 * @component: COMPONENTs
282 * @jack: structure to use for the jack
283 * @data: can be used if codec driver need extra data for configuring jack
284 *
285 * Configures and enables jack detection function.
286 */
287int snd_soc_component_set_jack(struct snd_soc_component *component,
288 struct snd_soc_jack *jack, void *data)
289{
290 if (component->driver->set_jack)
291 return component->driver->set_jack(component, jack, data);
292
293 return -ENOTSUPP;
294}
295EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
296
297int snd_soc_component_module_get(struct snd_soc_component *component,
298 int upon_open)
299{
300 if (component->driver->module_get_upon_open == !!upon_open &&
301 !try_module_get(component->dev->driver->owner))
302 return -ENODEV;
303
304 return 0;
305}
306
307void snd_soc_component_module_put(struct snd_soc_component *component,
308 int upon_open)
309{
310 if (component->driver->module_get_upon_open == !!upon_open)
311 module_put(component->dev->driver->owner);
312}
313
314int snd_soc_component_open(struct snd_soc_component *component,
315 struct snd_pcm_substream *substream)
316{
317 if (component->driver->ops &&
318 component->driver->ops->open)
319 return component->driver->ops->open(substream);
320
321 return 0;
322}
323
324int snd_soc_component_close(struct snd_soc_component *component,
325 struct snd_pcm_substream *substream)
326{
327 if (component->driver->ops &&
328 component->driver->ops->close)
329 return component->driver->ops->close(substream);
330
331 return 0;
332}
333
334int snd_soc_component_prepare(struct snd_soc_component *component,
335 struct snd_pcm_substream *substream)
336{
337 if (component->driver->ops &&
338 component->driver->ops->prepare)
339 return component->driver->ops->prepare(substream);
340
341 return 0;
342}
343
344int snd_soc_component_hw_params(struct snd_soc_component *component,
345 struct snd_pcm_substream *substream,
346 struct snd_pcm_hw_params *params)
347{
348 if (component->driver->ops &&
349 component->driver->ops->hw_params)
350 return component->driver->ops->hw_params(substream, params);
351
352 return 0;
353}
354
355int snd_soc_component_hw_free(struct snd_soc_component *component,
356 struct snd_pcm_substream *substream)
357{
358 if (component->driver->ops &&
359 component->driver->ops->hw_free)
360 return component->driver->ops->hw_free(substream);
361
362 return 0;
363}
364
365int snd_soc_component_trigger(struct snd_soc_component *component,
366 struct snd_pcm_substream *substream,
367 int cmd)
368{
369 if (component->driver->ops &&
370 component->driver->ops->trigger)
371 return component->driver->ops->trigger(substream, cmd);
372
373 return 0;
374}
375
376void snd_soc_component_suspend(struct snd_soc_component *component)
377{
378 if (component->driver->suspend)
379 component->driver->suspend(component);
380 component->suspended = 1;
381}
382
383void snd_soc_component_resume(struct snd_soc_component *component)
384{
385 if (component->driver->resume)
386 component->driver->resume(component);
387 component->suspended = 0;
388}
389
390int snd_soc_component_is_suspended(struct snd_soc_component *component)
391{
392 return component->suspended;
393}
394
395int snd_soc_component_probe(struct snd_soc_component *component)
396{
397 if (component->driver->probe)
398 return component->driver->probe(component);
399
400 return 0;
401}
402
403void snd_soc_component_remove(struct snd_soc_component *component)
404{
405 if (component->driver->remove)
406 component->driver->remove(component);
407}
408
409int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
410 struct device_node *ep)
411{
412 if (component->driver->of_xlate_dai_id)
413 return component->driver->of_xlate_dai_id(component, ep);
414
415 return -ENOTSUPP;
416}
417
418int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
419 struct of_phandle_args *args,
420 const char **dai_name)
421{
422 if (component->driver->of_xlate_dai_name)
423 return component->driver->of_xlate_dai_name(component,
424 args, dai_name);
425 return -ENOTSUPP;
426}
427
428int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
429{
430 struct snd_soc_pcm_runtime *rtd = substream->private_data;
431 struct snd_soc_component *component;
432 struct snd_soc_rtdcom_list *rtdcom;
433
434 for_each_rtdcom(rtd, rtdcom) {
435 component = rtdcom->component;
436
437 /* FIXME: use 1st pointer */
438 if (component->driver->ops &&
439 component->driver->ops->pointer)
440 return component->driver->ops->pointer(substream);
441 }
442
443 return 0;
444}
445
446int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
447 unsigned int cmd, void *arg)
448{
449 struct snd_soc_pcm_runtime *rtd = substream->private_data;
450 struct snd_soc_component *component;
451 struct snd_soc_rtdcom_list *rtdcom;
452
453 for_each_rtdcom(rtd, rtdcom) {
454 component = rtdcom->component;
455
456 /* FIXME: use 1st ioctl */
457 if (component->driver->ops &&
458 component->driver->ops->ioctl)
459 return component->driver->ops->ioctl(substream,
460 cmd, arg);
461 }
462
463 return snd_pcm_lib_ioctl(substream, cmd, arg);
464}
465
466int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
467 int channel, unsigned long pos,
468 void __user *buf, unsigned long bytes)
469{
470 struct snd_soc_pcm_runtime *rtd = substream->private_data;
471 struct snd_soc_rtdcom_list *rtdcom;
472 struct snd_soc_component *component;
473
474 for_each_rtdcom(rtd, rtdcom) {
475 component = rtdcom->component;
476
477 /* FIXME. it returns 1st copy now */
478 if (component->driver->ops &&
479 component->driver->ops->copy_user)
480 return component->driver->ops->copy_user(
481 substream, channel, pos, buf, bytes);
482 }
483
484 return -EINVAL;
485}
486
487struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
488 unsigned long offset)
489{
490 struct snd_soc_pcm_runtime *rtd = substream->private_data;
491 struct snd_soc_rtdcom_list *rtdcom;
492 struct snd_soc_component *component;
493 struct page *page;
494
495 for_each_rtdcom(rtd, rtdcom) {
496 component = rtdcom->component;
497
498 /* FIXME. it returns 1st page now */
499 if (component->driver->ops &&
500 component->driver->ops->page) {
501 page = component->driver->ops->page(substream, offset);
502 if (page)
503 return page;
504 }
505 }
506
507 return NULL;
508}
509
510int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
511 struct vm_area_struct *vma)
512{
513 struct snd_soc_pcm_runtime *rtd = substream->private_data;
514 struct snd_soc_rtdcom_list *rtdcom;
515 struct snd_soc_component *component;
516
517 for_each_rtdcom(rtd, rtdcom) {
518 component = rtdcom->component;
519
520 /* FIXME. it returns 1st mmap now */
521 if (component->driver->ops &&
522 component->driver->ops->mmap)
523 return component->driver->ops->mmap(substream, vma);
524 }
525
526 return -EINVAL;
527}
528
529int snd_soc_pcm_component_new(struct snd_pcm *pcm)
530{
531 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
532 struct snd_soc_rtdcom_list *rtdcom;
533 struct snd_soc_component *component;
534 int ret;
535
536 for_each_rtdcom(rtd, rtdcom) {
537 component = rtdcom->component;
538
539 if (component->driver->pcm_new) {
540 ret = component->driver->pcm_new(rtd);
541 if (ret < 0)
542 return ret;
543 }
544 }
545
546 return 0;
547}
548
549void snd_soc_pcm_component_free(struct snd_pcm *pcm)
550{
551 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
552 struct snd_soc_rtdcom_list *rtdcom;
553 struct snd_soc_component *component;
554
555 for_each_rtdcom(rtd, rtdcom) {
556 component = rtdcom->component;
557
558 if (component->driver->pcm_free)
559 component->driver->pcm_free(pcm);
560 }
561}
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index ddef4ff677ce..9e54d8ae6d2c 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -80,7 +80,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
80 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 80 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
81 int ret; 81 int ret;
82 82
83 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 83 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
84 84
85 if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) { 85 if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
86 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai); 86 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
@@ -108,7 +108,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
108 108
109 snd_soc_runtime_activate(rtd, cstream->direction); 109 snd_soc_runtime_activate(rtd, cstream->direction);
110 110
111 mutex_unlock(&rtd->pcm_mutex); 111 mutex_unlock(&rtd->card->pcm_mutex);
112 112
113 return 0; 113 return 0;
114 114
@@ -118,7 +118,7 @@ machine_err:
118 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown) 118 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
119 cpu_dai->driver->cops->shutdown(cstream, cpu_dai); 119 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
120out: 120out:
121 mutex_unlock(&rtd->pcm_mutex); 121 mutex_unlock(&rtd->card->pcm_mutex);
122 return ret; 122 return ret;
123} 123}
124 124
@@ -224,7 +224,7 @@ static void close_delayed_work(struct work_struct *work)
224 container_of(work, struct snd_soc_pcm_runtime, delayed_work.work); 224 container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
225 struct snd_soc_dai *codec_dai = rtd->codec_dai; 225 struct snd_soc_dai *codec_dai = rtd->codec_dai;
226 226
227 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 227 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
228 228
229 dev_dbg(rtd->dev, 229 dev_dbg(rtd->dev,
230 "Compress ASoC: pop wq checking: %s status: %s waiting: %s\n", 230 "Compress ASoC: pop wq checking: %s status: %s waiting: %s\n",
@@ -239,7 +239,7 @@ static void close_delayed_work(struct work_struct *work)
239 SND_SOC_DAPM_STREAM_STOP); 239 SND_SOC_DAPM_STREAM_STOP);
240 } 240 }
241 241
242 mutex_unlock(&rtd->pcm_mutex); 242 mutex_unlock(&rtd->card->pcm_mutex);
243} 243}
244 244
245static int soc_compr_free(struct snd_compr_stream *cstream) 245static int soc_compr_free(struct snd_compr_stream *cstream)
@@ -249,7 +249,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
249 struct snd_soc_dai *codec_dai = rtd->codec_dai; 249 struct snd_soc_dai *codec_dai = rtd->codec_dai;
250 int stream; 250 int stream;
251 251
252 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 252 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
253 253
254 if (cstream->direction == SND_COMPRESS_PLAYBACK) 254 if (cstream->direction == SND_COMPRESS_PLAYBACK)
255 stream = SNDRV_PCM_STREAM_PLAYBACK; 255 stream = SNDRV_PCM_STREAM_PLAYBACK;
@@ -292,7 +292,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
292 SND_SOC_DAPM_STREAM_STOP); 292 SND_SOC_DAPM_STREAM_STOP);
293 } 293 }
294 294
295 mutex_unlock(&rtd->pcm_mutex); 295 mutex_unlock(&rtd->card->pcm_mutex);
296 return 0; 296 return 0;
297} 297}
298 298
@@ -375,7 +375,7 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
375 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 375 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
376 int ret; 376 int ret;
377 377
378 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 378 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
379 379
380 ret = soc_compr_components_trigger(cstream, cmd); 380 ret = soc_compr_components_trigger(cstream, cmd);
381 if (ret < 0) 381 if (ret < 0)
@@ -394,7 +394,7 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
394 } 394 }
395 395
396out: 396out:
397 mutex_unlock(&rtd->pcm_mutex); 397 mutex_unlock(&rtd->card->pcm_mutex);
398 return ret; 398 return ret;
399} 399}
400 400
@@ -480,7 +480,7 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
480 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 480 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
481 int ret; 481 int ret;
482 482
483 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 483 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
484 484
485 /* 485 /*
486 * First we call set_params for the CPU DAI, then the component 486 * First we call set_params for the CPU DAI, then the component
@@ -514,14 +514,14 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
514 514
515 /* cancel any delayed stream shutdown that is pending */ 515 /* cancel any delayed stream shutdown that is pending */
516 rtd->pop_wait = 0; 516 rtd->pop_wait = 0;
517 mutex_unlock(&rtd->pcm_mutex); 517 mutex_unlock(&rtd->card->pcm_mutex);
518 518
519 cancel_delayed_work_sync(&rtd->delayed_work); 519 cancel_delayed_work_sync(&rtd->delayed_work);
520 520
521 return 0; 521 return 0;
522 522
523err: 523err:
524 mutex_unlock(&rtd->pcm_mutex); 524 mutex_unlock(&rtd->card->pcm_mutex);
525 return ret; 525 return ret;
526} 526}
527 527
@@ -593,7 +593,7 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
593 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 593 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
594 int ret = 0; 594 int ret = 0;
595 595
596 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 596 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
597 597
598 if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_params) { 598 if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_params) {
599 ret = cpu_dai->driver->cops->get_params(cstream, params, cpu_dai); 599 ret = cpu_dai->driver->cops->get_params(cstream, params, cpu_dai);
@@ -613,7 +613,7 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
613 } 613 }
614 614
615err: 615err:
616 mutex_unlock(&rtd->pcm_mutex); 616 mutex_unlock(&rtd->card->pcm_mutex);
617 return ret; 617 return ret;
618} 618}
619 619
@@ -625,7 +625,7 @@ static int soc_compr_get_caps(struct snd_compr_stream *cstream,
625 struct snd_soc_rtdcom_list *rtdcom; 625 struct snd_soc_rtdcom_list *rtdcom;
626 int ret = 0; 626 int ret = 0;
627 627
628 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 628 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
629 629
630 for_each_rtdcom(rtd, rtdcom) { 630 for_each_rtdcom(rtd, rtdcom) {
631 component = rtdcom->component; 631 component = rtdcom->component;
@@ -638,7 +638,7 @@ static int soc_compr_get_caps(struct snd_compr_stream *cstream,
638 break; 638 break;
639 } 639 }
640 640
641 mutex_unlock(&rtd->pcm_mutex); 641 mutex_unlock(&rtd->card->pcm_mutex);
642 return ret; 642 return ret;
643} 643}
644 644
@@ -650,7 +650,7 @@ static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
650 struct snd_soc_rtdcom_list *rtdcom; 650 struct snd_soc_rtdcom_list *rtdcom;
651 int ret = 0; 651 int ret = 0;
652 652
653 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 653 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
654 654
655 for_each_rtdcom(rtd, rtdcom) { 655 for_each_rtdcom(rtd, rtdcom) {
656 component = rtdcom->component; 656 component = rtdcom->component;
@@ -664,7 +664,7 @@ static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
664 break; 664 break;
665 } 665 }
666 666
667 mutex_unlock(&rtd->pcm_mutex); 667 mutex_unlock(&rtd->card->pcm_mutex);
668 return ret; 668 return ret;
669} 669}
670 670
@@ -676,7 +676,7 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
676 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 676 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
677 int ret = 0; 677 int ret = 0;
678 678
679 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 679 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
680 680
681 if (cpu_dai->driver->cops && cpu_dai->driver->cops->ack) { 681 if (cpu_dai->driver->cops && cpu_dai->driver->cops->ack) {
682 ret = cpu_dai->driver->cops->ack(cstream, bytes, cpu_dai); 682 ret = cpu_dai->driver->cops->ack(cstream, bytes, cpu_dai);
@@ -697,7 +697,7 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
697 } 697 }
698 698
699err: 699err:
700 mutex_unlock(&rtd->pcm_mutex); 700 mutex_unlock(&rtd->card->pcm_mutex);
701 return ret; 701 return ret;
702} 702}
703 703
@@ -710,7 +710,7 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
710 int ret = 0; 710 int ret = 0;
711 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 711 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
712 712
713 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 713 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
714 714
715 if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer) 715 if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
716 cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai); 716 cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
@@ -726,7 +726,7 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
726 break; 726 break;
727 } 727 }
728 728
729 mutex_unlock(&rtd->pcm_mutex); 729 mutex_unlock(&rtd->card->pcm_mutex);
730 return ret; 730 return ret;
731} 731}
732 732
@@ -738,7 +738,7 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
738 struct snd_soc_rtdcom_list *rtdcom; 738 struct snd_soc_rtdcom_list *rtdcom;
739 int ret = 0; 739 int ret = 0;
740 740
741 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 741 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
742 742
743 for_each_rtdcom(rtd, rtdcom) { 743 for_each_rtdcom(rtd, rtdcom) {
744 component = rtdcom->component; 744 component = rtdcom->component;
@@ -751,7 +751,7 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
751 break; 751 break;
752 } 752 }
753 753
754 mutex_unlock(&rtd->pcm_mutex); 754 mutex_unlock(&rtd->card->pcm_mutex);
755 return ret; 755 return ret;
756} 756}
757 757
@@ -872,14 +872,13 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
872 } 872 }
873 873
874 /* check client and interface hw capabilities */ 874 /* check client and interface hw capabilities */
875 if (codec_dai->driver->playback.channels_min) 875 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
876 snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
876 playback = 1; 877 playback = 1;
877 if (codec_dai->driver->capture.channels_min) 878 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
879 snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
878 capture = 1; 880 capture = 1;
879 881
880 capture = capture && cpu_dai->driver->capture.channels_min;
881 playback = playback && cpu_dai->driver->playback.channels_min;
882
883 /* 882 /*
884 * Compress devices are unidirectional so only one of the directions 883 * Compress devices are unidirectional so only one of the directions
885 * should be set, check for that (xor) 884 * should be set, check for that (xor)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 44f899b970c2..35f48e9c5ead 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -73,6 +73,7 @@ static int pmdown_time = 5000;
73module_param(pmdown_time, int, 0); 73module_param(pmdown_time, int, 0);
74MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)"); 74MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
75 75
76#ifdef CONFIG_DMI
76/* 77/*
77 * If a DMI filed contain strings in this blacklist (e.g. 78 * If a DMI filed contain strings in this blacklist (e.g.
78 * "Type2 - Board Manufacturer" or "Type1 - TBD by OEM"), it will be taken 79 * "Type2 - Board Manufacturer" or "Type1 - TBD by OEM"), it will be taken
@@ -87,6 +88,7 @@ static const char * const dmi_blacklist[] = {
87 "Board Product Name", 88 "Board Product Name",
88 NULL, /* terminator */ 89 NULL, /* terminator */
89}; 90};
91#endif
90 92
91static ssize_t pmdown_time_show(struct device *dev, 93static ssize_t pmdown_time_show(struct device *dev,
92 struct device_attribute *attr, char *buf) 94 struct device_attribute *attr, char *buf)
@@ -165,20 +167,16 @@ static void soc_init_component_debugfs(struct snd_soc_component *component)
165 component->card->debugfs_card_root); 167 component->card->debugfs_card_root);
166 } 168 }
167 169
168 if (IS_ERR(component->debugfs_root)) {
169 dev_warn(component->dev,
170 "ASoC: Failed to create component debugfs directory: %ld\n",
171 PTR_ERR(component->debugfs_root));
172 return;
173 }
174
175 snd_soc_dapm_debugfs_init(snd_soc_component_get_dapm(component), 170 snd_soc_dapm_debugfs_init(snd_soc_component_get_dapm(component),
176 component->debugfs_root); 171 component->debugfs_root);
177} 172}
178 173
179static void soc_cleanup_component_debugfs(struct snd_soc_component *component) 174static void soc_cleanup_component_debugfs(struct snd_soc_component *component)
180{ 175{
176 if (!component->debugfs_root)
177 return;
181 debugfs_remove_recursive(component->debugfs_root); 178 debugfs_remove_recursive(component->debugfs_root);
179 component->debugfs_root = NULL;
182} 180}
183 181
184static int dai_list_show(struct seq_file *m, void *v) 182static int dai_list_show(struct seq_file *m, void *v)
@@ -215,32 +213,17 @@ DEFINE_SHOW_ATTRIBUTE(component_list);
215 213
216static void soc_init_card_debugfs(struct snd_soc_card *card) 214static void soc_init_card_debugfs(struct snd_soc_card *card)
217{ 215{
218 if (!snd_soc_debugfs_root)
219 return;
220
221 card->debugfs_card_root = debugfs_create_dir(card->name, 216 card->debugfs_card_root = debugfs_create_dir(card->name,
222 snd_soc_debugfs_root); 217 snd_soc_debugfs_root);
223 if (IS_ERR(card->debugfs_card_root)) {
224 dev_warn(card->dev,
225 "ASoC: Failed to create card debugfs directory: %ld\n",
226 PTR_ERR(card->debugfs_card_root));
227 card->debugfs_card_root = NULL;
228 return;
229 }
230 218
231 card->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644, 219 debugfs_create_u32("dapm_pop_time", 0644, card->debugfs_card_root,
232 card->debugfs_card_root, 220 &card->pop_time);
233 &card->pop_time); 221
234 if (IS_ERR(card->debugfs_pop_time)) 222 snd_soc_dapm_debugfs_init(&card->dapm, card->debugfs_card_root);
235 dev_warn(card->dev,
236 "ASoC: Failed to create pop time debugfs file: %ld\n",
237 PTR_ERR(card->debugfs_pop_time));
238} 223}
239 224
240static void soc_cleanup_card_debugfs(struct snd_soc_card *card) 225static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
241{ 226{
242 if (!card->debugfs_card_root)
243 return;
244 debugfs_remove_recursive(card->debugfs_card_root); 227 debugfs_remove_recursive(card->debugfs_card_root);
245 card->debugfs_card_root = NULL; 228 card->debugfs_card_root = NULL;
246} 229}
@@ -248,19 +231,12 @@ static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
248static void snd_soc_debugfs_init(void) 231static void snd_soc_debugfs_init(void)
249{ 232{
250 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL); 233 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
251 if (IS_ERR_OR_NULL(snd_soc_debugfs_root)) {
252 pr_warn("ASoC: Failed to create debugfs directory\n");
253 snd_soc_debugfs_root = NULL;
254 return;
255 }
256 234
257 if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL, 235 debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
258 &dai_list_fops)) 236 &dai_list_fops);
259 pr_warn("ASoC: Failed to create DAI list debugfs file\n");
260 237
261 if (!debugfs_create_file("components", 0444, snd_soc_debugfs_root, NULL, 238 debugfs_create_file("components", 0444, snd_soc_debugfs_root, NULL,
262 &component_list_fops)) 239 &component_list_fops);
263 pr_warn("ASoC: Failed to create component list debugfs file\n");
264} 240}
265 241
266static void snd_soc_debugfs_exit(void) 242static void snd_soc_debugfs_exit(void)
@@ -302,7 +278,6 @@ static int snd_soc_rtdcom_add(struct snd_soc_pcm_runtime *rtd,
302 struct snd_soc_component *component) 278 struct snd_soc_component *component)
303{ 279{
304 struct snd_soc_rtdcom_list *rtdcom; 280 struct snd_soc_rtdcom_list *rtdcom;
305 struct snd_soc_rtdcom_list *new_rtdcom;
306 281
307 for_each_rtdcom(rtd, rtdcom) { 282 for_each_rtdcom(rtd, rtdcom) {
308 /* already connected */ 283 /* already connected */
@@ -310,14 +285,14 @@ static int snd_soc_rtdcom_add(struct snd_soc_pcm_runtime *rtd,
310 return 0; 285 return 0;
311 } 286 }
312 287
313 new_rtdcom = kmalloc(sizeof(*new_rtdcom), GFP_KERNEL); 288 rtdcom = kmalloc(sizeof(*rtdcom), GFP_KERNEL);
314 if (!new_rtdcom) 289 if (!rtdcom)
315 return -ENOMEM; 290 return -ENOMEM;
316 291
317 new_rtdcom->component = component; 292 rtdcom->component = component;
318 INIT_LIST_HEAD(&new_rtdcom->list); 293 INIT_LIST_HEAD(&rtdcom->list);
319 294
320 list_add_tail(&new_rtdcom->list, &rtd->component_list); 295 list_add_tail(&rtdcom->list, &rtd->component_list);
321 296
322 return 0; 297 return 0;
323} 298}
@@ -340,6 +315,14 @@ struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,
340 if (!driver_name) 315 if (!driver_name)
341 return NULL; 316 return NULL;
342 317
318 /*
319 * NOTE
320 *
321 * snd_soc_rtdcom_lookup() will find component from rtd by using
322 * specified driver name.
323 * But, if many components which have same driver name are connected
324 * to 1 rtd, this function will return 1st found component.
325 */
343 for_each_rtdcom(rtd, rtdcom) { 326 for_each_rtdcom(rtd, rtdcom) {
344 const char *component_name = rtdcom->component->driver->name; 327 const char *component_name = rtdcom->component->driver->name;
345 328
@@ -408,6 +391,7 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
408static void soc_add_pcm_runtime(struct snd_soc_card *card, 391static void soc_add_pcm_runtime(struct snd_soc_card *card,
409 struct snd_soc_pcm_runtime *rtd) 392 struct snd_soc_pcm_runtime *rtd)
410{ 393{
394 /* see for_each_card_rtds */
411 list_add_tail(&rtd->list, &card->rtd_list); 395 list_add_tail(&rtd->list, &card->rtd_list);
412 rtd->num = card->num_rtd; 396 rtd->num = card->num_rtd;
413 card->num_rtd++; 397 card->num_rtd++;
@@ -447,16 +431,6 @@ static void snd_soc_flush_all_delayed_work(struct snd_soc_card *card)
447 flush_delayed_work(&rtd->delayed_work); 431 flush_delayed_work(&rtd->delayed_work);
448} 432}
449 433
450static void codec2codec_close_delayed_work(struct work_struct *work)
451{
452 /*
453 * Currently nothing to do for c2c links
454 * Since c2c links are internal nodes in the DAPM graph and
455 * don't interface with the outside world or application layer
456 * we don't have to do any special handling on close.
457 */
458}
459
460#ifdef CONFIG_PM_SLEEP 434#ifdef CONFIG_PM_SLEEP
461/* powers down audio subsystem for suspend */ 435/* powers down audio subsystem for suspend */
462int snd_soc_suspend(struct device *dev) 436int snd_soc_suspend(struct device *dev)
@@ -487,10 +461,9 @@ int snd_soc_suspend(struct device *dev)
487 continue; 461 continue;
488 462
489 for_each_rtd_codec_dai(rtd, i, dai) { 463 for_each_rtd_codec_dai(rtd, i, dai) {
490 struct snd_soc_dai_driver *drv = dai->driver; 464 if (dai->playback_active)
491 465 snd_soc_dai_digital_mute(dai, 1,
492 if (drv->ops->digital_mute && dai->playback_active) 466 SNDRV_PCM_STREAM_PLAYBACK);
493 drv->ops->digital_mute(dai, 1);
494 } 467 }
495 } 468 }
496 469
@@ -511,8 +484,8 @@ int snd_soc_suspend(struct device *dev)
511 if (rtd->dai_link->ignore_suspend) 484 if (rtd->dai_link->ignore_suspend)
512 continue; 485 continue;
513 486
514 if (cpu_dai->driver->suspend && !cpu_dai->driver->bus_control) 487 if (!cpu_dai->driver->bus_control)
515 cpu_dai->driver->suspend(cpu_dai); 488 snd_soc_dai_suspend(cpu_dai);
516 } 489 }
517 490
518 /* close any waiting streams */ 491 /* close any waiting streams */
@@ -545,7 +518,7 @@ int snd_soc_suspend(struct device *dev)
545 * If there are paths active then the COMPONENT will be held 518 * If there are paths active then the COMPONENT will be held
546 * with bias _ON and should not be suspended. 519 * with bias _ON and should not be suspended.
547 */ 520 */
548 if (!component->suspended) { 521 if (!snd_soc_component_is_suspended(component)) {
549 switch (snd_soc_dapm_get_bias_level(dapm)) { 522 switch (snd_soc_dapm_get_bias_level(dapm)) {
550 case SND_SOC_BIAS_STANDBY: 523 case SND_SOC_BIAS_STANDBY:
551 /* 524 /*
@@ -562,9 +535,7 @@ int snd_soc_suspend(struct device *dev)
562 /* fall through */ 535 /* fall through */
563 536
564 case SND_SOC_BIAS_OFF: 537 case SND_SOC_BIAS_OFF:
565 if (component->driver->suspend) 538 snd_soc_component_suspend(component);
566 component->driver->suspend(component);
567 component->suspended = 1;
568 if (component->regmap) 539 if (component->regmap)
569 regcache_mark_dirty(component->regmap); 540 regcache_mark_dirty(component->regmap);
570 /* deactivate pins to sleep state */ 541 /* deactivate pins to sleep state */
@@ -584,8 +555,8 @@ int snd_soc_suspend(struct device *dev)
584 if (rtd->dai_link->ignore_suspend) 555 if (rtd->dai_link->ignore_suspend)
585 continue; 556 continue;
586 557
587 if (cpu_dai->driver->suspend && cpu_dai->driver->bus_control) 558 if (cpu_dai->driver->bus_control)
588 cpu_dai->driver->suspend(cpu_dai); 559 snd_soc_dai_suspend(cpu_dai);
589 560
590 /* deactivate pins to sleep state */ 561 /* deactivate pins to sleep state */
591 pinctrl_pm_select_sleep_state(cpu_dai->dev); 562 pinctrl_pm_select_sleep_state(cpu_dai->dev);
@@ -631,16 +602,13 @@ static void soc_resume_deferred(struct work_struct *work)
631 if (rtd->dai_link->ignore_suspend) 602 if (rtd->dai_link->ignore_suspend)
632 continue; 603 continue;
633 604
634 if (cpu_dai->driver->resume && cpu_dai->driver->bus_control) 605 if (cpu_dai->driver->bus_control)
635 cpu_dai->driver->resume(cpu_dai); 606 snd_soc_dai_resume(cpu_dai);
636 } 607 }
637 608
638 for_each_card_components(card, component) { 609 for_each_card_components(card, component) {
639 if (component->suspended) { 610 if (snd_soc_component_is_suspended(component))
640 if (component->driver->resume) 611 snd_soc_component_resume(component);
641 component->driver->resume(component);
642 component->suspended = 0;
643 }
644 } 612 }
645 613
646 for_each_card_rtds(card, rtd) { 614 for_each_card_rtds(card, rtd) {
@@ -665,10 +633,9 @@ static void soc_resume_deferred(struct work_struct *work)
665 continue; 633 continue;
666 634
667 for_each_rtd_codec_dai(rtd, i, dai) { 635 for_each_rtd_codec_dai(rtd, i, dai) {
668 struct snd_soc_dai_driver *drv = dai->driver; 636 if (dai->playback_active)
669 637 snd_soc_dai_digital_mute(dai, 0,
670 if (drv->ops->digital_mute && dai->playback_active) 638 SNDRV_PCM_STREAM_PLAYBACK);
671 drv->ops->digital_mute(dai, 0);
672 } 639 }
673 } 640 }
674 641
@@ -678,8 +645,8 @@ static void soc_resume_deferred(struct work_struct *work)
678 if (rtd->dai_link->ignore_suspend) 645 if (rtd->dai_link->ignore_suspend)
679 continue; 646 continue;
680 647
681 if (cpu_dai->driver->resume && !cpu_dai->driver->bus_control) 648 if (!cpu_dai->driver->bus_control)
682 cpu_dai->driver->resume(cpu_dai); 649 snd_soc_dai_resume(cpu_dai);
683 } 650 }
684 651
685 if (card->resume_post) 652 if (card->resume_post)
@@ -744,9 +711,18 @@ int snd_soc_resume(struct device *dev)
744 return 0; 711 return 0;
745} 712}
746EXPORT_SYMBOL_GPL(snd_soc_resume); 713EXPORT_SYMBOL_GPL(snd_soc_resume);
714
715static void soc_resume_init(struct snd_soc_card *card)
716{
717 /* deferred resume work */
718 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
719}
747#else 720#else
748#define snd_soc_suspend NULL 721#define snd_soc_suspend NULL
749#define snd_soc_resume NULL 722#define snd_soc_resume NULL
723static inline void soc_resume_init(struct snd_soc_card *card)
724{
725}
750#endif 726#endif
751 727
752static const struct snd_soc_dai_ops null_dai_ops = { 728static const struct snd_soc_dai_ops null_dai_ops = {
@@ -861,11 +837,11 @@ struct snd_soc_dai_link *snd_soc_find_dai_link(struct snd_soc_card *card,
861 int id, const char *name, 837 int id, const char *name,
862 const char *stream_name) 838 const char *stream_name)
863{ 839{
864 struct snd_soc_dai_link *link, *_link; 840 struct snd_soc_dai_link *link;
865 841
866 lockdep_assert_held(&client_mutex); 842 lockdep_assert_held(&client_mutex);
867 843
868 for_each_card_links_safe(card, link, _link) { 844 for_each_card_links(card, link) {
869 if (link->id != id) 845 if (link->id != id)
870 continue; 846 continue;
871 847
@@ -962,15 +938,51 @@ _err_defer:
962 return -EPROBE_DEFER; 938 return -EPROBE_DEFER;
963} 939}
964 940
941static void soc_set_of_name_prefix(struct snd_soc_component *component)
942{
943 struct device_node *of_node = soc_component_to_node(component);
944 const char *str;
945 int ret;
946
947 ret = of_property_read_string(of_node, "sound-name-prefix", &str);
948 if (!ret)
949 component->name_prefix = str;
950}
951
952static void soc_set_name_prefix(struct snd_soc_card *card,
953 struct snd_soc_component *component)
954{
955 int i;
956
957 for (i = 0; i < card->num_configs && card->codec_conf; i++) {
958 struct snd_soc_codec_conf *map = &card->codec_conf[i];
959 struct device_node *of_node = soc_component_to_node(component);
960
961 if (map->of_node && of_node != map->of_node)
962 continue;
963 if (map->dev_name && strcmp(component->name, map->dev_name))
964 continue;
965 component->name_prefix = map->name_prefix;
966 return;
967 }
968
969 /*
970 * If there is no configuration table or no match in the table,
971 * check if a prefix is provided in the node
972 */
973 soc_set_of_name_prefix(component);
974}
975
965static void soc_cleanup_component(struct snd_soc_component *component) 976static void soc_cleanup_component(struct snd_soc_component *component)
966{ 977{
978 /* For framework level robustness */
967 snd_soc_component_set_jack(component, NULL, NULL); 979 snd_soc_component_set_jack(component, NULL, NULL);
980
968 list_del(&component->card_list); 981 list_del(&component->card_list);
969 snd_soc_dapm_free(snd_soc_component_get_dapm(component)); 982 snd_soc_dapm_free(snd_soc_component_get_dapm(component));
970 soc_cleanup_component_debugfs(component); 983 soc_cleanup_component_debugfs(component);
971 component->card = NULL; 984 component->card = NULL;
972 if (!component->driver->module_get_upon_open) 985 snd_soc_component_module_put_when_remove(component);
973 module_put(component->dev->driver->owner);
974} 986}
975 987
976static void soc_remove_component(struct snd_soc_component *component) 988static void soc_remove_component(struct snd_soc_component *component)
@@ -978,12 +990,105 @@ static void soc_remove_component(struct snd_soc_component *component)
978 if (!component->card) 990 if (!component->card)
979 return; 991 return;
980 992
981 if (component->driver->remove) 993 snd_soc_component_remove(component);
982 component->driver->remove(component);
983 994
984 soc_cleanup_component(component); 995 soc_cleanup_component(component);
985} 996}
986 997
998static int soc_probe_component(struct snd_soc_card *card,
999 struct snd_soc_component *component)
1000{
1001 struct snd_soc_dapm_context *dapm =
1002 snd_soc_component_get_dapm(component);
1003 struct snd_soc_dai *dai;
1004 int ret;
1005
1006 if (!strcmp(component->name, "snd-soc-dummy"))
1007 return 0;
1008
1009 if (component->card) {
1010 if (component->card != card) {
1011 dev_err(component->dev,
1012 "Trying to bind component to card \"%s\" but is already bound to card \"%s\"\n",
1013 card->name, component->card->name);
1014 return -ENODEV;
1015 }
1016 return 0;
1017 }
1018
1019 ret = snd_soc_component_module_get_when_probe(component);
1020 if (ret < 0)
1021 return ret;
1022
1023 component->card = card;
1024 soc_set_name_prefix(card, component);
1025
1026 soc_init_component_debugfs(component);
1027
1028 snd_soc_dapm_init(dapm, card, component);
1029
1030 ret = snd_soc_dapm_new_controls(dapm,
1031 component->driver->dapm_widgets,
1032 component->driver->num_dapm_widgets);
1033
1034 if (ret != 0) {
1035 dev_err(component->dev,
1036 "Failed to create new controls %d\n", ret);
1037 goto err_probe;
1038 }
1039
1040 for_each_component_dais(component, dai) {
1041 ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1042 if (ret != 0) {
1043 dev_err(component->dev,
1044 "Failed to create DAI widgets %d\n", ret);
1045 goto err_probe;
1046 }
1047 }
1048
1049 ret = snd_soc_component_probe(component);
1050 if (ret < 0) {
1051 dev_err(component->dev,
1052 "ASoC: failed to probe component %d\n", ret);
1053 goto err_probe;
1054 }
1055 WARN(dapm->idle_bias_off &&
1056 dapm->bias_level != SND_SOC_BIAS_OFF,
1057 "codec %s can not start from non-off bias with idle_bias_off==1\n",
1058 component->name);
1059
1060 /* machine specific init */
1061 if (component->init) {
1062 ret = component->init(component);
1063 if (ret < 0) {
1064 dev_err(component->dev,
1065 "Failed to do machine specific init %d\n", ret);
1066 goto err_probe;
1067 }
1068 }
1069
1070 ret = snd_soc_add_component_controls(component,
1071 component->driver->controls,
1072 component->driver->num_controls);
1073 if (ret < 0)
1074 goto err_probe;
1075
1076 ret = snd_soc_dapm_add_routes(dapm,
1077 component->driver->dapm_routes,
1078 component->driver->num_dapm_routes);
1079 if (ret < 0)
1080 goto err_probe;
1081
1082 /* see for_each_card_components */
1083 list_add(&component->card_list, &card->component_dev_list);
1084
1085err_probe:
1086 if (ret < 0)
1087 soc_cleanup_component(component);
1088
1089 return ret;
1090}
1091
987static void soc_remove_dai(struct snd_soc_dai *dai, int order) 1092static void soc_remove_dai(struct snd_soc_dai *dai, int order)
988{ 1093{
989 int err; 1094 int err;
@@ -992,65 +1097,141 @@ static void soc_remove_dai(struct snd_soc_dai *dai, int order)
992 dai->driver->remove_order != order) 1097 dai->driver->remove_order != order)
993 return; 1098 return;
994 1099
995 if (dai->driver->remove) { 1100 err = snd_soc_dai_remove(dai);
996 err = dai->driver->remove(dai); 1101 if (err < 0)
997 if (err < 0) 1102 dev_err(dai->dev,
998 dev_err(dai->dev, 1103 "ASoC: failed to remove %s: %d\n",
999 "ASoC: failed to remove %s: %d\n", 1104 dai->name, err);
1000 dai->name, err); 1105
1001 }
1002 dai->probed = 0; 1106 dai->probed = 0;
1003} 1107}
1004 1108
1005static void soc_remove_link_dais(struct snd_soc_card *card, 1109static int soc_probe_dai(struct snd_soc_dai *dai, int order)
1006 struct snd_soc_pcm_runtime *rtd, int order) 1110{
1111 int ret;
1112
1113 if (dai->probed ||
1114 dai->driver->probe_order != order)
1115 return 0;
1116
1117 ret = snd_soc_dai_probe(dai);
1118 if (ret < 0) {
1119 dev_err(dai->dev, "ASoC: failed to probe DAI %s: %d\n",
1120 dai->name, ret);
1121 return ret;
1122 }
1123
1124 dai->probed = 1;
1125
1126 return 0;
1127}
1128
1129static void soc_rtd_free(struct snd_soc_pcm_runtime *rtd); /* remove me */
1130static void soc_remove_link_dais(struct snd_soc_card *card)
1007{ 1131{
1008 int i; 1132 int i;
1009 struct snd_soc_dai *codec_dai; 1133 struct snd_soc_dai *codec_dai;
1134 struct snd_soc_pcm_runtime *rtd;
1135 int order;
1010 1136
1011 /* unregister the rtd device */ 1137 for_each_comp_order(order) {
1012 if (rtd->dev_registered) { 1138 for_each_card_rtds(card, rtd) {
1013 device_unregister(rtd->dev); 1139
1014 rtd->dev_registered = 0; 1140 /* finalize rtd device */
1141 soc_rtd_free(rtd);
1142
1143 /* remove the CODEC DAI */
1144 for_each_rtd_codec_dai(rtd, i, codec_dai)
1145 soc_remove_dai(codec_dai, order);
1146
1147 soc_remove_dai(rtd->cpu_dai, order);
1148 }
1015 } 1149 }
1150}
1016 1151
1017 /* remove the CODEC DAI */ 1152static int soc_probe_link_dais(struct snd_soc_card *card)
1018 for_each_rtd_codec_dai(rtd, i, codec_dai) 1153{
1019 soc_remove_dai(codec_dai, order); 1154 struct snd_soc_dai *codec_dai;
1155 struct snd_soc_pcm_runtime *rtd;
1156 int i, order, ret;
1020 1157
1021 soc_remove_dai(rtd->cpu_dai, order); 1158 for_each_comp_order(order) {
1159 for_each_card_rtds(card, rtd) {
1160
1161 dev_dbg(card->dev,
1162 "ASoC: probe %s dai link %d late %d\n",
1163 card->name, rtd->num, order);
1164
1165 ret = soc_probe_dai(rtd->cpu_dai, order);
1166 if (ret)
1167 return ret;
1168
1169 /* probe the CODEC DAI */
1170 for_each_rtd_codec_dai(rtd, i, codec_dai) {
1171 ret = soc_probe_dai(codec_dai, order);
1172 if (ret)
1173 return ret;
1174 }
1175 }
1176 }
1177
1178 return 0;
1022} 1179}
1023 1180
1024static void soc_remove_link_components(struct snd_soc_card *card, 1181static void soc_remove_link_components(struct snd_soc_card *card)
1025 struct snd_soc_pcm_runtime *rtd, int order)
1026{ 1182{
1027 struct snd_soc_component *component; 1183 struct snd_soc_component *component;
1184 struct snd_soc_pcm_runtime *rtd;
1028 struct snd_soc_rtdcom_list *rtdcom; 1185 struct snd_soc_rtdcom_list *rtdcom;
1186 int order;
1029 1187
1030 for_each_rtdcom(rtd, rtdcom) { 1188 for_each_comp_order(order) {
1031 component = rtdcom->component; 1189 for_each_card_rtds(card, rtd) {
1190 for_each_rtdcom(rtd, rtdcom) {
1191 component = rtdcom->component;
1192
1193 if (component->driver->remove_order != order)
1194 continue;
1032 1195
1033 if (component->driver->remove_order == order) 1196 soc_remove_component(component);
1034 soc_remove_component(component); 1197 }
1198 }
1035 } 1199 }
1036} 1200}
1037 1201
1038static void soc_remove_dai_links(struct snd_soc_card *card) 1202static int soc_probe_link_components(struct snd_soc_card *card)
1039{ 1203{
1040 int order; 1204 struct snd_soc_component *component;
1041 struct snd_soc_pcm_runtime *rtd; 1205 struct snd_soc_pcm_runtime *rtd;
1042 struct snd_soc_dai_link *link, *_link; 1206 struct snd_soc_rtdcom_list *rtdcom;
1207 int ret, order;
1043 1208
1044 for_each_comp_order(order) { 1209 for_each_comp_order(order) {
1045 for_each_card_rtds(card, rtd) 1210 for_each_card_rtds(card, rtd) {
1046 soc_remove_link_dais(card, rtd, order); 1211 for_each_rtdcom(rtd, rtdcom) {
1047 } 1212 component = rtdcom->component;
1048 1213
1049 for_each_comp_order(order) { 1214 if (component->driver->probe_order != order)
1050 for_each_card_rtds(card, rtd) 1215 continue;
1051 soc_remove_link_components(card, rtd, order); 1216
1217 ret = soc_probe_component(card, component);
1218 if (ret < 0)
1219 return ret;
1220 }
1221 }
1052 } 1222 }
1053 1223
1224 return 0;
1225}
1226
1227static void soc_remove_dai_links(struct snd_soc_card *card)
1228{
1229 struct snd_soc_dai_link *link, *_link;
1230
1231 soc_remove_link_dais(card);
1232
1233 soc_remove_link_components(card);
1234
1054 for_each_card_links_safe(card, link, _link) { 1235 for_each_card_links_safe(card, link, _link) {
1055 if (link->dobj.type == SND_SOC_DOBJ_DAI_LINK) 1236 if (link->dobj.type == SND_SOC_DOBJ_DAI_LINK)
1056 dev_warn(card->dev, "Topology forgot to remove link %s?\n", 1237 dev_warn(card->dev, "Topology forgot to remove link %s?\n",
@@ -1197,6 +1378,7 @@ int snd_soc_add_dai_link(struct snd_soc_card *card,
1197 if (dai_link->dobj.type && card->add_dai_link) 1378 if (dai_link->dobj.type && card->add_dai_link)
1198 card->add_dai_link(card, dai_link); 1379 card->add_dai_link(card, dai_link);
1199 1380
1381 /* see for_each_card_links */
1200 list_add_tail(&dai_link->list, &card->dai_link_list); 1382 list_add_tail(&dai_link->list, &card->dai_link_list);
1201 1383
1202 return 0; 1384 return 0;
@@ -1216,8 +1398,6 @@ EXPORT_SYMBOL_GPL(snd_soc_add_dai_link);
1216void snd_soc_remove_dai_link(struct snd_soc_card *card, 1398void snd_soc_remove_dai_link(struct snd_soc_card *card,
1217 struct snd_soc_dai_link *dai_link) 1399 struct snd_soc_dai_link *dai_link)
1218{ 1400{
1219 struct snd_soc_dai_link *link, *_link;
1220
1221 if (dai_link->dobj.type 1401 if (dai_link->dobj.type
1222 && dai_link->dobj.type != SND_SOC_DOBJ_DAI_LINK) { 1402 && dai_link->dobj.type != SND_SOC_DOBJ_DAI_LINK) {
1223 dev_err(card->dev, "Invalid dai link type %d\n", 1403 dev_err(card->dev, "Invalid dai link type %d\n",
@@ -1233,155 +1413,25 @@ void snd_soc_remove_dai_link(struct snd_soc_card *card,
1233 if (dai_link->dobj.type && card->remove_dai_link) 1413 if (dai_link->dobj.type && card->remove_dai_link)
1234 card->remove_dai_link(card, dai_link); 1414 card->remove_dai_link(card, dai_link);
1235 1415
1236 for_each_card_links_safe(card, link, _link) { 1416 list_del(&dai_link->list);
1237 if (link == dai_link) {
1238 list_del(&link->list);
1239 return;
1240 }
1241 }
1242} 1417}
1243EXPORT_SYMBOL_GPL(snd_soc_remove_dai_link); 1418EXPORT_SYMBOL_GPL(snd_soc_remove_dai_link);
1244 1419
1245static void soc_set_of_name_prefix(struct snd_soc_component *component) 1420static void soc_rtd_free(struct snd_soc_pcm_runtime *rtd)
1246{ 1421{
1247 struct device_node *component_of_node = soc_component_to_node(component); 1422 if (rtd->dev_registered) {
1248 const char *str; 1423 /* we don't need to call kfree() for rtd->dev */
1249 int ret; 1424 device_unregister(rtd->dev);
1250 1425 rtd->dev_registered = 0;
1251 ret = of_property_read_string(component_of_node, "sound-name-prefix",
1252 &str);
1253 if (!ret)
1254 component->name_prefix = str;
1255}
1256
1257static void soc_set_name_prefix(struct snd_soc_card *card,
1258 struct snd_soc_component *component)
1259{
1260 int i;
1261
1262 for (i = 0; i < card->num_configs && card->codec_conf; i++) {
1263 struct snd_soc_codec_conf *map = &card->codec_conf[i];
1264 struct device_node *component_of_node = soc_component_to_node(component);
1265
1266 if (map->of_node && component_of_node != map->of_node)
1267 continue;
1268 if (map->dev_name && strcmp(component->name, map->dev_name))
1269 continue;
1270 component->name_prefix = map->name_prefix;
1271 return;
1272 }
1273
1274 /*
1275 * If there is no configuration table or no match in the table,
1276 * check if a prefix is provided in the node
1277 */
1278 soc_set_of_name_prefix(component);
1279}
1280
1281static int soc_probe_component(struct snd_soc_card *card,
1282 struct snd_soc_component *component)
1283{
1284 struct snd_soc_dapm_context *dapm =
1285 snd_soc_component_get_dapm(component);
1286 struct snd_soc_dai *dai;
1287 int ret;
1288
1289 if (!strcmp(component->name, "snd-soc-dummy"))
1290 return 0;
1291
1292 if (component->card) {
1293 if (component->card != card) {
1294 dev_err(component->dev,
1295 "Trying to bind component to card \"%s\" but is already bound to card \"%s\"\n",
1296 card->name, component->card->name);
1297 return -ENODEV;
1298 }
1299 return 0;
1300 }
1301
1302 if (!component->driver->module_get_upon_open &&
1303 !try_module_get(component->dev->driver->owner))
1304 return -ENODEV;
1305
1306 component->card = card;
1307 dapm->card = card;
1308 INIT_LIST_HEAD(&component->card_list);
1309 INIT_LIST_HEAD(&dapm->list);
1310 soc_set_name_prefix(card, component);
1311
1312 soc_init_component_debugfs(component);
1313
1314 if (component->driver->dapm_widgets) {
1315 ret = snd_soc_dapm_new_controls(dapm,
1316 component->driver->dapm_widgets,
1317 component->driver->num_dapm_widgets);
1318
1319 if (ret != 0) {
1320 dev_err(component->dev,
1321 "Failed to create new controls %d\n", ret);
1322 goto err_probe;
1323 }
1324 }
1325
1326 for_each_component_dais(component, dai) {
1327 ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1328 if (ret != 0) {
1329 dev_err(component->dev,
1330 "Failed to create DAI widgets %d\n", ret);
1331 goto err_probe;
1332 }
1333 }
1334
1335 if (component->driver->probe) {
1336 ret = component->driver->probe(component);
1337 if (ret < 0) {
1338 dev_err(component->dev,
1339 "ASoC: failed to probe component %d\n", ret);
1340 goto err_probe;
1341 }
1342 }
1343 WARN(dapm->idle_bias_off &&
1344 dapm->bias_level != SND_SOC_BIAS_OFF,
1345 "codec %s can not start from non-off bias with idle_bias_off==1\n",
1346 component->name);
1347
1348 /* machine specific init */
1349 if (component->init) {
1350 ret = component->init(component);
1351 if (ret < 0) {
1352 dev_err(component->dev,
1353 "Failed to do machine specific init %d\n", ret);
1354 goto err_probe;
1355 }
1356 } 1426 }
1357
1358 if (component->driver->controls)
1359 snd_soc_add_component_controls(component,
1360 component->driver->controls,
1361 component->driver->num_controls);
1362 if (component->driver->dapm_routes)
1363 snd_soc_dapm_add_routes(dapm,
1364 component->driver->dapm_routes,
1365 component->driver->num_dapm_routes);
1366
1367 list_add(&dapm->list, &card->dapm_list);
1368 /* see for_each_card_components */
1369 list_add(&component->card_list, &card->component_dev_list);
1370
1371err_probe:
1372 if (ret < 0)
1373 soc_cleanup_component(component);
1374
1375 return ret;
1376} 1427}
1377 1428
1378static void rtd_release(struct device *dev) 1429static void soc_rtd_release(struct device *dev)
1379{ 1430{
1380 kfree(dev); 1431 kfree(dev);
1381} 1432}
1382 1433
1383static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd, 1434static int soc_rtd_init(struct snd_soc_pcm_runtime *rtd, const char *name)
1384 const char *name)
1385{ 1435{
1386 int ret = 0; 1436 int ret = 0;
1387 1437
@@ -1389,18 +1439,16 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd,
1389 rtd->dev = kzalloc(sizeof(struct device), GFP_KERNEL); 1439 rtd->dev = kzalloc(sizeof(struct device), GFP_KERNEL);
1390 if (!rtd->dev) 1440 if (!rtd->dev)
1391 return -ENOMEM; 1441 return -ENOMEM;
1392 device_initialize(rtd->dev);
1393 rtd->dev->parent = rtd->card->dev; 1442 rtd->dev->parent = rtd->card->dev;
1394 rtd->dev->release = rtd_release; 1443 rtd->dev->release = soc_rtd_release;
1395 rtd->dev->groups = soc_dev_attr_groups; 1444 rtd->dev->groups = soc_dev_attr_groups;
1396 dev_set_name(rtd->dev, "%s", name); 1445 dev_set_name(rtd->dev, "%s", name);
1397 dev_set_drvdata(rtd->dev, rtd); 1446 dev_set_drvdata(rtd->dev, rtd);
1398 mutex_init(&rtd->pcm_mutex);
1399 INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients); 1447 INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients);
1400 INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients); 1448 INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients);
1401 INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients); 1449 INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients);
1402 INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients); 1450 INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients);
1403 ret = device_add(rtd->dev); 1451 ret = device_register(rtd->dev);
1404 if (ret < 0) { 1452 if (ret < 0) {
1405 /* calling put_device() here to free the rtd->dev */ 1453 /* calling put_device() here to free the rtd->dev */
1406 put_device(rtd->dev); 1454 put_device(rtd->dev);
@@ -1412,47 +1460,6 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd,
1412 return 0; 1460 return 0;
1413} 1461}
1414 1462
1415static int soc_probe_link_components(struct snd_soc_card *card,
1416 struct snd_soc_pcm_runtime *rtd, int order)
1417{
1418 struct snd_soc_component *component;
1419 struct snd_soc_rtdcom_list *rtdcom;
1420 int ret;
1421
1422 for_each_rtdcom(rtd, rtdcom) {
1423 component = rtdcom->component;
1424
1425 if (component->driver->probe_order == order) {
1426 ret = soc_probe_component(card, component);
1427 if (ret < 0)
1428 return ret;
1429 }
1430 }
1431
1432 return 0;
1433}
1434
1435static int soc_probe_dai(struct snd_soc_dai *dai, int order)
1436{
1437 if (dai->probed ||
1438 dai->driver->probe_order != order)
1439 return 0;
1440
1441 if (dai->driver->probe) {
1442 int ret = dai->driver->probe(dai);
1443
1444 if (ret < 0) {
1445 dev_err(dai->dev, "ASoC: failed to probe DAI %s: %d\n",
1446 dai->name, ret);
1447 return ret;
1448 }
1449 }
1450
1451 dai->probed = 1;
1452
1453 return 0;
1454}
1455
1456static int soc_link_dai_pcm_new(struct snd_soc_dai **dais, int num_dais, 1463static int soc_link_dai_pcm_new(struct snd_soc_dai **dais, int num_dais,
1457 struct snd_soc_pcm_runtime *rtd) 1464 struct snd_soc_pcm_runtime *rtd)
1458{ 1465{
@@ -1474,37 +1481,18 @@ static int soc_link_dai_pcm_new(struct snd_soc_dai **dais, int num_dais,
1474 return 0; 1481 return 0;
1475} 1482}
1476 1483
1477static int soc_probe_link_dais(struct snd_soc_card *card, 1484static int soc_link_init(struct snd_soc_card *card,
1478 struct snd_soc_pcm_runtime *rtd, int order) 1485 struct snd_soc_pcm_runtime *rtd)
1479{ 1486{
1480 struct snd_soc_dai_link *dai_link = rtd->dai_link; 1487 struct snd_soc_dai_link *dai_link = rtd->dai_link;
1481 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1488 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1482 struct snd_soc_rtdcom_list *rtdcom; 1489 struct snd_soc_rtdcom_list *rtdcom;
1483 struct snd_soc_component *component; 1490 struct snd_soc_component *component;
1484 struct snd_soc_dai *codec_dai; 1491 int ret, num;
1485 int i, ret, num;
1486
1487 dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n",
1488 card->name, rtd->num, order);
1489 1492
1490 /* set default power off timeout */ 1493 /* set default power off timeout */
1491 rtd->pmdown_time = pmdown_time; 1494 rtd->pmdown_time = pmdown_time;
1492 1495
1493 ret = soc_probe_dai(cpu_dai, order);
1494 if (ret)
1495 return ret;
1496
1497 /* probe the CODEC DAI */
1498 for_each_rtd_codec_dai(rtd, i, codec_dai) {
1499 ret = soc_probe_dai(codec_dai, order);
1500 if (ret)
1501 return ret;
1502 }
1503
1504 /* complete DAI probe during last probe */
1505 if (order != SND_SOC_COMP_ORDER_LAST)
1506 return 0;
1507
1508 /* do machine specific initialization */ 1496 /* do machine specific initialization */
1509 if (dai_link->init) { 1497 if (dai_link->init) {
1510 ret = dai_link->init(rtd); 1498 ret = dai_link->init(rtd);
@@ -1521,15 +1509,12 @@ static int soc_probe_link_dais(struct snd_soc_card *card,
1521 return ret; 1509 return ret;
1522 } 1510 }
1523 1511
1524 ret = soc_post_component_init(rtd, dai_link->name); 1512 ret = soc_rtd_init(rtd, dai_link->name);
1525 if (ret) 1513 if (ret)
1526 return ret; 1514 return ret;
1527 1515
1528#ifdef CONFIG_DEBUG_FS
1529 /* add DPCM sysfs entries */ 1516 /* add DPCM sysfs entries */
1530 if (dai_link->dynamic) 1517 soc_dpcm_debugfs_add(rtd);
1531 soc_dpcm_debugfs_add(rtd);
1532#endif
1533 1518
1534 num = rtd->num; 1519 num = rtd->num;
1535 1520
@@ -1550,73 +1535,57 @@ static int soc_probe_link_dais(struct snd_soc_card *card,
1550 num = rtd->dai_link->id; 1535 num = rtd->dai_link->id;
1551 } 1536 }
1552 1537
1553 if (cpu_dai->driver->compress_new) { 1538 /* create compress_device if possible */
1554 /* create compress_device" */ 1539 ret = snd_soc_dai_compress_new(cpu_dai, rtd, num);
1555 ret = cpu_dai->driver->compress_new(rtd, num); 1540 if (ret != -ENOTSUPP) {
1556 if (ret < 0) { 1541 if (ret < 0)
1557 dev_err(card->dev, "ASoC: can't create compress %s\n", 1542 dev_err(card->dev, "ASoC: can't create compress %s\n",
1558 dai_link->stream_name); 1543 dai_link->stream_name);
1559 return ret; 1544 return ret;
1560 }
1561 } else if (!dai_link->params) {
1562 /* create the pcm */
1563 ret = soc_new_pcm(rtd, num);
1564 if (ret < 0) {
1565 dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
1566 dai_link->stream_name, ret);
1567 return ret;
1568 }
1569 ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd);
1570 if (ret < 0)
1571 return ret;
1572 ret = soc_link_dai_pcm_new(rtd->codec_dais,
1573 rtd->num_codecs, rtd);
1574 if (ret < 0)
1575 return ret;
1576 } else {
1577 INIT_DELAYED_WORK(&rtd->delayed_work,
1578 codec2codec_close_delayed_work);
1579 } 1545 }
1580 1546
1581 return 0; 1547 /* create the pcm */
1548 ret = soc_new_pcm(rtd, num);
1549 if (ret < 0) {
1550 dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
1551 dai_link->stream_name, ret);
1552 return ret;
1553 }
1554 ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd);
1555 if (ret < 0)
1556 return ret;
1557 ret = soc_link_dai_pcm_new(rtd->codec_dais,
1558 rtd->num_codecs, rtd);
1559 return ret;
1560}
1561
1562static void soc_unbind_aux_dev(struct snd_soc_card *card)
1563{
1564 struct snd_soc_component *component, *_component;
1565
1566 for_each_card_auxs_safe(card, component, _component) {
1567 component->init = NULL;
1568 list_del(&component->card_aux_list);
1569 }
1582} 1570}
1583 1571
1584static int soc_bind_aux_dev(struct snd_soc_card *card, int num) 1572static int soc_bind_aux_dev(struct snd_soc_card *card)
1585{ 1573{
1586 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1587 struct snd_soc_component *component; 1574 struct snd_soc_component *component;
1588 struct snd_soc_dai_link_component dlc; 1575 struct snd_soc_aux_dev *aux;
1576 int i;
1589 1577
1590 if (aux_dev->codec_of_node || aux_dev->codec_name) { 1578 for_each_card_pre_auxs(card, i, aux) {
1591 /* codecs, usually analog devices */ 1579 /* codecs, usually analog devices */
1592 dlc.name = aux_dev->codec_name; 1580 component = soc_find_component(&aux->dlc);
1593 dlc.of_node = aux_dev->codec_of_node;
1594 component = soc_find_component(&dlc);
1595 if (!component) {
1596 if (dlc.of_node)
1597 dlc.name = of_node_full_name(dlc.of_node);
1598 goto err_defer;
1599 }
1600 } else if (aux_dev->name) {
1601 /* generic components */
1602 dlc.name = aux_dev->name;
1603 dlc.of_node = NULL;
1604 component = soc_find_component(&dlc);
1605 if (!component) 1581 if (!component)
1606 goto err_defer; 1582 return -EPROBE_DEFER;
1607 } else {
1608 dev_err(card->dev, "ASoC: Invalid auxiliary device\n");
1609 return -EINVAL;
1610 }
1611
1612 component->init = aux_dev->init;
1613 list_add(&component->card_aux_list, &card->aux_comp_list);
1614 1583
1584 component->init = aux->init;
1585 /* see for_each_card_auxs */
1586 list_add(&component->card_aux_list, &card->aux_comp_list);
1587 }
1615 return 0; 1588 return 0;
1616
1617err_defer:
1618 dev_err(card->dev, "ASoC: %s not registered\n", dlc.name);
1619 return -EPROBE_DEFER;
1620} 1589}
1621 1590
1622static int soc_probe_aux_devices(struct snd_soc_card *card) 1591static int soc_probe_aux_devices(struct snd_soc_card *card)
@@ -1626,7 +1595,7 @@ static int soc_probe_aux_devices(struct snd_soc_card *card)
1626 int ret; 1595 int ret;
1627 1596
1628 for_each_comp_order(order) { 1597 for_each_comp_order(order) {
1629 list_for_each_entry(comp, &card->aux_comp_list, card_aux_list) { 1598 for_each_card_auxs(card, comp) {
1630 if (comp->driver->probe_order == order) { 1599 if (comp->driver->probe_order == order) {
1631 ret = soc_probe_component(card, comp); 1600 ret = soc_probe_component(card, comp);
1632 if (ret < 0) { 1601 if (ret < 0) {
@@ -1648,14 +1617,9 @@ static void soc_remove_aux_devices(struct snd_soc_card *card)
1648 int order; 1617 int order;
1649 1618
1650 for_each_comp_order(order) { 1619 for_each_comp_order(order) {
1651 list_for_each_entry_safe(comp, _comp, 1620 for_each_card_auxs_safe(card, comp, _comp) {
1652 &card->aux_comp_list, card_aux_list) { 1621 if (comp->driver->remove_order == order)
1653
1654 if (comp->driver->remove_order == order) {
1655 soc_remove_component(comp); 1622 soc_remove_component(comp);
1656 /* remove it from the card's aux_comp_list */
1657 list_del(&comp->card_aux_list);
1658 }
1659 } 1623 }
1660 } 1624 }
1661} 1625}
@@ -1954,7 +1918,7 @@ match:
1954 } 1918 }
1955} 1919}
1956 1920
1957static int soc_cleanup_card_resources(struct snd_soc_card *card) 1921static void soc_cleanup_card_resources(struct snd_soc_card *card)
1958{ 1922{
1959 /* free the ALSA card at first; this syncs with pending operations */ 1923 /* free the ALSA card at first; this syncs with pending operations */
1960 if (card->snd_card) { 1924 if (card->snd_card) {
@@ -1968,6 +1932,7 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
1968 1932
1969 /* remove auxiliary devices */ 1933 /* remove auxiliary devices */
1970 soc_remove_aux_devices(card); 1934 soc_remove_aux_devices(card);
1935 soc_unbind_aux_dev(card);
1971 1936
1972 snd_soc_dapm_free(&card->dapm); 1937 snd_soc_dapm_free(&card->dapm);
1973 soc_cleanup_card_debugfs(card); 1938 soc_cleanup_card_debugfs(card);
@@ -1975,15 +1940,13 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
1975 /* remove the card */ 1940 /* remove the card */
1976 if (card->remove) 1941 if (card->remove)
1977 card->remove(card); 1942 card->remove(card);
1978
1979 return 0;
1980} 1943}
1981 1944
1982static int snd_soc_instantiate_card(struct snd_soc_card *card) 1945static int snd_soc_instantiate_card(struct snd_soc_card *card)
1983{ 1946{
1984 struct snd_soc_pcm_runtime *rtd; 1947 struct snd_soc_pcm_runtime *rtd;
1985 struct snd_soc_dai_link *dai_link; 1948 struct snd_soc_dai_link *dai_link;
1986 int ret, i, order; 1949 int ret, i;
1987 1950
1988 mutex_lock(&client_mutex); 1951 mutex_lock(&client_mutex);
1989 for_each_card_prelinks(card, i, dai_link) { 1952 for_each_card_prelinks(card, i, dai_link) {
@@ -1997,10 +1960,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1997 } 1960 }
1998 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT); 1961 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
1999 1962
2000 card->dapm.bias_level = SND_SOC_BIAS_OFF; 1963 snd_soc_dapm_init(&card->dapm, card, NULL);
2001 card->dapm.dev = card->dev;
2002 card->dapm.card = card;
2003 list_add(&card->dapm.list, &card->dapm_list);
2004 1964
2005 /* check whether any platform is ignore machine FE and using topology */ 1965 /* check whether any platform is ignore machine FE and using topology */
2006 soc_check_tplg_fes(card); 1966 soc_check_tplg_fes(card);
@@ -2013,15 +1973,16 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
2013 } 1973 }
2014 1974
2015 /* bind aux_devs too */ 1975 /* bind aux_devs too */
2016 for (i = 0; i < card->num_aux_devs; i++) { 1976 ret = soc_bind_aux_dev(card);
2017 ret = soc_bind_aux_dev(card, i); 1977 if (ret < 0)
2018 if (ret != 0) 1978 goto probe_end;
2019 goto probe_end;
2020 }
2021 1979
2022 /* add predefined DAI links to the list */ 1980 /* add predefined DAI links to the list */
2023 for_each_card_prelinks(card, i, dai_link) 1981 for_each_card_prelinks(card, i, dai_link) {
2024 snd_soc_add_dai_link(card, dai_link); 1982 ret = snd_soc_add_dai_link(card, dai_link);
1983 if (ret < 0)
1984 goto probe_end;
1985 }
2025 1986
2026 /* card bind complete so register a sound card */ 1987 /* card bind complete so register a sound card */
2027 ret = snd_card_new(card->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, 1988 ret = snd_card_new(card->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
@@ -2035,22 +1996,17 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
2035 1996
2036 soc_init_card_debugfs(card); 1997 soc_init_card_debugfs(card);
2037 1998
2038#ifdef CONFIG_DEBUG_FS 1999 soc_resume_init(card);
2039 snd_soc_dapm_debugfs_init(&card->dapm, card->debugfs_card_root);
2040#endif
2041 2000
2042#ifdef CONFIG_PM_SLEEP 2001 ret = snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,
2043 /* deferred resume work */ 2002 card->num_dapm_widgets);
2044 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 2003 if (ret < 0)
2045#endif 2004 goto probe_end;
2046
2047 if (card->dapm_widgets)
2048 snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,
2049 card->num_dapm_widgets);
2050 2005
2051 if (card->of_dapm_widgets) 2006 ret = snd_soc_dapm_new_controls(&card->dapm, card->of_dapm_widgets,
2052 snd_soc_dapm_new_controls(&card->dapm, card->of_dapm_widgets, 2007 card->num_of_dapm_widgets);
2053 card->num_of_dapm_widgets); 2008 if (ret < 0)
2009 goto probe_end;
2054 2010
2055 /* initialise the sound card only once */ 2011 /* initialise the sound card only once */
2056 if (card->probe) { 2012 if (card->probe) {
@@ -2060,16 +2016,11 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
2060 } 2016 }
2061 2017
2062 /* probe all components used by DAI links on this card */ 2018 /* probe all components used by DAI links on this card */
2063 for_each_comp_order(order) { 2019 ret = soc_probe_link_components(card);
2064 for_each_card_rtds(card, rtd) { 2020 if (ret < 0) {
2065 ret = soc_probe_link_components(card, rtd, order); 2021 dev_err(card->dev,
2066 if (ret < 0) { 2022 "ASoC: failed to instantiate card %d\n", ret);
2067 dev_err(card->dev, 2023 goto probe_end;
2068 "ASoC: failed to instantiate card %d\n",
2069 ret);
2070 goto probe_end;
2071 }
2072 }
2073 } 2024 }
2074 2025
2075 /* probe auxiliary components */ 2026 /* probe auxiliary components */
@@ -2094,32 +2045,33 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
2094 } 2045 }
2095 2046
2096 /* probe all DAI links on this card */ 2047 /* probe all DAI links on this card */
2097 for_each_comp_order(order) { 2048 ret = soc_probe_link_dais(card);
2098 for_each_card_rtds(card, rtd) { 2049 if (ret < 0) {
2099 ret = soc_probe_link_dais(card, rtd, order); 2050 dev_err(card->dev,
2100 if (ret < 0) { 2051 "ASoC: failed to instantiate card %d\n", ret);
2101 dev_err(card->dev, 2052 goto probe_end;
2102 "ASoC: failed to instantiate card %d\n",
2103 ret);
2104 goto probe_end;
2105 }
2106 }
2107 } 2053 }
2108 2054
2055 for_each_card_rtds(card, rtd)
2056 soc_link_init(card, rtd);
2057
2109 snd_soc_dapm_link_dai_widgets(card); 2058 snd_soc_dapm_link_dai_widgets(card);
2110 snd_soc_dapm_connect_dai_link_widgets(card); 2059 snd_soc_dapm_connect_dai_link_widgets(card);
2111 2060
2112 if (card->controls) 2061 ret = snd_soc_add_card_controls(card, card->controls,
2113 snd_soc_add_card_controls(card, card->controls, 2062 card->num_controls);
2114 card->num_controls); 2063 if (ret < 0)
2064 goto probe_end;
2115 2065
2116 if (card->dapm_routes) 2066 ret = snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
2117 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 2067 card->num_dapm_routes);
2118 card->num_dapm_routes); 2068 if (ret < 0)
2069 goto probe_end;
2119 2070
2120 if (card->of_dapm_routes) 2071 ret = snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes,
2121 snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes, 2072 card->num_of_dapm_routes);
2122 card->num_of_dapm_routes); 2073 if (ret < 0)
2074 goto probe_end;
2123 2075
2124 /* try to set some sane longname if DMI is available */ 2076 /* try to set some sane longname if DMI is available */
2125 snd_soc_set_dmi_name(card, NULL); 2077 snd_soc_set_dmi_name(card, NULL);
@@ -2397,293 +2349,6 @@ int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
2397} 2349}
2398EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls); 2350EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls);
2399 2351
2400/**
2401 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
2402 * @dai: DAI
2403 * @clk_id: DAI specific clock ID
2404 * @freq: new clock frequency in Hz
2405 * @dir: new clock direction - input/output.
2406 *
2407 * Configures the DAI master (MCLK) or system (SYSCLK) clocking.
2408 */
2409int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
2410 unsigned int freq, int dir)
2411{
2412 if (dai->driver->ops->set_sysclk)
2413 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
2414
2415 return snd_soc_component_set_sysclk(dai->component, clk_id, 0,
2416 freq, dir);
2417}
2418EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
2419
2420/**
2421 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
2422 * @component: COMPONENT
2423 * @clk_id: DAI specific clock ID
2424 * @source: Source for the clock
2425 * @freq: new clock frequency in Hz
2426 * @dir: new clock direction - input/output.
2427 *
2428 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
2429 */
2430int snd_soc_component_set_sysclk(struct snd_soc_component *component,
2431 int clk_id, int source, unsigned int freq,
2432 int dir)
2433{
2434 if (component->driver->set_sysclk)
2435 return component->driver->set_sysclk(component, clk_id, source,
2436 freq, dir);
2437
2438 return -ENOTSUPP;
2439}
2440EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
2441
2442/**
2443 * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
2444 * @dai: DAI
2445 * @div_id: DAI specific clock divider ID
2446 * @div: new clock divisor.
2447 *
2448 * Configures the clock dividers. This is used to derive the best DAI bit and
2449 * frame clocks from the system or master clock. It's best to set the DAI bit
2450 * and frame clocks as low as possible to save system power.
2451 */
2452int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
2453 int div_id, int div)
2454{
2455 if (dai->driver->ops->set_clkdiv)
2456 return dai->driver->ops->set_clkdiv(dai, div_id, div);
2457 else
2458 return -EINVAL;
2459}
2460EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
2461
2462/**
2463 * snd_soc_dai_set_pll - configure DAI PLL.
2464 * @dai: DAI
2465 * @pll_id: DAI specific PLL ID
2466 * @source: DAI specific source for the PLL
2467 * @freq_in: PLL input clock frequency in Hz
2468 * @freq_out: requested PLL output clock frequency in Hz
2469 *
2470 * Configures and enables PLL to generate output clock based on input clock.
2471 */
2472int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
2473 unsigned int freq_in, unsigned int freq_out)
2474{
2475 if (dai->driver->ops->set_pll)
2476 return dai->driver->ops->set_pll(dai, pll_id, source,
2477 freq_in, freq_out);
2478
2479 return snd_soc_component_set_pll(dai->component, pll_id, source,
2480 freq_in, freq_out);
2481}
2482EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
2483
2484/*
2485 * snd_soc_component_set_pll - configure component PLL.
2486 * @component: COMPONENT
2487 * @pll_id: DAI specific PLL ID
2488 * @source: DAI specific source for the PLL
2489 * @freq_in: PLL input clock frequency in Hz
2490 * @freq_out: requested PLL output clock frequency in Hz
2491 *
2492 * Configures and enables PLL to generate output clock based on input clock.
2493 */
2494int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
2495 int source, unsigned int freq_in,
2496 unsigned int freq_out)
2497{
2498 if (component->driver->set_pll)
2499 return component->driver->set_pll(component, pll_id, source,
2500 freq_in, freq_out);
2501
2502 return -EINVAL;
2503}
2504EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
2505
2506/**
2507 * snd_soc_dai_set_bclk_ratio - configure BCLK to sample rate ratio.
2508 * @dai: DAI
2509 * @ratio: Ratio of BCLK to Sample rate.
2510 *
2511 * Configures the DAI for a preset BCLK to sample rate ratio.
2512 */
2513int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
2514{
2515 if (dai->driver->ops->set_bclk_ratio)
2516 return dai->driver->ops->set_bclk_ratio(dai, ratio);
2517 else
2518 return -EINVAL;
2519}
2520EXPORT_SYMBOL_GPL(snd_soc_dai_set_bclk_ratio);
2521
2522/**
2523 * snd_soc_dai_set_fmt - configure DAI hardware audio format.
2524 * @dai: DAI
2525 * @fmt: SND_SOC_DAIFMT_* format value.
2526 *
2527 * Configures the DAI hardware format and clocking.
2528 */
2529int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2530{
2531 if (dai->driver->ops->set_fmt == NULL)
2532 return -ENOTSUPP;
2533 return dai->driver->ops->set_fmt(dai, fmt);
2534}
2535EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
2536
2537/**
2538 * snd_soc_xlate_tdm_slot - generate tx/rx slot mask.
2539 * @slots: Number of slots in use.
2540 * @tx_mask: bitmask representing active TX slots.
2541 * @rx_mask: bitmask representing active RX slots.
2542 *
2543 * Generates the TDM tx and rx slot default masks for DAI.
2544 */
2545static int snd_soc_xlate_tdm_slot_mask(unsigned int slots,
2546 unsigned int *tx_mask,
2547 unsigned int *rx_mask)
2548{
2549 if (*tx_mask || *rx_mask)
2550 return 0;
2551
2552 if (!slots)
2553 return -EINVAL;
2554
2555 *tx_mask = (1 << slots) - 1;
2556 *rx_mask = (1 << slots) - 1;
2557
2558 return 0;
2559}
2560
2561/**
2562 * snd_soc_dai_set_tdm_slot() - Configures a DAI for TDM operation
2563 * @dai: The DAI to configure
2564 * @tx_mask: bitmask representing active TX slots.
2565 * @rx_mask: bitmask representing active RX slots.
2566 * @slots: Number of slots in use.
2567 * @slot_width: Width in bits for each slot.
2568 *
2569 * This function configures the specified DAI for TDM operation. @slot contains
2570 * the total number of slots of the TDM stream and @slot_with the width of each
2571 * slot in bit clock cycles. @tx_mask and @rx_mask are bitmasks specifying the
2572 * active slots of the TDM stream for the specified DAI, i.e. which slots the
2573 * DAI should write to or read from. If a bit is set the corresponding slot is
2574 * active, if a bit is cleared the corresponding slot is inactive. Bit 0 maps to
2575 * the first slot, bit 1 to the second slot and so on. The first active slot
2576 * maps to the first channel of the DAI, the second active slot to the second
2577 * channel and so on.
2578 *
2579 * TDM mode can be disabled by passing 0 for @slots. In this case @tx_mask,
2580 * @rx_mask and @slot_width will be ignored.
2581 *
2582 * Returns 0 on success, a negative error code otherwise.
2583 */
2584int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
2585 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
2586{
2587 if (dai->driver->ops->xlate_tdm_slot_mask)
2588 dai->driver->ops->xlate_tdm_slot_mask(slots,
2589 &tx_mask, &rx_mask);
2590 else
2591 snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask);
2592
2593 dai->tx_mask = tx_mask;
2594 dai->rx_mask = rx_mask;
2595
2596 if (dai->driver->ops->set_tdm_slot)
2597 return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
2598 slots, slot_width);
2599 else
2600 return -ENOTSUPP;
2601}
2602EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
2603
2604/**
2605 * snd_soc_dai_set_channel_map - configure DAI audio channel map
2606 * @dai: DAI
2607 * @tx_num: how many TX channels
2608 * @tx_slot: pointer to an array which imply the TX slot number channel
2609 * 0~num-1 uses
2610 * @rx_num: how many RX channels
2611 * @rx_slot: pointer to an array which imply the RX slot number channel
2612 * 0~num-1 uses
2613 *
2614 * configure the relationship between channel number and TDM slot number.
2615 */
2616int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
2617 unsigned int tx_num, unsigned int *tx_slot,
2618 unsigned int rx_num, unsigned int *rx_slot)
2619{
2620 if (dai->driver->ops->set_channel_map)
2621 return dai->driver->ops->set_channel_map(dai, tx_num, tx_slot,
2622 rx_num, rx_slot);
2623 else
2624 return -ENOTSUPP;
2625}
2626EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
2627
2628/**
2629 * snd_soc_dai_get_channel_map - Get DAI audio channel map
2630 * @dai: DAI
2631 * @tx_num: how many TX channels
2632 * @tx_slot: pointer to an array which imply the TX slot number channel
2633 * 0~num-1 uses
2634 * @rx_num: how many RX channels
2635 * @rx_slot: pointer to an array which imply the RX slot number channel
2636 * 0~num-1 uses
2637 */
2638int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
2639 unsigned int *tx_num, unsigned int *tx_slot,
2640 unsigned int *rx_num, unsigned int *rx_slot)
2641{
2642 if (dai->driver->ops->get_channel_map)
2643 return dai->driver->ops->get_channel_map(dai, tx_num, tx_slot,
2644 rx_num, rx_slot);
2645 else
2646 return -ENOTSUPP;
2647}
2648EXPORT_SYMBOL_GPL(snd_soc_dai_get_channel_map);
2649
2650/**
2651 * snd_soc_dai_set_tristate - configure DAI system or master clock.
2652 * @dai: DAI
2653 * @tristate: tristate enable
2654 *
2655 * Tristates the DAI so that others can use it.
2656 */
2657int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
2658{
2659 if (dai->driver->ops->set_tristate)
2660 return dai->driver->ops->set_tristate(dai, tristate);
2661 else
2662 return -EINVAL;
2663}
2664EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
2665
2666/**
2667 * snd_soc_dai_digital_mute - configure DAI system or master clock.
2668 * @dai: DAI
2669 * @mute: mute enable
2670 * @direction: stream to mute
2671 *
2672 * Mutes the DAI DAC.
2673 */
2674int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
2675 int direction)
2676{
2677 if (dai->driver->ops->mute_stream)
2678 return dai->driver->ops->mute_stream(dai, mute, direction);
2679 else if (direction == SNDRV_PCM_STREAM_PLAYBACK &&
2680 dai->driver->ops->digital_mute)
2681 return dai->driver->ops->digital_mute(dai, mute);
2682 else
2683 return -ENOTSUPP;
2684}
2685EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
2686
2687static int snd_soc_bind_card(struct snd_soc_card *card) 2352static int snd_soc_bind_card(struct snd_soc_card *card)
2688{ 2353{
2689 struct snd_soc_pcm_runtime *rtd; 2354 struct snd_soc_pcm_runtime *rtd;
@@ -2724,18 +2389,22 @@ int snd_soc_register_card(struct snd_soc_card *card)
2724 2389
2725 dev_set_drvdata(card->dev, card); 2390 dev_set_drvdata(card->dev, card);
2726 2391
2727 snd_soc_initialize_card_lists(card); 2392 INIT_LIST_HEAD(&card->widgets);
2728 2393 INIT_LIST_HEAD(&card->paths);
2394 INIT_LIST_HEAD(&card->dapm_list);
2395 INIT_LIST_HEAD(&card->aux_comp_list);
2396 INIT_LIST_HEAD(&card->component_dev_list);
2397 INIT_LIST_HEAD(&card->list);
2729 INIT_LIST_HEAD(&card->dai_link_list); 2398 INIT_LIST_HEAD(&card->dai_link_list);
2730
2731 INIT_LIST_HEAD(&card->rtd_list); 2399 INIT_LIST_HEAD(&card->rtd_list);
2732 card->num_rtd = 0;
2733
2734 INIT_LIST_HEAD(&card->dapm_dirty); 2400 INIT_LIST_HEAD(&card->dapm_dirty);
2735 INIT_LIST_HEAD(&card->dobj_list); 2401 INIT_LIST_HEAD(&card->dobj_list);
2402
2403 card->num_rtd = 0;
2736 card->instantiated = 0; 2404 card->instantiated = 0;
2737 mutex_init(&card->mutex); 2405 mutex_init(&card->mutex);
2738 mutex_init(&card->dapm_mutex); 2406 mutex_init(&card->dapm_mutex);
2407 mutex_init(&card->pcm_mutex);
2739 spin_lock_init(&card->dpcm_lock); 2408 spin_lock_init(&card->dpcm_lock);
2740 2409
2741 return snd_soc_bind_card(card); 2410 return snd_soc_bind_card(card);
@@ -2744,20 +2413,13 @@ EXPORT_SYMBOL_GPL(snd_soc_register_card);
2744 2413
2745static void snd_soc_unbind_card(struct snd_soc_card *card, bool unregister) 2414static void snd_soc_unbind_card(struct snd_soc_card *card, bool unregister)
2746{ 2415{
2747 struct snd_soc_pcm_runtime *rtd;
2748 int order;
2749
2750 if (card->instantiated) { 2416 if (card->instantiated) {
2751 card->instantiated = false; 2417 card->instantiated = false;
2752 snd_soc_dapm_shutdown(card); 2418 snd_soc_dapm_shutdown(card);
2753 snd_soc_flush_all_delayed_work(card); 2419 snd_soc_flush_all_delayed_work(card);
2754 2420
2755 /* remove all components used by DAI links on this card */ 2421 /* remove all components used by DAI links on this card */
2756 for_each_comp_order(order) { 2422 soc_remove_link_components(card);
2757 for_each_card_rtds(card, rtd) {
2758 soc_remove_link_components(card, rtd, order);
2759 }
2760 }
2761 2423
2762 soc_cleanup_card_resources(card); 2424 soc_cleanup_card_resources(card);
2763 if (!unregister) 2425 if (!unregister)
@@ -2994,34 +2656,13 @@ int snd_soc_register_dai(struct snd_soc_component *component,
2994} 2656}
2995EXPORT_SYMBOL_GPL(snd_soc_register_dai); 2657EXPORT_SYMBOL_GPL(snd_soc_register_dai);
2996 2658
2997static void snd_soc_component_seq_notifier(struct snd_soc_dapm_context *dapm,
2998 enum snd_soc_dapm_type type, int subseq)
2999{
3000 struct snd_soc_component *component = dapm->component;
3001
3002 component->driver->seq_notifier(component, type, subseq);
3003}
3004
3005static int snd_soc_component_stream_event(struct snd_soc_dapm_context *dapm,
3006 int event)
3007{
3008 struct snd_soc_component *component = dapm->component;
3009
3010 return component->driver->stream_event(component, event);
3011}
3012
3013static int snd_soc_component_set_bias_level(struct snd_soc_dapm_context *dapm,
3014 enum snd_soc_bias_level level)
3015{
3016 struct snd_soc_component *component = dapm->component;
3017
3018 return component->driver->set_bias_level(component, level);
3019}
3020
3021static int snd_soc_component_initialize(struct snd_soc_component *component, 2659static int snd_soc_component_initialize(struct snd_soc_component *component,
3022 const struct snd_soc_component_driver *driver, struct device *dev) 2660 const struct snd_soc_component_driver *driver, struct device *dev)
3023{ 2661{
3024 struct snd_soc_dapm_context *dapm; 2662 INIT_LIST_HEAD(&component->dai_list);
2663 INIT_LIST_HEAD(&component->dobj_list);
2664 INIT_LIST_HEAD(&component->card_list);
2665 mutex_init(&component->io_mutex);
3025 2666
3026 component->name = fmt_single_name(dev, &component->id); 2667 component->name = fmt_single_name(dev, &component->id);
3027 if (!component->name) { 2668 if (!component->name) {
@@ -3032,22 +2673,6 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
3032 component->dev = dev; 2673 component->dev = dev;
3033 component->driver = driver; 2674 component->driver = driver;
3034 2675
3035 dapm = snd_soc_component_get_dapm(component);
3036 dapm->dev = dev;
3037 dapm->component = component;
3038 dapm->bias_level = SND_SOC_BIAS_OFF;
3039 dapm->idle_bias_off = !driver->idle_bias_on;
3040 dapm->suspend_bias_off = driver->suspend_bias_off;
3041 if (driver->seq_notifier)
3042 dapm->seq_notifier = snd_soc_component_seq_notifier;
3043 if (driver->stream_event)
3044 dapm->stream_event = snd_soc_component_stream_event;
3045 if (driver->set_bias_level)
3046 dapm->set_bias_level = snd_soc_component_set_bias_level;
3047
3048 INIT_LIST_HEAD(&component->dai_list);
3049 mutex_init(&component->io_mutex);
3050
3051 return 0; 2676 return 0;
3052} 2677}
3053 2678
@@ -3115,7 +2740,6 @@ static void snd_soc_component_add(struct snd_soc_component *component)
3115 2740
3116 /* see for_each_component */ 2741 /* see for_each_component */
3117 list_add(&component->list, &component_list); 2742 list_add(&component->list, &component_list);
3118 INIT_LIST_HEAD(&component->dobj_list);
3119 2743
3120 mutex_unlock(&client_mutex); 2744 mutex_unlock(&client_mutex);
3121} 2745}
@@ -3175,12 +2799,9 @@ static void snd_soc_try_rebind_card(void)
3175{ 2799{
3176 struct snd_soc_card *card, *c; 2800 struct snd_soc_card *card, *c;
3177 2801
3178 if (!list_empty(&unbind_card_list)) { 2802 list_for_each_entry_safe(card, c, &unbind_card_list, list)
3179 list_for_each_entry_safe(card, c, &unbind_card_list, list) { 2803 if (!snd_soc_bind_card(card))
3180 if (!snd_soc_bind_card(card)) 2804 list_del(&card->list);
3181 list_del(&card->list);
3182 }
3183 }
3184} 2805}
3185 2806
3186int snd_soc_add_component(struct device *dev, 2807int snd_soc_add_component(struct device *dev,
@@ -3682,9 +3303,8 @@ int snd_soc_get_dai_id(struct device_node *ep)
3682 ret = -ENOTSUPP; 3303 ret = -ENOTSUPP;
3683 mutex_lock(&client_mutex); 3304 mutex_lock(&client_mutex);
3684 component = soc_find_component(&dlc); 3305 component = soc_find_component(&dlc);
3685 if (component && 3306 if (component)
3686 component->driver->of_xlate_dai_id) 3307 ret = snd_soc_component_of_xlate_dai_id(component, ep);
3687 ret = component->driver->of_xlate_dai_id(component, ep);
3688 mutex_unlock(&client_mutex); 3308 mutex_unlock(&client_mutex);
3689 3309
3690 of_node_put(dlc.of_node); 3310 of_node_put(dlc.of_node);
@@ -3707,11 +3327,8 @@ int snd_soc_get_dai_name(struct of_phandle_args *args,
3707 if (component_of_node != args->np) 3327 if (component_of_node != args->np)
3708 continue; 3328 continue;
3709 3329
3710 if (pos->driver->of_xlate_dai_name) { 3330 ret = snd_soc_component_of_xlate_dai_name(pos, args, dai_name);
3711 ret = pos->driver->of_xlate_dai_name(pos, 3331 if (ret == -ENOTSUPP) {
3712 args,
3713 dai_name);
3714 } else {
3715 struct snd_soc_dai *dai; 3332 struct snd_soc_dai *dai;
3716 int id = -1; 3333 int id = -1;
3717 3334
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
new file mode 100644
index 000000000000..1c7f63871c1d
--- /dev/null
+++ b/sound/soc/soc-dai.c
@@ -0,0 +1,407 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// soc-dai.c
4//
5// Copyright (C) 2019 Renesas Electronics Corp.
6// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7//
8
9#include <sound/soc.h>
10#include <sound/soc-dai.h>
11
12/**
13 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
14 * @dai: DAI
15 * @clk_id: DAI specific clock ID
16 * @freq: new clock frequency in Hz
17 * @dir: new clock direction - input/output.
18 *
19 * Configures the DAI master (MCLK) or system (SYSCLK) clocking.
20 */
21int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
22 unsigned int freq, int dir)
23{
24 if (dai->driver->ops->set_sysclk)
25 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
26
27 return snd_soc_component_set_sysclk(dai->component, clk_id, 0,
28 freq, dir);
29}
30EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
31
32/**
33 * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
34 * @dai: DAI
35 * @div_id: DAI specific clock divider ID
36 * @div: new clock divisor.
37 *
38 * Configures the clock dividers. This is used to derive the best DAI bit and
39 * frame clocks from the system or master clock. It's best to set the DAI bit
40 * and frame clocks as low as possible to save system power.
41 */
42int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
43 int div_id, int div)
44{
45 if (dai->driver->ops->set_clkdiv)
46 return dai->driver->ops->set_clkdiv(dai, div_id, div);
47 else
48 return -EINVAL;
49}
50EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
51
52/**
53 * snd_soc_dai_set_pll - configure DAI PLL.
54 * @dai: DAI
55 * @pll_id: DAI specific PLL ID
56 * @source: DAI specific source for the PLL
57 * @freq_in: PLL input clock frequency in Hz
58 * @freq_out: requested PLL output clock frequency in Hz
59 *
60 * Configures and enables PLL to generate output clock based on input clock.
61 */
62int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
63 unsigned int freq_in, unsigned int freq_out)
64{
65 if (dai->driver->ops->set_pll)
66 return dai->driver->ops->set_pll(dai, pll_id, source,
67 freq_in, freq_out);
68
69 return snd_soc_component_set_pll(dai->component, pll_id, source,
70 freq_in, freq_out);
71}
72EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
73
74/**
75 * snd_soc_dai_set_bclk_ratio - configure BCLK to sample rate ratio.
76 * @dai: DAI
77 * @ratio: Ratio of BCLK to Sample rate.
78 *
79 * Configures the DAI for a preset BCLK to sample rate ratio.
80 */
81int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
82{
83 if (dai->driver->ops->set_bclk_ratio)
84 return dai->driver->ops->set_bclk_ratio(dai, ratio);
85 else
86 return -EINVAL;
87}
88EXPORT_SYMBOL_GPL(snd_soc_dai_set_bclk_ratio);
89
90/**
91 * snd_soc_dai_set_fmt - configure DAI hardware audio format.
92 * @dai: DAI
93 * @fmt: SND_SOC_DAIFMT_* format value.
94 *
95 * Configures the DAI hardware format and clocking.
96 */
97int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
98{
99 if (dai->driver->ops->set_fmt == NULL)
100 return -ENOTSUPP;
101 return dai->driver->ops->set_fmt(dai, fmt);
102}
103EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
104
105/**
106 * snd_soc_xlate_tdm_slot - generate tx/rx slot mask.
107 * @slots: Number of slots in use.
108 * @tx_mask: bitmask representing active TX slots.
109 * @rx_mask: bitmask representing active RX slots.
110 *
111 * Generates the TDM tx and rx slot default masks for DAI.
112 */
113static int snd_soc_xlate_tdm_slot_mask(unsigned int slots,
114 unsigned int *tx_mask,
115 unsigned int *rx_mask)
116{
117 if (*tx_mask || *rx_mask)
118 return 0;
119
120 if (!slots)
121 return -EINVAL;
122
123 *tx_mask = (1 << slots) - 1;
124 *rx_mask = (1 << slots) - 1;
125
126 return 0;
127}
128
129/**
130 * snd_soc_dai_set_tdm_slot() - Configures a DAI for TDM operation
131 * @dai: The DAI to configure
132 * @tx_mask: bitmask representing active TX slots.
133 * @rx_mask: bitmask representing active RX slots.
134 * @slots: Number of slots in use.
135 * @slot_width: Width in bits for each slot.
136 *
137 * This function configures the specified DAI for TDM operation. @slot contains
138 * the total number of slots of the TDM stream and @slot_with the width of each
139 * slot in bit clock cycles. @tx_mask and @rx_mask are bitmasks specifying the
140 * active slots of the TDM stream for the specified DAI, i.e. which slots the
141 * DAI should write to or read from. If a bit is set the corresponding slot is
142 * active, if a bit is cleared the corresponding slot is inactive. Bit 0 maps to
143 * the first slot, bit 1 to the second slot and so on. The first active slot
144 * maps to the first channel of the DAI, the second active slot to the second
145 * channel and so on.
146 *
147 * TDM mode can be disabled by passing 0 for @slots. In this case @tx_mask,
148 * @rx_mask and @slot_width will be ignored.
149 *
150 * Returns 0 on success, a negative error code otherwise.
151 */
152int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
153 unsigned int tx_mask, unsigned int rx_mask,
154 int slots, int slot_width)
155{
156 if (dai->driver->ops->xlate_tdm_slot_mask)
157 dai->driver->ops->xlate_tdm_slot_mask(slots,
158 &tx_mask, &rx_mask);
159 else
160 snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask);
161
162 dai->tx_mask = tx_mask;
163 dai->rx_mask = rx_mask;
164
165 if (dai->driver->ops->set_tdm_slot)
166 return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
167 slots, slot_width);
168 else
169 return -ENOTSUPP;
170}
171EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
172
173/**
174 * snd_soc_dai_set_channel_map - configure DAI audio channel map
175 * @dai: DAI
176 * @tx_num: how many TX channels
177 * @tx_slot: pointer to an array which imply the TX slot number channel
178 * 0~num-1 uses
179 * @rx_num: how many RX channels
180 * @rx_slot: pointer to an array which imply the RX slot number channel
181 * 0~num-1 uses
182 *
183 * configure the relationship between channel number and TDM slot number.
184 */
185int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
186 unsigned int tx_num, unsigned int *tx_slot,
187 unsigned int rx_num, unsigned int *rx_slot)
188{
189 if (dai->driver->ops->set_channel_map)
190 return dai->driver->ops->set_channel_map(dai, tx_num, tx_slot,
191 rx_num, rx_slot);
192 else
193 return -ENOTSUPP;
194}
195EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
196
197/**
198 * snd_soc_dai_get_channel_map - Get DAI audio channel map
199 * @dai: DAI
200 * @tx_num: how many TX channels
201 * @tx_slot: pointer to an array which imply the TX slot number channel
202 * 0~num-1 uses
203 * @rx_num: how many RX channels
204 * @rx_slot: pointer to an array which imply the RX slot number channel
205 * 0~num-1 uses
206 */
207int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
208 unsigned int *tx_num, unsigned int *tx_slot,
209 unsigned int *rx_num, unsigned int *rx_slot)
210{
211 if (dai->driver->ops->get_channel_map)
212 return dai->driver->ops->get_channel_map(dai, tx_num, tx_slot,
213 rx_num, rx_slot);
214 else
215 return -ENOTSUPP;
216}
217EXPORT_SYMBOL_GPL(snd_soc_dai_get_channel_map);
218
219/**
220 * snd_soc_dai_set_tristate - configure DAI system or master clock.
221 * @dai: DAI
222 * @tristate: tristate enable
223 *
224 * Tristates the DAI so that others can use it.
225 */
226int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
227{
228 if (dai->driver->ops->set_tristate)
229 return dai->driver->ops->set_tristate(dai, tristate);
230 else
231 return -EINVAL;
232}
233EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
234
235/**
236 * snd_soc_dai_digital_mute - configure DAI system or master clock.
237 * @dai: DAI
238 * @mute: mute enable
239 * @direction: stream to mute
240 *
241 * Mutes the DAI DAC.
242 */
243int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
244 int direction)
245{
246 if (dai->driver->ops->mute_stream)
247 return dai->driver->ops->mute_stream(dai, mute, direction);
248 else if (direction == SNDRV_PCM_STREAM_PLAYBACK &&
249 dai->driver->ops->digital_mute)
250 return dai->driver->ops->digital_mute(dai, mute);
251 else
252 return -ENOTSUPP;
253}
254EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
255
256int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
257 struct snd_pcm_substream *substream,
258 struct snd_pcm_hw_params *params)
259{
260 struct snd_soc_pcm_runtime *rtd = substream->private_data;
261 int ret;
262
263 /* perform any topology hw_params fixups before DAI */
264 if (rtd->dai_link->be_hw_params_fixup) {
265 ret = rtd->dai_link->be_hw_params_fixup(rtd, params);
266 if (ret < 0) {
267 dev_err(rtd->dev,
268 "ASoC: hw_params topology fixup failed %d\n",
269 ret);
270 return ret;
271 }
272 }
273
274 if (dai->driver->ops->hw_params) {
275 ret = dai->driver->ops->hw_params(substream, params, dai);
276 if (ret < 0) {
277 dev_err(dai->dev, "ASoC: can't set %s hw params: %d\n",
278 dai->name, ret);
279 return ret;
280 }
281 }
282
283 return 0;
284}
285
286void snd_soc_dai_hw_free(struct snd_soc_dai *dai,
287 struct snd_pcm_substream *substream)
288{
289 if (dai->driver->ops->hw_free)
290 dai->driver->ops->hw_free(substream, dai);
291}
292
293int snd_soc_dai_startup(struct snd_soc_dai *dai,
294 struct snd_pcm_substream *substream)
295{
296 int ret = 0;
297
298 if (dai->driver->ops->startup)
299 ret = dai->driver->ops->startup(substream, dai);
300
301 return ret;
302}
303
304void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
305 struct snd_pcm_substream *substream)
306{
307 if (dai->driver->ops->shutdown)
308 dai->driver->ops->shutdown(substream, dai);
309}
310
311int snd_soc_dai_prepare(struct snd_soc_dai *dai,
312 struct snd_pcm_substream *substream)
313{
314 int ret = 0;
315
316 if (dai->driver->ops->prepare)
317 ret = dai->driver->ops->prepare(substream, dai);
318
319 return ret;
320}
321
322int snd_soc_dai_trigger(struct snd_soc_dai *dai,
323 struct snd_pcm_substream *substream,
324 int cmd)
325{
326 int ret = 0;
327
328 if (dai->driver->ops->trigger)
329 ret = dai->driver->ops->trigger(substream, cmd, dai);
330
331 return ret;
332}
333
334int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
335 struct snd_pcm_substream *substream,
336 int cmd)
337{
338 int ret = 0;
339
340 if (dai->driver->ops->bespoke_trigger)
341 ret = dai->driver->ops->bespoke_trigger(substream, cmd, dai);
342
343 return ret;
344}
345
346snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
347 struct snd_pcm_substream *substream)
348{
349 int delay = 0;
350
351 if (dai->driver->ops->delay)
352 delay = dai->driver->ops->delay(substream, dai);
353
354 return delay;
355}
356
357void snd_soc_dai_suspend(struct snd_soc_dai *dai)
358{
359 if (dai->driver->suspend)
360 dai->driver->suspend(dai);
361}
362
363void snd_soc_dai_resume(struct snd_soc_dai *dai)
364{
365 if (dai->driver->resume)
366 dai->driver->resume(dai);
367}
368
369int snd_soc_dai_probe(struct snd_soc_dai *dai)
370{
371 if (dai->driver->probe)
372 return dai->driver->probe(dai);
373 return 0;
374}
375
376int snd_soc_dai_remove(struct snd_soc_dai *dai)
377{
378 if (dai->driver->remove)
379 return dai->driver->remove(dai);
380 return 0;
381}
382
383int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
384 struct snd_soc_pcm_runtime *rtd, int num)
385{
386 if (dai->driver->compress_new)
387 return dai->driver->compress_new(rtd, num);
388 return -ENOTSUPP;
389}
390
391/*
392 * snd_soc_dai_stream_valid() - check if a DAI supports the given stream
393 *
394 * Returns true if the DAI supports the indicated stream type.
395 */
396bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir)
397{
398 struct snd_soc_pcm_stream *stream;
399
400 if (dir == SNDRV_PCM_STREAM_PLAYBACK)
401 stream = &dai->driver->playback;
402 else
403 stream = &dai->driver->capture;
404
405 /* If the codec specifies any channels at all, it supports the stream */
406 return stream->channels_min;
407}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 2790c00735f3..b6378f025836 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -684,8 +684,8 @@ int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm,
684{ 684{
685 int ret = 0; 685 int ret = 0;
686 686
687 if (dapm->set_bias_level) 687 if (dapm->component)
688 ret = dapm->set_bias_level(dapm, level); 688 ret = snd_soc_component_set_bias_level(dapm->component, level);
689 689
690 if (ret == 0) 690 if (ret == 0)
691 dapm->bias_level = level; 691 dapm->bias_level = level;
@@ -1129,6 +1129,34 @@ static int dapm_widget_list_create(struct snd_soc_dapm_widget_list **list,
1129} 1129}
1130 1130
1131/* 1131/*
1132 * Recursively reset the cached number of inputs or outputs for the specified
1133 * widget and all widgets that can be reached via incoming or outcoming paths
1134 * from the widget.
1135 */
1136static void invalidate_paths_ep(struct snd_soc_dapm_widget *widget,
1137 enum snd_soc_dapm_direction dir)
1138{
1139 enum snd_soc_dapm_direction rdir = SND_SOC_DAPM_DIR_REVERSE(dir);
1140 struct snd_soc_dapm_path *path;
1141
1142 widget->endpoints[dir] = -1;
1143
1144 snd_soc_dapm_widget_for_each_path(widget, rdir, path) {
1145 if (path->weak || path->is_supply)
1146 continue;
1147
1148 if (path->walking)
1149 return;
1150
1151 if (path->connect) {
1152 path->walking = 1;
1153 invalidate_paths_ep(path->node[dir], dir);
1154 path->walking = 0;
1155 }
1156 }
1157}
1158
1159/*
1132 * Common implementation for is_connected_output_ep() and 1160 * Common implementation for is_connected_output_ep() and
1133 * is_connected_input_ep(). The function is inlined since the combined size of 1161 * is_connected_input_ep(). The function is inlined since the combined size of
1134 * the two specialized functions is only marginally larger then the size of the 1162 * the two specialized functions is only marginally larger then the size of the
@@ -1257,21 +1285,17 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
1257 1285
1258 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 1286 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
1259 1287
1260 /* 1288 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1261 * For is_connected_{output,input}_ep fully discover the graph we need 1289 w = dai->playback_widget;
1262 * to reset the cached number of inputs and outputs. 1290 invalidate_paths_ep(w, SND_SOC_DAPM_DIR_OUT);
1263 */ 1291 paths = is_connected_output_ep(w, &widgets,
1264 list_for_each_entry(w, &card->widgets, list) {
1265 w->endpoints[SND_SOC_DAPM_DIR_IN] = -1;
1266 w->endpoints[SND_SOC_DAPM_DIR_OUT] = -1;
1267 }
1268
1269 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
1270 paths = is_connected_output_ep(dai->playback_widget, &widgets,
1271 custom_stop_condition); 1292 custom_stop_condition);
1272 else 1293 } else {
1273 paths = is_connected_input_ep(dai->capture_widget, &widgets, 1294 w = dai->capture_widget;
1295 invalidate_paths_ep(w, SND_SOC_DAPM_DIR_IN);
1296 paths = is_connected_input_ep(w, &widgets,
1274 custom_stop_condition); 1297 custom_stop_condition);
1298 }
1275 1299
1276 /* Drop starting point */ 1300 /* Drop starting point */
1277 list_del(widgets.next); 1301 list_del(widgets.next);
@@ -1611,12 +1635,12 @@ static void dapm_seq_run(struct snd_soc_card *card,
1611 if (!list_empty(&pending)) 1635 if (!list_empty(&pending))
1612 dapm_seq_run_coalesced(card, &pending); 1636 dapm_seq_run_coalesced(card, &pending);
1613 1637
1614 if (cur_dapm && cur_dapm->seq_notifier) { 1638 if (cur_dapm && cur_dapm->component) {
1615 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++) 1639 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
1616 if (sort[i] == cur_sort) 1640 if (sort[i] == cur_sort)
1617 cur_dapm->seq_notifier(cur_dapm, 1641 snd_soc_component_seq_notifier(
1618 i, 1642 cur_dapm->component,
1619 cur_subseq); 1643 i, cur_subseq);
1620 } 1644 }
1621 1645
1622 if (cur_dapm && w->dapm != cur_dapm) 1646 if (cur_dapm && w->dapm != cur_dapm)
@@ -1674,11 +1698,12 @@ static void dapm_seq_run(struct snd_soc_card *card,
1674 if (!list_empty(&pending)) 1698 if (!list_empty(&pending))
1675 dapm_seq_run_coalesced(card, &pending); 1699 dapm_seq_run_coalesced(card, &pending);
1676 1700
1677 if (cur_dapm && cur_dapm->seq_notifier) { 1701 if (cur_dapm && cur_dapm->component) {
1678 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++) 1702 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
1679 if (sort[i] == cur_sort) 1703 if (sort[i] == cur_sort)
1680 cur_dapm->seq_notifier(cur_dapm, 1704 snd_soc_component_seq_notifier(
1681 i, cur_subseq); 1705 cur_dapm->component,
1706 i, cur_subseq);
1682 } 1707 }
1683 1708
1684 list_for_each_entry(d, &card->dapm_list, list) { 1709 list_for_each_entry(d, &card->dapm_list, list) {
@@ -1912,6 +1937,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
1912 LIST_HEAD(down_list); 1937 LIST_HEAD(down_list);
1913 ASYNC_DOMAIN_EXCLUSIVE(async_domain); 1938 ASYNC_DOMAIN_EXCLUSIVE(async_domain);
1914 enum snd_soc_bias_level bias; 1939 enum snd_soc_bias_level bias;
1940 int ret;
1915 1941
1916 lockdep_assert_held(&card->dapm_mutex); 1942 lockdep_assert_held(&card->dapm_mutex);
1917 1943
@@ -2028,8 +2054,12 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
2028 2054
2029 /* do we need to notify any clients that DAPM event is complete */ 2055 /* do we need to notify any clients that DAPM event is complete */
2030 list_for_each_entry(d, &card->dapm_list, list) { 2056 list_for_each_entry(d, &card->dapm_list, list) {
2031 if (d->stream_event) 2057 if (!d->component)
2032 d->stream_event(d, event); 2058 continue;
2059
2060 ret = snd_soc_component_stream_event(d->component, event);
2061 if (ret < 0)
2062 return ret;
2033 } 2063 }
2034 2064
2035 pop_dbg(card->dev, card->pop_time, 2065 pop_dbg(card->dev, card->pop_time,
@@ -2154,50 +2184,28 @@ static const struct file_operations dapm_bias_fops = {
2154void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, 2184void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
2155 struct dentry *parent) 2185 struct dentry *parent)
2156{ 2186{
2157 struct dentry *d;
2158
2159 if (!parent || IS_ERR(parent)) 2187 if (!parent || IS_ERR(parent))
2160 return; 2188 return;
2161 2189
2162 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent); 2190 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
2163 2191
2164 if (IS_ERR(dapm->debugfs_dapm)) { 2192 debugfs_create_file("bias_level", 0444, dapm->debugfs_dapm, dapm,
2165 dev_warn(dapm->dev, 2193 &dapm_bias_fops);
2166 "ASoC: Failed to create DAPM debugfs directory %ld\n",
2167 PTR_ERR(dapm->debugfs_dapm));
2168 return;
2169 }
2170
2171 d = debugfs_create_file("bias_level", 0444,
2172 dapm->debugfs_dapm, dapm,
2173 &dapm_bias_fops);
2174 if (IS_ERR(d))
2175 dev_warn(dapm->dev,
2176 "ASoC: Failed to create bias level debugfs file: %ld\n",
2177 PTR_ERR(d));
2178} 2194}
2179 2195
2180static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w) 2196static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
2181{ 2197{
2182 struct snd_soc_dapm_context *dapm = w->dapm; 2198 struct snd_soc_dapm_context *dapm = w->dapm;
2183 struct dentry *d;
2184 2199
2185 if (!dapm->debugfs_dapm || !w->name) 2200 if (!dapm->debugfs_dapm || !w->name)
2186 return; 2201 return;
2187 2202
2188 d = debugfs_create_file(w->name, 0444, 2203 debugfs_create_file(w->name, 0444, dapm->debugfs_dapm, w,
2189 dapm->debugfs_dapm, w, 2204 &dapm_widget_power_fops);
2190 &dapm_widget_power_fops);
2191 if (IS_ERR(d))
2192 dev_warn(w->dapm->dev,
2193 "ASoC: Failed to create %s debugfs file: %ld\n",
2194 w->name, PTR_ERR(d));
2195} 2205}
2196 2206
2197static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm) 2207static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
2198{ 2208{
2199 if (!dapm->debugfs_dapm)
2200 return;
2201 debugfs_remove_recursive(dapm->debugfs_dapm); 2209 debugfs_remove_recursive(dapm->debugfs_dapm);
2202 dapm->debugfs_dapm = NULL; 2210 dapm->debugfs_dapm = NULL;
2203} 2211}
@@ -3766,25 +3774,70 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
3766} 3774}
3767EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); 3775EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
3768 3776
3769static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, 3777static int
3770 struct snd_kcontrol *kcontrol, int event) 3778snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
3779 struct snd_pcm_substream *substream)
3771{ 3780{
3772 struct snd_soc_dapm_path *path; 3781 struct snd_soc_dapm_path *path;
3773 struct snd_soc_dai *source, *sink; 3782 struct snd_soc_dai *source, *sink;
3774 struct snd_soc_pcm_runtime *rtd = w->priv; 3783 struct snd_soc_pcm_runtime *rtd = substream->private_data;
3775 const struct snd_soc_pcm_stream *config;
3776 struct snd_pcm_substream substream;
3777 struct snd_pcm_hw_params *params = NULL; 3784 struct snd_pcm_hw_params *params = NULL;
3785 const struct snd_soc_pcm_stream *config = NULL;
3778 struct snd_pcm_runtime *runtime = NULL; 3786 struct snd_pcm_runtime *runtime = NULL;
3779 unsigned int fmt; 3787 unsigned int fmt;
3780 int ret = 0; 3788 int ret = 0;
3781 3789
3782 config = rtd->dai_link->params + rtd->params_select; 3790 params = kzalloc(sizeof(*params), GFP_KERNEL);
3791 if (!params)
3792 return -ENOMEM;
3783 3793
3784 if (WARN_ON(!config) || 3794 runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
3785 WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) || 3795 if (!runtime) {
3786 list_empty(&w->edges[SND_SOC_DAPM_DIR_IN]))) 3796 ret = -ENOMEM;
3787 return -EINVAL; 3797 goto out;
3798 }
3799
3800 substream->runtime = runtime;
3801
3802 substream->stream = SNDRV_PCM_STREAM_CAPTURE;
3803 snd_soc_dapm_widget_for_each_source_path(w, path) {
3804 source = path->source->priv;
3805
3806 ret = snd_soc_dai_startup(source, substream);
3807 if (ret < 0) {
3808 dev_err(source->dev,
3809 "ASoC: startup() failed: %d\n", ret);
3810 goto out;
3811 }
3812 source->active++;
3813 }
3814
3815 substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
3816 snd_soc_dapm_widget_for_each_sink_path(w, path) {
3817 sink = path->sink->priv;
3818
3819 ret = snd_soc_dai_startup(sink, substream);
3820 if (ret < 0) {
3821 dev_err(sink->dev,
3822 "ASoC: startup() failed: %d\n", ret);
3823 goto out;
3824 }
3825 sink->active++;
3826 }
3827
3828 substream->hw_opened = 1;
3829
3830 /*
3831 * Note: getting the config after .startup() gives a chance to
3832 * either party on the link to alter the configuration if
3833 * necessary
3834 */
3835 config = rtd->dai_link->params + rtd->params_select;
3836 if (WARN_ON(!config)) {
3837 dev_err(w->dapm->dev, "ASoC: link config missing\n");
3838 ret = -EINVAL;
3839 goto out;
3840 }
3788 3841
3789 /* Be a little careful as we don't want to overflow the mask array */ 3842 /* Be a little careful as we don't want to overflow the mask array */
3790 if (config->formats) { 3843 if (config->formats) {
@@ -3792,83 +3845,74 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
3792 } else { 3845 } else {
3793 dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n", 3846 dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n",
3794 config->formats); 3847 config->formats);
3795 fmt = 0;
3796 }
3797 3848
3798 /* Currently very limited parameter selection */ 3849 ret = -EINVAL;
3799 params = kzalloc(sizeof(*params), GFP_KERNEL);
3800 if (!params) {
3801 ret = -ENOMEM;
3802 goto out; 3850 goto out;
3803 } 3851 }
3804 snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
3805 3852
3853 snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
3806 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min = 3854 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min =
3807 config->rate_min; 3855 config->rate_min;
3808 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max = 3856 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max =
3809 config->rate_max; 3857 config->rate_max;
3810
3811 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min 3858 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min
3812 = config->channels_min; 3859 = config->channels_min;
3813 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max 3860 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max
3814 = config->channels_max; 3861 = config->channels_max;
3815 3862
3816 memset(&substream, 0, sizeof(substream)); 3863 substream->stream = SNDRV_PCM_STREAM_CAPTURE;
3864 snd_soc_dapm_widget_for_each_source_path(w, path) {
3865 source = path->source->priv;
3817 3866
3818 /* Allocate a dummy snd_pcm_runtime for startup() and other ops() */ 3867 ret = snd_soc_dai_hw_params(source, substream, params);
3819 runtime = kzalloc(sizeof(*runtime), GFP_KERNEL); 3868 if (ret < 0)
3820 if (!runtime) { 3869 goto out;
3821 ret = -ENOMEM; 3870
3822 goto out; 3871 dapm_update_dai_unlocked(substream, params, source);
3823 } 3872 }
3824 substream.runtime = runtime;
3825 substream.private_data = rtd;
3826 3873
3827 switch (event) { 3874 substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
3828 case SND_SOC_DAPM_PRE_PMU: 3875 snd_soc_dapm_widget_for_each_sink_path(w, path) {
3829 substream.stream = SNDRV_PCM_STREAM_CAPTURE; 3876 sink = path->sink->priv;
3830 snd_soc_dapm_widget_for_each_source_path(w, path) {
3831 source = path->source->priv;
3832 3877
3833 if (source->driver->ops->startup) { 3878 ret = snd_soc_dai_hw_params(sink, substream, params);
3834 ret = source->driver->ops->startup(&substream, 3879 if (ret < 0)
3835 source); 3880 goto out;
3836 if (ret < 0) {
3837 dev_err(source->dev,
3838 "ASoC: startup() failed: %d\n",
3839 ret);
3840 goto out;
3841 }
3842 }
3843 source->active++;
3844 ret = soc_dai_hw_params(&substream, params, source);
3845 if (ret < 0)
3846 goto out;
3847 3881
3848 dapm_update_dai_unlocked(&substream, params, source); 3882 dapm_update_dai_unlocked(substream, params, sink);
3849 } 3883 }
3850 3884
3851 substream.stream = SNDRV_PCM_STREAM_PLAYBACK; 3885 runtime->format = params_format(params);
3852 snd_soc_dapm_widget_for_each_sink_path(w, path) { 3886 runtime->subformat = params_subformat(params);
3853 sink = path->sink->priv; 3887 runtime->channels = params_channels(params);
3888 runtime->rate = params_rate(params);
3854 3889
3855 if (sink->driver->ops->startup) { 3890out:
3856 ret = sink->driver->ops->startup(&substream, 3891 if (ret < 0)
3857 sink); 3892 kfree(runtime);
3858 if (ret < 0) { 3893
3859 dev_err(sink->dev, 3894 kfree(params);
3860 "ASoC: startup() failed: %d\n", 3895 return ret;
3861 ret); 3896}
3862 goto out; 3897
3863 } 3898static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
3864 } 3899 struct snd_kcontrol *kcontrol, int event)
3865 sink->active++; 3900{
3866 ret = soc_dai_hw_params(&substream, params, sink); 3901 struct snd_soc_dapm_path *path;
3867 if (ret < 0) 3902 struct snd_soc_dai *source, *sink;
3868 goto out; 3903 struct snd_pcm_substream *substream = w->priv;
3904 int ret = 0, saved_stream = substream->stream;
3905
3906 if (WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) ||
3907 list_empty(&w->edges[SND_SOC_DAPM_DIR_IN])))
3908 return -EINVAL;
3909
3910 switch (event) {
3911 case SND_SOC_DAPM_PRE_PMU:
3912 ret = snd_soc_dai_link_event_pre_pmu(w, substream);
3913 if (ret < 0)
3914 goto out;
3869 3915
3870 dapm_update_dai_unlocked(&substream, params, sink);
3871 }
3872 break; 3916 break;
3873 3917
3874 case SND_SOC_DAPM_POST_PMU: 3918 case SND_SOC_DAPM_POST_PMU:
@@ -3896,41 +3940,45 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
3896 ret = 0; 3940 ret = 0;
3897 } 3941 }
3898 3942
3899 substream.stream = SNDRV_PCM_STREAM_CAPTURE; 3943 substream->stream = SNDRV_PCM_STREAM_CAPTURE;
3900 snd_soc_dapm_widget_for_each_source_path(w, path) { 3944 snd_soc_dapm_widget_for_each_source_path(w, path) {
3901 source = path->source->priv; 3945 source = path->source->priv;
3946 snd_soc_dai_hw_free(source, substream);
3947 }
3902 3948
3903 if (source->driver->ops->hw_free) 3949 substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
3904 source->driver->ops->hw_free(&substream, 3950 snd_soc_dapm_widget_for_each_sink_path(w, path) {
3905 source); 3951 sink = path->sink->priv;
3952 snd_soc_dai_hw_free(sink, substream);
3953 }
3906 3954
3955 substream->stream = SNDRV_PCM_STREAM_CAPTURE;
3956 snd_soc_dapm_widget_for_each_source_path(w, path) {
3957 source = path->source->priv;
3907 source->active--; 3958 source->active--;
3908 if (source->driver->ops->shutdown) 3959 snd_soc_dai_shutdown(source, substream);
3909 source->driver->ops->shutdown(&substream,
3910 source);
3911 } 3960 }
3912 3961
3913 substream.stream = SNDRV_PCM_STREAM_PLAYBACK; 3962 substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
3914 snd_soc_dapm_widget_for_each_sink_path(w, path) { 3963 snd_soc_dapm_widget_for_each_sink_path(w, path) {
3915 sink = path->sink->priv; 3964 sink = path->sink->priv;
3916
3917 if (sink->driver->ops->hw_free)
3918 sink->driver->ops->hw_free(&substream, sink);
3919
3920 sink->active--; 3965 sink->active--;
3921 if (sink->driver->ops->shutdown) 3966 snd_soc_dai_shutdown(sink, substream);
3922 sink->driver->ops->shutdown(&substream, sink);
3923 } 3967 }
3924 break; 3968 break;
3925 3969
3970 case SND_SOC_DAPM_POST_PMD:
3971 kfree(substream->runtime);
3972 break;
3973
3926 default: 3974 default:
3927 WARN(1, "Unknown event %d\n", event); 3975 WARN(1, "Unknown event %d\n", event);
3928 ret = -EINVAL; 3976 ret = -EINVAL;
3929 } 3977 }
3930 3978
3931out: 3979out:
3932 kfree(runtime); 3980 /* Restore the substream direction */
3933 kfree(params); 3981 substream->stream = saved_stream;
3934 return ret; 3982 return ret;
3935} 3983}
3936 3984
@@ -4053,10 +4101,11 @@ outfree_w_param:
4053} 4101}
4054 4102
4055static struct snd_soc_dapm_widget * 4103static struct snd_soc_dapm_widget *
4056snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd, 4104snd_soc_dapm_new_dai(struct snd_soc_card *card,
4057 struct snd_soc_dapm_widget *source, 4105 struct snd_pcm_substream *substream,
4058 struct snd_soc_dapm_widget *sink) 4106 char *id)
4059{ 4107{
4108 struct snd_soc_pcm_runtime *rtd = substream->private_data;
4060 struct snd_soc_dapm_widget template; 4109 struct snd_soc_dapm_widget template;
4061 struct snd_soc_dapm_widget *w; 4110 struct snd_soc_dapm_widget *w;
4062 const char **w_param_text; 4111 const char **w_param_text;
@@ -4065,7 +4114,7 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
4065 int ret; 4114 int ret;
4066 4115
4067 link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s", 4116 link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s",
4068 source->name, sink->name); 4117 rtd->dai_link->name, id);
4069 if (!link_name) 4118 if (!link_name)
4070 return ERR_PTR(-ENOMEM); 4119 return ERR_PTR(-ENOMEM);
4071 4120
@@ -4075,7 +4124,7 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
4075 template.name = link_name; 4124 template.name = link_name;
4076 template.event = snd_soc_dai_link_event; 4125 template.event = snd_soc_dai_link_event;
4077 template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4126 template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
4078 SND_SOC_DAPM_PRE_PMD; 4127 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD;
4079 template.kcontrol_news = NULL; 4128 template.kcontrol_news = NULL;
4080 4129
4081 /* allocate memory for control, only in case of multiple configs */ 4130 /* allocate memory for control, only in case of multiple configs */
@@ -4110,7 +4159,7 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
4110 goto outfree_kcontrol_news; 4159 goto outfree_kcontrol_news;
4111 } 4160 }
4112 4161
4113 w->priv = rtd; 4162 w->priv = substream;
4114 4163
4115 return w; 4164 return w;
4116 4165
@@ -4232,6 +4281,8 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
4232 struct snd_soc_dai *codec_dai; 4281 struct snd_soc_dai *codec_dai;
4233 struct snd_soc_dapm_widget *playback = NULL, *capture = NULL; 4282 struct snd_soc_dapm_widget *playback = NULL, *capture = NULL;
4234 struct snd_soc_dapm_widget *codec, *playback_cpu, *capture_cpu; 4283 struct snd_soc_dapm_widget *codec, *playback_cpu, *capture_cpu;
4284 struct snd_pcm_substream *substream;
4285 struct snd_pcm_str *streams = rtd->pcm->streams;
4235 int i; 4286 int i;
4236 4287
4237 if (rtd->dai_link->params) { 4288 if (rtd->dai_link->params) {
@@ -4245,15 +4296,14 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
4245 } 4296 }
4246 4297
4247 for_each_rtd_codec_dai(rtd, i, codec_dai) { 4298 for_each_rtd_codec_dai(rtd, i, codec_dai) {
4248
4249 /* connect BE DAI playback if widgets are valid */ 4299 /* connect BE DAI playback if widgets are valid */
4250 codec = codec_dai->playback_widget; 4300 codec = codec_dai->playback_widget;
4251 4301
4252 if (playback_cpu && codec) { 4302 if (playback_cpu && codec) {
4253 if (!playback) { 4303 if (!playback) {
4254 playback = snd_soc_dapm_new_dai(card, rtd, 4304 substream = streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
4255 playback_cpu, 4305 playback = snd_soc_dapm_new_dai(card, substream,
4256 codec); 4306 "playback");
4257 if (IS_ERR(playback)) { 4307 if (IS_ERR(playback)) {
4258 dev_err(rtd->dev, 4308 dev_err(rtd->dev,
4259 "ASoC: Failed to create DAI %s: %ld\n", 4309 "ASoC: Failed to create DAI %s: %ld\n",
@@ -4281,9 +4331,9 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
4281 4331
4282 if (codec && capture_cpu) { 4332 if (codec && capture_cpu) {
4283 if (!capture) { 4333 if (!capture) {
4284 capture = snd_soc_dapm_new_dai(card, rtd, 4334 substream = streams[SNDRV_PCM_STREAM_CAPTURE].substream;
4285 codec, 4335 capture = snd_soc_dapm_new_dai(card, substream,
4286 capture_cpu); 4336 "capture");
4287 if (IS_ERR(capture)) { 4337 if (IS_ERR(capture)) {
4288 dev_err(rtd->dev, 4338 dev_err(rtd->dev,
4289 "ASoC: Failed to create DAI %s: %ld\n", 4339 "ASoC: Failed to create DAI %s: %ld\n",
@@ -4667,6 +4717,27 @@ void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
4667} 4717}
4668EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 4718EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
4669 4719
4720void snd_soc_dapm_init(struct snd_soc_dapm_context *dapm,
4721 struct snd_soc_card *card,
4722 struct snd_soc_component *component)
4723{
4724 dapm->card = card;
4725 dapm->component = component;
4726 dapm->bias_level = SND_SOC_BIAS_OFF;
4727
4728 if (component) {
4729 dapm->dev = component->dev;
4730 dapm->idle_bias_off = !component->driver->idle_bias_on,
4731 dapm->suspend_bias_off = component->driver->suspend_bias_off;
4732 } else {
4733 dapm->dev = card->dev;
4734 }
4735
4736 INIT_LIST_HEAD(&dapm->list);
4737 list_add(&dapm->list, &card->dapm_list);
4738}
4739EXPORT_SYMBOL_GPL(snd_soc_dapm_init);
4740
4670static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm) 4741static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm)
4671{ 4742{
4672 struct snd_soc_card *card = dapm->card; 4743 struct snd_soc_card *card = dapm->card;
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index c7b990abdbaa..a71d2340eb05 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -24,24 +24,6 @@ struct jack_gpio_tbl {
24}; 24};
25 25
26/** 26/**
27 * snd_soc_component_set_jack - configure component jack.
28 * @component: COMPONENTs
29 * @jack: structure to use for the jack
30 * @data: can be used if codec driver need extra data for configuring jack
31 *
32 * Configures and enables jack detection function.
33 */
34int snd_soc_component_set_jack(struct snd_soc_component *component,
35 struct snd_soc_jack *jack, void *data)
36{
37 if (component->driver->set_jack)
38 return component->driver->set_jack(component, jack, data);
39
40 return -ENOTSUPP;
41}
42EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
43
44/**
45 * snd_soc_card_jack_new - Create a new jack 27 * snd_soc_card_jack_new - Create a new jack
46 * @card: ASoC card 28 * @card: ASoC card
47 * @id: an identifying string for this jack 29 * @id: an identifying string for this jack
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 4878d22ebd8c..e163dde5eab1 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -15,7 +15,6 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/pinctrl/consumer.h> 16#include <linux/pinctrl/consumer.h>
17#include <linux/pm_runtime.h> 17#include <linux/pm_runtime.h>
18#include <linux/module.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
20#include <linux/workqueue.h> 19#include <linux/workqueue.h>
21#include <linux/export.h> 20#include <linux/export.h>
@@ -29,24 +28,6 @@
29 28
30#define DPCM_MAX_BE_USERS 8 29#define DPCM_MAX_BE_USERS 8
31 30
32/*
33 * snd_soc_dai_stream_valid() - check if a DAI supports the given stream
34 *
35 * Returns true if the DAI supports the indicated stream type.
36 */
37static bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream)
38{
39 struct snd_soc_pcm_stream *codec_stream;
40
41 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
42 codec_stream = &dai->driver->playback;
43 else
44 codec_stream = &dai->driver->capture;
45
46 /* If the codec specifies any channels at all, it supports the stream */
47 return codec_stream->channels_min;
48}
49
50/** 31/**
51 * snd_soc_runtime_activate() - Increment active count for PCM runtime components 32 * snd_soc_runtime_activate() - Increment active count for PCM runtime components
52 * @rtd: ASoC PCM runtime that is activated 33 * @rtd: ASoC PCM runtime that is activated
@@ -55,7 +36,7 @@ static bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream)
55 * Increments the active count for all the DAIs and components attached to a PCM 36 * Increments the active count for all the DAIs and components attached to a PCM
56 * runtime. Should typically be called when a stream is opened. 37 * runtime. Should typically be called when a stream is opened.
57 * 38 *
58 * Must be called with the rtd->pcm_mutex being held 39 * Must be called with the rtd->card->pcm_mutex being held
59 */ 40 */
60void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream) 41void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
61{ 42{
@@ -63,7 +44,7 @@ void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
63 struct snd_soc_dai *codec_dai; 44 struct snd_soc_dai *codec_dai;
64 int i; 45 int i;
65 46
66 lockdep_assert_held(&rtd->pcm_mutex); 47 lockdep_assert_held(&rtd->card->pcm_mutex);
67 48
68 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 49 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
69 cpu_dai->playback_active++; 50 cpu_dai->playback_active++;
@@ -91,7 +72,7 @@ void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
91 * Decrements the active count for all the DAIs and components attached to a PCM 72 * Decrements the active count for all the DAIs and components attached to a PCM
92 * runtime. Should typically be called when a stream is closed. 73 * runtime. Should typically be called when a stream is closed.
93 * 74 *
94 * Must be called with the rtd->pcm_mutex being held 75 * Must be called with the rtd->card->pcm_mutex being held
95 */ 76 */
96void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream) 77void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
97{ 78{
@@ -99,7 +80,7 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
99 struct snd_soc_dai *codec_dai; 80 struct snd_soc_dai *codec_dai;
100 int i; 81 int i;
101 82
102 lockdep_assert_held(&rtd->pcm_mutex); 83 lockdep_assert_held(&rtd->card->pcm_mutex);
103 84
104 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 85 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
105 cpu_dai->playback_active--; 86 cpu_dai->playback_active--;
@@ -458,19 +439,15 @@ static int soc_pcm_components_open(struct snd_pcm_substream *substream,
458 component = rtdcom->component; 439 component = rtdcom->component;
459 *last = component; 440 *last = component;
460 441
461 if (component->driver->module_get_upon_open && 442 ret = snd_soc_component_module_get_when_open(component);
462 !try_module_get(component->dev->driver->owner)) { 443 if (ret < 0) {
463 dev_err(component->dev, 444 dev_err(component->dev,
464 "ASoC: can't get module %s\n", 445 "ASoC: can't get module %s\n",
465 component->name); 446 component->name);
466 return -ENODEV; 447 return ret;
467 } 448 }
468 449
469 if (!component->driver->ops || 450 ret = snd_soc_component_open(component, substream);
470 !component->driver->ops->open)
471 continue;
472
473 ret = component->driver->ops->open(substream);
474 if (ret < 0) { 451 if (ret < 0) {
475 dev_err(component->dev, 452 dev_err(component->dev,
476 "ASoC: can't open component %s: %d\n", 453 "ASoC: can't open component %s: %d\n",
@@ -488,6 +465,7 @@ static int soc_pcm_components_close(struct snd_pcm_substream *substream,
488 struct snd_soc_pcm_runtime *rtd = substream->private_data; 465 struct snd_soc_pcm_runtime *rtd = substream->private_data;
489 struct snd_soc_rtdcom_list *rtdcom; 466 struct snd_soc_rtdcom_list *rtdcom;
490 struct snd_soc_component *component; 467 struct snd_soc_component *component;
468 int ret = 0;
491 469
492 for_each_rtdcom(rtd, rtdcom) { 470 for_each_rtdcom(rtd, rtdcom) {
493 component = rtdcom->component; 471 component = rtdcom->component;
@@ -495,15 +473,11 @@ static int soc_pcm_components_close(struct snd_pcm_substream *substream,
495 if (component == last) 473 if (component == last)
496 break; 474 break;
497 475
498 if (component->driver->ops && 476 ret |= snd_soc_component_close(component, substream);
499 component->driver->ops->close) 477 snd_soc_component_module_put_when_close(component);
500 component->driver->ops->close(substream);
501
502 if (component->driver->module_get_upon_open)
503 module_put(component->dev->driver->owner);
504 } 478 }
505 479
506 return 0; 480 return ret;
507} 481}
508 482
509/* 483/*
@@ -532,16 +506,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
532 pm_runtime_get_sync(component->dev); 506 pm_runtime_get_sync(component->dev);
533 } 507 }
534 508
535 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 509 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
536 510
537 /* startup the audio subsystem */ 511 /* startup the audio subsystem */
538 if (cpu_dai->driver->ops->startup) { 512 ret = snd_soc_dai_startup(cpu_dai, substream);
539 ret = cpu_dai->driver->ops->startup(substream, cpu_dai); 513 if (ret < 0) {
540 if (ret < 0) { 514 dev_err(cpu_dai->dev, "ASoC: can't open interface %s: %d\n",
541 dev_err(cpu_dai->dev, "ASoC: can't open interface" 515 cpu_dai->name, ret);
542 " %s: %d\n", cpu_dai->name, ret); 516 goto out;
543 goto out;
544 }
545 } 517 }
546 518
547 ret = soc_pcm_components_open(substream, &component); 519 ret = soc_pcm_components_open(substream, &component);
@@ -549,15 +521,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
549 goto component_err; 521 goto component_err;
550 522
551 for_each_rtd_codec_dai(rtd, i, codec_dai) { 523 for_each_rtd_codec_dai(rtd, i, codec_dai) {
552 if (codec_dai->driver->ops->startup) { 524 ret = snd_soc_dai_startup(codec_dai, substream);
553 ret = codec_dai->driver->ops->startup(substream, 525 if (ret < 0) {
554 codec_dai); 526 dev_err(codec_dai->dev,
555 if (ret < 0) { 527 "ASoC: can't open codec %s: %d\n",
556 dev_err(codec_dai->dev, 528 codec_dai->name, ret);
557 "ASoC: can't open codec %s: %d\n", 529 goto codec_dai_err;
558 codec_dai->name, ret);
559 goto codec_dai_err;
560 }
561 } 530 }
562 531
563 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 532 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -635,7 +604,7 @@ dynamic:
635 604
636 snd_soc_runtime_activate(rtd, substream->stream); 605 snd_soc_runtime_activate(rtd, substream->stream);
637 606
638 mutex_unlock(&rtd->pcm_mutex); 607 mutex_unlock(&rtd->card->pcm_mutex);
639 return 0; 608 return 0;
640 609
641config_err: 610config_err:
@@ -646,18 +615,15 @@ machine_err:
646 i = rtd->num_codecs; 615 i = rtd->num_codecs;
647 616
648codec_dai_err: 617codec_dai_err:
649 for_each_rtd_codec_dai_rollback(rtd, i, codec_dai) { 618 for_each_rtd_codec_dai_rollback(rtd, i, codec_dai)
650 if (codec_dai->driver->ops->shutdown) 619 snd_soc_dai_shutdown(codec_dai, substream);
651 codec_dai->driver->ops->shutdown(substream, codec_dai);
652 }
653 620
654component_err: 621component_err:
655 soc_pcm_components_close(substream, component); 622 soc_pcm_components_close(substream, component);
656 623
657 if (cpu_dai->driver->ops->shutdown) 624 snd_soc_dai_shutdown(cpu_dai, substream);
658 cpu_dai->driver->ops->shutdown(substream, cpu_dai);
659out: 625out:
660 mutex_unlock(&rtd->pcm_mutex); 626 mutex_unlock(&rtd->card->pcm_mutex);
661 627
662 for_each_rtdcom(rtd, rtdcom) { 628 for_each_rtdcom(rtd, rtdcom) {
663 component = rtdcom->component; 629 component = rtdcom->component;
@@ -687,7 +653,7 @@ static void close_delayed_work(struct work_struct *work)
687 container_of(work, struct snd_soc_pcm_runtime, delayed_work.work); 653 container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
688 struct snd_soc_dai *codec_dai = rtd->codec_dais[0]; 654 struct snd_soc_dai *codec_dai = rtd->codec_dais[0];
689 655
690 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 656 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
691 657
692 dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n", 658 dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n",
693 codec_dai->driver->playback.stream_name, 659 codec_dai->driver->playback.stream_name,
@@ -701,7 +667,17 @@ static void close_delayed_work(struct work_struct *work)
701 SND_SOC_DAPM_STREAM_STOP); 667 SND_SOC_DAPM_STREAM_STOP);
702 } 668 }
703 669
704 mutex_unlock(&rtd->pcm_mutex); 670 mutex_unlock(&rtd->card->pcm_mutex);
671}
672
673static void codec2codec_close_delayed_work(struct work_struct *work)
674{
675 /*
676 * Currently nothing to do for c2c links
677 * Since c2c links are internal nodes in the DAPM graph and
678 * don't interface with the outside world or application layer
679 * we don't have to do any special handling on close.
680 */
705} 681}
706 682
707/* 683/*
@@ -718,7 +694,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
718 struct snd_soc_dai *codec_dai; 694 struct snd_soc_dai *codec_dai;
719 int i; 695 int i;
720 696
721 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 697 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
722 698
723 snd_soc_runtime_deactivate(rtd, substream->stream); 699 snd_soc_runtime_deactivate(rtd, substream->stream);
724 700
@@ -733,13 +709,10 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
733 709
734 snd_soc_dai_digital_mute(cpu_dai, 1, substream->stream); 710 snd_soc_dai_digital_mute(cpu_dai, 1, substream->stream);
735 711
736 if (cpu_dai->driver->ops->shutdown) 712 snd_soc_dai_shutdown(cpu_dai, substream);
737 cpu_dai->driver->ops->shutdown(substream, cpu_dai);
738 713
739 for_each_rtd_codec_dai(rtd, i, codec_dai) { 714 for_each_rtd_codec_dai(rtd, i, codec_dai)
740 if (codec_dai->driver->ops->shutdown) 715 snd_soc_dai_shutdown(codec_dai, substream);
741 codec_dai->driver->ops->shutdown(substream, codec_dai);
742 }
743 716
744 if (rtd->dai_link->ops->shutdown) 717 if (rtd->dai_link->ops->shutdown)
745 rtd->dai_link->ops->shutdown(substream); 718 rtd->dai_link->ops->shutdown(substream);
@@ -765,7 +738,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
765 SND_SOC_DAPM_STREAM_STOP); 738 SND_SOC_DAPM_STREAM_STOP);
766 } 739 }
767 740
768 mutex_unlock(&rtd->pcm_mutex); 741 mutex_unlock(&rtd->card->pcm_mutex);
769 742
770 for_each_rtdcom(rtd, rtdcom) { 743 for_each_rtdcom(rtd, rtdcom) {
771 component = rtdcom->component; 744 component = rtdcom->component;
@@ -798,7 +771,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
798 struct snd_soc_dai *codec_dai; 771 struct snd_soc_dai *codec_dai;
799 int i, ret = 0; 772 int i, ret = 0;
800 773
801 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 774 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
802 775
803 if (rtd->dai_link->ops->prepare) { 776 if (rtd->dai_link->ops->prepare) {
804 ret = rtd->dai_link->ops->prepare(substream); 777 ret = rtd->dai_link->ops->prepare(substream);
@@ -812,11 +785,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
812 for_each_rtdcom(rtd, rtdcom) { 785 for_each_rtdcom(rtd, rtdcom) {
813 component = rtdcom->component; 786 component = rtdcom->component;
814 787
815 if (!component->driver->ops || 788 ret = snd_soc_component_prepare(component, substream);
816 !component->driver->ops->prepare)
817 continue;
818
819 ret = component->driver->ops->prepare(substream);
820 if (ret < 0) { 789 if (ret < 0) {
821 dev_err(component->dev, 790 dev_err(component->dev,
822 "ASoC: platform prepare error: %d\n", ret); 791 "ASoC: platform prepare error: %d\n", ret);
@@ -825,27 +794,22 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
825 } 794 }
826 795
827 for_each_rtd_codec_dai(rtd, i, codec_dai) { 796 for_each_rtd_codec_dai(rtd, i, codec_dai) {
828 if (codec_dai->driver->ops->prepare) { 797 ret = snd_soc_dai_prepare(codec_dai, substream);
829 ret = codec_dai->driver->ops->prepare(substream,
830 codec_dai);
831 if (ret < 0) {
832 dev_err(codec_dai->dev,
833 "ASoC: codec DAI prepare error: %d\n",
834 ret);
835 goto out;
836 }
837 }
838 }
839
840 if (cpu_dai->driver->ops->prepare) {
841 ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
842 if (ret < 0) { 798 if (ret < 0) {
843 dev_err(cpu_dai->dev, 799 dev_err(codec_dai->dev,
844 "ASoC: cpu DAI prepare error: %d\n", ret); 800 "ASoC: codec DAI prepare error: %d\n",
801 ret);
845 goto out; 802 goto out;
846 } 803 }
847 } 804 }
848 805
806 ret = snd_soc_dai_prepare(cpu_dai, substream);
807 if (ret < 0) {
808 dev_err(cpu_dai->dev,
809 "ASoC: cpu DAI prepare error: %d\n", ret);
810 goto out;
811 }
812
849 /* cancel any delayed stream shutdown that is pending */ 813 /* cancel any delayed stream shutdown that is pending */
850 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 814 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
851 rtd->pop_wait) { 815 rtd->pop_wait) {
@@ -862,7 +826,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
862 snd_soc_dai_digital_mute(cpu_dai, 0, substream->stream); 826 snd_soc_dai_digital_mute(cpu_dai, 0, substream->stream);
863 827
864out: 828out:
865 mutex_unlock(&rtd->pcm_mutex); 829 mutex_unlock(&rtd->card->pcm_mutex);
866 return ret; 830 return ret;
867} 831}
868 832
@@ -877,42 +841,13 @@ static void soc_pcm_codec_params_fixup(struct snd_pcm_hw_params *params,
877 interval->max = channels; 841 interval->max = channels;
878} 842}
879 843
880int soc_dai_hw_params(struct snd_pcm_substream *substream,
881 struct snd_pcm_hw_params *params,
882 struct snd_soc_dai *dai)
883{
884 struct snd_soc_pcm_runtime *rtd = substream->private_data;
885 int ret;
886
887 /* perform any topology hw_params fixups before DAI */
888 if (rtd->dai_link->be_hw_params_fixup) {
889 ret = rtd->dai_link->be_hw_params_fixup(rtd, params);
890 if (ret < 0) {
891 dev_err(rtd->dev,
892 "ASoC: hw_params topology fixup failed %d\n",
893 ret);
894 return ret;
895 }
896 }
897
898 if (dai->driver->ops->hw_params) {
899 ret = dai->driver->ops->hw_params(substream, params, dai);
900 if (ret < 0) {
901 dev_err(dai->dev, "ASoC: can't set %s hw params: %d\n",
902 dai->name, ret);
903 return ret;
904 }
905 }
906
907 return 0;
908}
909
910static int soc_pcm_components_hw_free(struct snd_pcm_substream *substream, 844static int soc_pcm_components_hw_free(struct snd_pcm_substream *substream,
911 struct snd_soc_component *last) 845 struct snd_soc_component *last)
912{ 846{
913 struct snd_soc_pcm_runtime *rtd = substream->private_data; 847 struct snd_soc_pcm_runtime *rtd = substream->private_data;
914 struct snd_soc_rtdcom_list *rtdcom; 848 struct snd_soc_rtdcom_list *rtdcom;
915 struct snd_soc_component *component; 849 struct snd_soc_component *component;
850 int ret = 0;
916 851
917 for_each_rtdcom(rtd, rtdcom) { 852 for_each_rtdcom(rtd, rtdcom) {
918 component = rtdcom->component; 853 component = rtdcom->component;
@@ -920,14 +855,10 @@ static int soc_pcm_components_hw_free(struct snd_pcm_substream *substream,
920 if (component == last) 855 if (component == last)
921 break; 856 break;
922 857
923 if (!component->driver->ops || 858 ret |= snd_soc_component_hw_free(component, substream);
924 !component->driver->ops->hw_free)
925 continue;
926
927 component->driver->ops->hw_free(substream);
928 } 859 }
929 860
930 return 0; 861 return ret;
931} 862}
932 863
933/* 864/*
@@ -945,7 +876,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
945 struct snd_soc_dai *codec_dai; 876 struct snd_soc_dai *codec_dai;
946 int i, ret = 0; 877 int i, ret = 0;
947 878
948 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 879 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
949 if (rtd->dai_link->ops->hw_params) { 880 if (rtd->dai_link->ops->hw_params) {
950 ret = rtd->dai_link->ops->hw_params(substream, params); 881 ret = rtd->dai_link->ops->hw_params(substream, params);
951 if (ret < 0) { 882 if (ret < 0) {
@@ -989,7 +920,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
989 soc_pcm_codec_params_fixup(&codec_params, 920 soc_pcm_codec_params_fixup(&codec_params,
990 codec_dai->rx_mask); 921 codec_dai->rx_mask);
991 922
992 ret = soc_dai_hw_params(substream, &codec_params, codec_dai); 923 ret = snd_soc_dai_hw_params(codec_dai, substream,
924 &codec_params);
993 if(ret < 0) 925 if(ret < 0)
994 goto codec_err; 926 goto codec_err;
995 927
@@ -1001,7 +933,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
1001 snd_soc_dapm_update_dai(substream, &codec_params, codec_dai); 933 snd_soc_dapm_update_dai(substream, &codec_params, codec_dai);
1002 } 934 }
1003 935
1004 ret = soc_dai_hw_params(substream, params, cpu_dai); 936 ret = snd_soc_dai_hw_params(cpu_dai, substream, params);
1005 if (ret < 0) 937 if (ret < 0)
1006 goto interface_err; 938 goto interface_err;
1007 939
@@ -1016,11 +948,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
1016 for_each_rtdcom(rtd, rtdcom) { 948 for_each_rtdcom(rtd, rtdcom) {
1017 component = rtdcom->component; 949 component = rtdcom->component;
1018 950
1019 if (!component->driver->ops || 951 ret = snd_soc_component_hw_params(component, substream, params);
1020 !component->driver->ops->hw_params)
1021 continue;
1022
1023 ret = component->driver->ops->hw_params(substream, params);
1024 if (ret < 0) { 952 if (ret < 0) {
1025 dev_err(component->dev, 953 dev_err(component->dev,
1026 "ASoC: %s hw params failed: %d\n", 954 "ASoC: %s hw params failed: %d\n",
@@ -1034,14 +962,13 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
1034 if (ret) 962 if (ret)
1035 goto component_err; 963 goto component_err;
1036out: 964out:
1037 mutex_unlock(&rtd->pcm_mutex); 965 mutex_unlock(&rtd->card->pcm_mutex);
1038 return ret; 966 return ret;
1039 967
1040component_err: 968component_err:
1041 soc_pcm_components_hw_free(substream, component); 969 soc_pcm_components_hw_free(substream, component);
1042 970
1043 if (cpu_dai->driver->ops->hw_free) 971 snd_soc_dai_hw_free(cpu_dai, substream);
1044 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
1045 cpu_dai->rate = 0; 972 cpu_dai->rate = 0;
1046 973
1047interface_err: 974interface_err:
@@ -1052,15 +979,14 @@ codec_err:
1052 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream)) 979 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
1053 continue; 980 continue;
1054 981
1055 if (codec_dai->driver->ops->hw_free) 982 snd_soc_dai_hw_free(codec_dai, substream);
1056 codec_dai->driver->ops->hw_free(substream, codec_dai);
1057 codec_dai->rate = 0; 983 codec_dai->rate = 0;
1058 } 984 }
1059 985
1060 if (rtd->dai_link->ops->hw_free) 986 if (rtd->dai_link->ops->hw_free)
1061 rtd->dai_link->ops->hw_free(substream); 987 rtd->dai_link->ops->hw_free(substream);
1062 988
1063 mutex_unlock(&rtd->pcm_mutex); 989 mutex_unlock(&rtd->card->pcm_mutex);
1064 return ret; 990 return ret;
1065} 991}
1066 992
@@ -1075,7 +1001,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
1075 bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 1001 bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
1076 int i; 1002 int i;
1077 1003
1078 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 1004 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
1079 1005
1080 /* clear the corresponding DAIs parameters when going to be inactive */ 1006 /* clear the corresponding DAIs parameters when going to be inactive */
1081 if (cpu_dai->active == 1) { 1007 if (cpu_dai->active == 1) {
@@ -1112,14 +1038,12 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
1112 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream)) 1038 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
1113 continue; 1039 continue;
1114 1040
1115 if (codec_dai->driver->ops->hw_free) 1041 snd_soc_dai_hw_free(codec_dai, substream);
1116 codec_dai->driver->ops->hw_free(substream, codec_dai);
1117 } 1042 }
1118 1043
1119 if (cpu_dai->driver->ops->hw_free) 1044 snd_soc_dai_hw_free(cpu_dai, substream);
1120 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
1121 1045
1122 mutex_unlock(&rtd->pcm_mutex); 1046 mutex_unlock(&rtd->card->pcm_mutex);
1123 return 0; 1047 return 0;
1124} 1048}
1125 1049
@@ -1133,31 +1057,22 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1133 int i, ret; 1057 int i, ret;
1134 1058
1135 for_each_rtd_codec_dai(rtd, i, codec_dai) { 1059 for_each_rtd_codec_dai(rtd, i, codec_dai) {
1136 if (codec_dai->driver->ops->trigger) { 1060 ret = snd_soc_dai_trigger(codec_dai, substream, cmd);
1137 ret = codec_dai->driver->ops->trigger(substream, 1061 if (ret < 0)
1138 cmd, codec_dai); 1062 return ret;
1139 if (ret < 0)
1140 return ret;
1141 }
1142 } 1063 }
1143 1064
1144 for_each_rtdcom(rtd, rtdcom) { 1065 for_each_rtdcom(rtd, rtdcom) {
1145 component = rtdcom->component; 1066 component = rtdcom->component;
1146 1067
1147 if (!component->driver->ops || 1068 ret = snd_soc_component_trigger(component, substream, cmd);
1148 !component->driver->ops->trigger)
1149 continue;
1150
1151 ret = component->driver->ops->trigger(substream, cmd);
1152 if (ret < 0) 1069 if (ret < 0)
1153 return ret; 1070 return ret;
1154 } 1071 }
1155 1072
1156 if (cpu_dai->driver->ops->trigger) { 1073 snd_soc_dai_trigger(cpu_dai, substream, cmd);
1157 ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai); 1074 if (ret < 0)
1158 if (ret < 0) 1075 return ret;
1159 return ret;
1160 }
1161 1076
1162 if (rtd->dai_link->ops->trigger) { 1077 if (rtd->dai_link->ops->trigger) {
1163 ret = rtd->dai_link->ops->trigger(substream, cmd); 1078 ret = rtd->dai_link->ops->trigger(substream, cmd);
@@ -1177,19 +1092,15 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
1177 int i, ret; 1092 int i, ret;
1178 1093
1179 for_each_rtd_codec_dai(rtd, i, codec_dai) { 1094 for_each_rtd_codec_dai(rtd, i, codec_dai) {
1180 if (codec_dai->driver->ops->bespoke_trigger) { 1095 ret = snd_soc_dai_bespoke_trigger(codec_dai, substream, cmd);
1181 ret = codec_dai->driver->ops->bespoke_trigger(substream,
1182 cmd, codec_dai);
1183 if (ret < 0)
1184 return ret;
1185 }
1186 }
1187
1188 if (cpu_dai->driver->ops->bespoke_trigger) {
1189 ret = cpu_dai->driver->ops->bespoke_trigger(substream, cmd, cpu_dai);
1190 if (ret < 0) 1096 if (ret < 0)
1191 return ret; 1097 return ret;
1192 } 1098 }
1099
1100 snd_soc_dai_bespoke_trigger(cpu_dai, substream, cmd);
1101 if (ret < 0)
1102 return ret;
1103
1193 return 0; 1104 return 0;
1194} 1105}
1195/* 1106/*
@@ -1200,8 +1111,6 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
1200static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) 1111static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
1201{ 1112{
1202 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1113 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1203 struct snd_soc_component *component;
1204 struct snd_soc_rtdcom_list *rtdcom;
1205 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1114 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1206 struct snd_soc_dai *codec_dai; 1115 struct snd_soc_dai *codec_dai;
1207 struct snd_pcm_runtime *runtime = substream->runtime; 1116 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -1213,28 +1122,16 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
1213 /* clearing the previous total delay */ 1122 /* clearing the previous total delay */
1214 runtime->delay = 0; 1123 runtime->delay = 0;
1215 1124
1216 for_each_rtdcom(rtd, rtdcom) { 1125 offset = snd_soc_pcm_component_pointer(substream);
1217 component = rtdcom->component;
1218
1219 if (!component->driver->ops ||
1220 !component->driver->ops->pointer)
1221 continue;
1222 1126
1223 /* FIXME: use 1st pointer */
1224 offset = component->driver->ops->pointer(substream);
1225 break;
1226 }
1227 /* base delay if assigned in pointer callback */ 1127 /* base delay if assigned in pointer callback */
1228 delay = runtime->delay; 1128 delay = runtime->delay;
1229 1129
1230 if (cpu_dai->driver->ops->delay) 1130 delay += snd_soc_dai_delay(cpu_dai, substream);
1231 delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
1232 1131
1233 for_each_rtd_codec_dai(rtd, i, codec_dai) { 1132 for_each_rtd_codec_dai(rtd, i, codec_dai) {
1234 if (codec_dai->driver->ops->delay) 1133 codec_delay = max(codec_delay,
1235 codec_delay = max(codec_delay, 1134 snd_soc_dai_delay(codec_dai, substream));
1236 codec_dai->driver->ops->delay(substream,
1237 codec_dai));
1238 } 1135 }
1239 delay += codec_delay; 1136 delay += codec_delay;
1240 1137
@@ -1274,9 +1171,9 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
1274 stream ? "<-" : "->", be->dai_link->name); 1171 stream ? "<-" : "->", be->dai_link->name);
1275 1172
1276#ifdef CONFIG_DEBUG_FS 1173#ifdef CONFIG_DEBUG_FS
1277 if (fe->debugfs_dpcm_root) 1174 dpcm->debugfs_state = debugfs_create_dir(be->dai_link->name,
1278 dpcm->debugfs_state = debugfs_create_u32(be->dai_link->name, 0644, 1175 fe->debugfs_dpcm_root);
1279 fe->debugfs_dpcm_root, &dpcm->state); 1176 debugfs_create_u32("state", 0644, dpcm->debugfs_state, &dpcm->state);
1280#endif 1177#endif
1281 return 1; 1178 return 1;
1282} 1179}
@@ -1331,7 +1228,7 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
1331 dpcm_be_reparent(fe, dpcm->be, stream); 1228 dpcm_be_reparent(fe, dpcm->be, stream);
1332 1229
1333#ifdef CONFIG_DEBUG_FS 1230#ifdef CONFIG_DEBUG_FS
1334 debugfs_remove(dpcm->debugfs_state); 1231 debugfs_remove_recursive(dpcm->debugfs_state);
1335#endif 1232#endif
1336 spin_lock_irqsave(&fe->card->dpcm_lock, flags); 1233 spin_lock_irqsave(&fe->card->dpcm_lock, flags);
1337 list_del(&dpcm->list_be); 1234 list_del(&dpcm->list_be);
@@ -2556,27 +2453,6 @@ out:
2556 return ret; 2453 return ret;
2557} 2454}
2558 2455
2559static int soc_pcm_ioctl(struct snd_pcm_substream *substream,
2560 unsigned int cmd, void *arg)
2561{
2562 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2563 struct snd_soc_component *component;
2564 struct snd_soc_rtdcom_list *rtdcom;
2565
2566 for_each_rtdcom(rtd, rtdcom) {
2567 component = rtdcom->component;
2568
2569 if (!component->driver->ops ||
2570 !component->driver->ops->ioctl)
2571 continue;
2572
2573 /* FIXME: use 1st ioctl */
2574 return component->driver->ops->ioctl(substream, cmd, arg);
2575 }
2576
2577 return snd_pcm_lib_ioctl(substream, cmd, arg);
2578}
2579
2580static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream) 2456static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
2581{ 2457{
2582 struct snd_pcm_substream *substream = 2458 struct snd_pcm_substream *substream =
@@ -2749,8 +2625,8 @@ static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new)
2749 new ? "new" : "old", fe->dai_link->name); 2625 new ? "new" : "old", fe->dai_link->name);
2750 2626
2751 /* skip if FE doesn't have playback capability */ 2627 /* skip if FE doesn't have playback capability */
2752 if (!fe->cpu_dai->driver->playback.channels_min || 2628 if (!snd_soc_dai_stream_valid(fe->cpu_dai, SNDRV_PCM_STREAM_PLAYBACK) ||
2753 !fe->codec_dai->driver->playback.channels_min) 2629 !snd_soc_dai_stream_valid(fe->codec_dai, SNDRV_PCM_STREAM_PLAYBACK))
2754 goto capture; 2630 goto capture;
2755 2631
2756 /* skip if FE isn't currently playing */ 2632 /* skip if FE isn't currently playing */
@@ -2780,8 +2656,8 @@ static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new)
2780 2656
2781capture: 2657capture:
2782 /* skip if FE doesn't have capture capability */ 2658 /* skip if FE doesn't have capture capability */
2783 if (!fe->cpu_dai->driver->capture.channels_min || 2659 if (!snd_soc_dai_stream_valid(fe->cpu_dai, SNDRV_PCM_STREAM_CAPTURE) ||
2784 !fe->codec_dai->driver->capture.channels_min) 2660 !snd_soc_dai_stream_valid(fe->codec_dai, SNDRV_PCM_STREAM_CAPTURE))
2785 return 0; 2661 return 0;
2786 2662
2787 /* skip if FE isn't currently capturing */ 2663 /* skip if FE isn't currently capturing */
@@ -2929,149 +2805,10 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
2929static void soc_pcm_private_free(struct snd_pcm *pcm) 2805static void soc_pcm_private_free(struct snd_pcm *pcm)
2930{ 2806{
2931 struct snd_soc_pcm_runtime *rtd = pcm->private_data; 2807 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
2932 struct snd_soc_rtdcom_list *rtdcom;
2933 struct snd_soc_component *component;
2934 2808
2935 /* need to sync the delayed work before releasing resources */ 2809 /* need to sync the delayed work before releasing resources */
2936 flush_delayed_work(&rtd->delayed_work); 2810 flush_delayed_work(&rtd->delayed_work);
2937 for_each_rtdcom(rtd, rtdcom) { 2811 snd_soc_pcm_component_free(pcm);
2938 component = rtdcom->component;
2939
2940 if (component->driver->pcm_free)
2941 component->driver->pcm_free(pcm);
2942 }
2943}
2944
2945static int soc_rtdcom_ack(struct snd_pcm_substream *substream)
2946{
2947 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2948 struct snd_soc_rtdcom_list *rtdcom;
2949 struct snd_soc_component *component;
2950
2951 for_each_rtdcom(rtd, rtdcom) {
2952 component = rtdcom->component;
2953
2954 if (!component->driver->ops ||
2955 !component->driver->ops->ack)
2956 continue;
2957
2958 /* FIXME. it returns 1st ask now */
2959 return component->driver->ops->ack(substream);
2960 }
2961
2962 return -EINVAL;
2963}
2964
2965static int soc_rtdcom_copy_user(struct snd_pcm_substream *substream, int channel,
2966 unsigned long pos, void __user *buf,
2967 unsigned long bytes)
2968{
2969 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2970 struct snd_soc_rtdcom_list *rtdcom;
2971 struct snd_soc_component *component;
2972
2973 for_each_rtdcom(rtd, rtdcom) {
2974 component = rtdcom->component;
2975
2976 if (!component->driver->ops ||
2977 !component->driver->ops->copy_user)
2978 continue;
2979
2980 /* FIXME. it returns 1st copy now */
2981 return component->driver->ops->copy_user(substream, channel,
2982 pos, buf, bytes);
2983 }
2984
2985 return -EINVAL;
2986}
2987
2988static int soc_rtdcom_copy_kernel(struct snd_pcm_substream *substream, int channel,
2989 unsigned long pos, void *buf, unsigned long bytes)
2990{
2991 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2992 struct snd_soc_rtdcom_list *rtdcom;
2993 struct snd_soc_component *component;
2994
2995 for_each_rtdcom(rtd, rtdcom) {
2996 component = rtdcom->component;
2997
2998 if (!component->driver->ops ||
2999 !component->driver->ops->copy_kernel)
3000 continue;
3001
3002 /* FIXME. it returns 1st copy now */
3003 return component->driver->ops->copy_kernel(substream, channel,
3004 pos, buf, bytes);
3005 }
3006
3007 return -EINVAL;
3008}
3009
3010static int soc_rtdcom_fill_silence(struct snd_pcm_substream *substream, int channel,
3011 unsigned long pos, unsigned long bytes)
3012{
3013 struct snd_soc_pcm_runtime *rtd = substream->private_data;
3014 struct snd_soc_rtdcom_list *rtdcom;
3015 struct snd_soc_component *component;
3016
3017 for_each_rtdcom(rtd, rtdcom) {
3018 component = rtdcom->component;
3019
3020 if (!component->driver->ops ||
3021 !component->driver->ops->fill_silence)
3022 continue;
3023
3024 /* FIXME. it returns 1st silence now */
3025 return component->driver->ops->fill_silence(substream, channel,
3026 pos, bytes);
3027 }
3028
3029 return -EINVAL;
3030}
3031
3032static struct page *soc_rtdcom_page(struct snd_pcm_substream *substream,
3033 unsigned long offset)
3034{
3035 struct snd_soc_pcm_runtime *rtd = substream->private_data;
3036 struct snd_soc_rtdcom_list *rtdcom;
3037 struct snd_soc_component *component;
3038 struct page *page;
3039
3040 for_each_rtdcom(rtd, rtdcom) {
3041 component = rtdcom->component;
3042
3043 if (!component->driver->ops ||
3044 !component->driver->ops->page)
3045 continue;
3046
3047 /* FIXME. it returns 1st page now */
3048 page = component->driver->ops->page(substream, offset);
3049 if (page)
3050 return page;
3051 }
3052
3053 return NULL;
3054}
3055
3056static int soc_rtdcom_mmap(struct snd_pcm_substream *substream,
3057 struct vm_area_struct *vma)
3058{
3059 struct snd_soc_pcm_runtime *rtd = substream->private_data;
3060 struct snd_soc_rtdcom_list *rtdcom;
3061 struct snd_soc_component *component;
3062
3063 for_each_rtdcom(rtd, rtdcom) {
3064 component = rtdcom->component;
3065
3066 if (!component->driver->ops ||
3067 !component->driver->ops->mmap)
3068 continue;
3069
3070 /* FIXME. it returns 1st mmap now */
3071 return component->driver->ops->mmap(substream, vma);
3072 }
3073
3074 return -EINVAL;
3075} 2812}
3076 2813
3077/* create a new pcm */ 2814/* create a new pcm */
@@ -3079,7 +2816,6 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
3079{ 2816{
3080 struct snd_soc_dai *codec_dai; 2817 struct snd_soc_dai *codec_dai;
3081 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 2818 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
3082 struct snd_soc_component *component;
3083 struct snd_soc_rtdcom_list *rtdcom; 2819 struct snd_soc_rtdcom_list *rtdcom;
3084 struct snd_pcm *pcm; 2820 struct snd_pcm *pcm;
3085 char new_name[64]; 2821 char new_name[64];
@@ -3090,15 +2826,23 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
3090 playback = rtd->dai_link->dpcm_playback; 2826 playback = rtd->dai_link->dpcm_playback;
3091 capture = rtd->dai_link->dpcm_capture; 2827 capture = rtd->dai_link->dpcm_capture;
3092 } else { 2828 } else {
2829 /* Adapt stream for codec2codec links */
2830 struct snd_soc_pcm_stream *cpu_capture = rtd->dai_link->params ?
2831 &cpu_dai->driver->playback : &cpu_dai->driver->capture;
2832 struct snd_soc_pcm_stream *cpu_playback = rtd->dai_link->params ?
2833 &cpu_dai->driver->capture : &cpu_dai->driver->playback;
2834
3093 for_each_rtd_codec_dai(rtd, i, codec_dai) { 2835 for_each_rtd_codec_dai(rtd, i, codec_dai) {
3094 if (codec_dai->driver->playback.channels_min) 2836 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
2837 snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
3095 playback = 1; 2838 playback = 1;
3096 if (codec_dai->driver->capture.channels_min) 2839 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
2840 snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
3097 capture = 1; 2841 capture = 1;
3098 } 2842 }
3099 2843
3100 capture = capture && cpu_dai->driver->capture.channels_min; 2844 capture = capture && cpu_capture->channels_min;
3101 playback = playback && cpu_dai->driver->playback.channels_min; 2845 playback = playback && cpu_playback->channels_min;
3102 } 2846 }
3103 2847
3104 if (rtd->dai_link->playback_only) { 2848 if (rtd->dai_link->playback_only) {
@@ -3112,7 +2856,13 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
3112 } 2856 }
3113 2857
3114 /* create the PCM */ 2858 /* create the PCM */
3115 if (rtd->dai_link->no_pcm) { 2859 if (rtd->dai_link->params) {
2860 snprintf(new_name, sizeof(new_name), "codec2codec(%s)",
2861 rtd->dai_link->stream_name);
2862
2863 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
2864 playback, capture, &pcm);
2865 } else if (rtd->dai_link->no_pcm) {
3116 snprintf(new_name, sizeof(new_name), "(%s)", 2866 snprintf(new_name, sizeof(new_name), "(%s)",
3117 rtd->dai_link->stream_name); 2867 rtd->dai_link->stream_name);
3118 2868
@@ -3139,13 +2889,17 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
3139 dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name); 2889 dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name);
3140 2890
3141 /* DAPM dai link stream work */ 2891 /* DAPM dai link stream work */
3142 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); 2892 if (rtd->dai_link->params)
2893 INIT_DELAYED_WORK(&rtd->delayed_work,
2894 codec2codec_close_delayed_work);
2895 else
2896 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
3143 2897
3144 pcm->nonatomic = rtd->dai_link->nonatomic; 2898 pcm->nonatomic = rtd->dai_link->nonatomic;
3145 rtd->pcm = pcm; 2899 rtd->pcm = pcm;
3146 pcm->private_data = rtd; 2900 pcm->private_data = rtd;
3147 2901
3148 if (rtd->dai_link->no_pcm) { 2902 if (rtd->dai_link->no_pcm || rtd->dai_link->params) {
3149 if (playback) 2903 if (playback)
3150 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; 2904 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
3151 if (capture) 2905 if (capture)
@@ -3162,7 +2916,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
3162 rtd->ops.hw_free = dpcm_fe_dai_hw_free; 2916 rtd->ops.hw_free = dpcm_fe_dai_hw_free;
3163 rtd->ops.close = dpcm_fe_dai_close; 2917 rtd->ops.close = dpcm_fe_dai_close;
3164 rtd->ops.pointer = soc_pcm_pointer; 2918 rtd->ops.pointer = soc_pcm_pointer;
3165 rtd->ops.ioctl = soc_pcm_ioctl; 2919 rtd->ops.ioctl = snd_soc_pcm_component_ioctl;
3166 } else { 2920 } else {
3167 rtd->ops.open = soc_pcm_open; 2921 rtd->ops.open = soc_pcm_open;
3168 rtd->ops.hw_params = soc_pcm_hw_params; 2922 rtd->ops.hw_params = soc_pcm_hw_params;
@@ -3171,7 +2925,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
3171 rtd->ops.hw_free = soc_pcm_hw_free; 2925 rtd->ops.hw_free = soc_pcm_hw_free;
3172 rtd->ops.close = soc_pcm_close; 2926 rtd->ops.close = soc_pcm_close;
3173 rtd->ops.pointer = soc_pcm_pointer; 2927 rtd->ops.pointer = soc_pcm_pointer;
3174 rtd->ops.ioctl = soc_pcm_ioctl; 2928 rtd->ops.ioctl = snd_soc_pcm_component_ioctl;
3175 } 2929 }
3176 2930
3177 for_each_rtdcom(rtd, rtdcom) { 2931 for_each_rtdcom(rtd, rtdcom) {
@@ -3180,18 +2934,12 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
3180 if (!ops) 2934 if (!ops)
3181 continue; 2935 continue;
3182 2936
3183 if (ops->ack)
3184 rtd->ops.ack = soc_rtdcom_ack;
3185 if (ops->copy_user) 2937 if (ops->copy_user)
3186 rtd->ops.copy_user = soc_rtdcom_copy_user; 2938 rtd->ops.copy_user = snd_soc_pcm_component_copy_user;
3187 if (ops->copy_kernel)
3188 rtd->ops.copy_kernel = soc_rtdcom_copy_kernel;
3189 if (ops->fill_silence)
3190 rtd->ops.fill_silence = soc_rtdcom_fill_silence;
3191 if (ops->page) 2939 if (ops->page)
3192 rtd->ops.page = soc_rtdcom_page; 2940 rtd->ops.page = snd_soc_pcm_component_page;
3193 if (ops->mmap) 2941 if (ops->mmap)
3194 rtd->ops.mmap = soc_rtdcom_mmap; 2942 rtd->ops.mmap = snd_soc_pcm_component_mmap;
3195 } 2943 }
3196 2944
3197 if (playback) 2945 if (playback)
@@ -3200,19 +2948,10 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
3200 if (capture) 2948 if (capture)
3201 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops); 2949 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
3202 2950
3203 for_each_rtdcom(rtd, rtdcom) { 2951 ret = snd_soc_pcm_component_new(pcm);
3204 component = rtdcom->component; 2952 if (ret < 0) {
3205 2953 dev_err(rtd->dev, "ASoC: pcm constructor failed: %d\n", ret);
3206 if (!component->driver->pcm_new) 2954 return ret;
3207 continue;
3208
3209 ret = component->driver->pcm_new(rtd);
3210 if (ret < 0) {
3211 dev_err(component->dev,
3212 "ASoC: pcm constructor failed: %d\n",
3213 ret);
3214 return ret;
3215 }
3216 } 2955 }
3217 2956
3218 pcm->private_free = soc_pcm_private_free; 2957 pcm->private_free = soc_pcm_private_free;
@@ -3436,11 +3175,11 @@ static ssize_t dpcm_state_read_file(struct file *file, char __user *user_buf,
3436 if (!buf) 3175 if (!buf)
3437 return -ENOMEM; 3176 return -ENOMEM;
3438 3177
3439 if (fe->cpu_dai->driver->playback.channels_min) 3178 if (snd_soc_dai_stream_valid(fe->cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
3440 offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_PLAYBACK, 3179 offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_PLAYBACK,
3441 buf + offset, out_count - offset); 3180 buf + offset, out_count - offset);
3442 3181
3443 if (fe->cpu_dai->driver->capture.channels_min) 3182 if (snd_soc_dai_stream_valid(fe->cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
3444 offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_CAPTURE, 3183 offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_CAPTURE,
3445 buf + offset, out_count - offset); 3184 buf + offset, out_count - offset);
3446 3185
@@ -3461,17 +3200,14 @@ void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
3461 if (!rtd->dai_link) 3200 if (!rtd->dai_link)
3462 return; 3201 return;
3463 3202
3203 if (!rtd->dai_link->dynamic)
3204 return;
3205
3464 if (!rtd->card->debugfs_card_root) 3206 if (!rtd->card->debugfs_card_root)
3465 return; 3207 return;
3466 3208
3467 rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name, 3209 rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name,
3468 rtd->card->debugfs_card_root); 3210 rtd->card->debugfs_card_root);
3469 if (!rtd->debugfs_dpcm_root) {
3470 dev_dbg(rtd->dev,
3471 "ASoC: Failed to create dpcm debugfs directory %s\n",
3472 rtd->dai_link->name);
3473 return;
3474 }
3475 3211
3476 debugfs_create_file("state", 0444, rtd->debugfs_dpcm_root, 3212 debugfs_create_file("state", 0444, rtd->debugfs_dpcm_root,
3477 rtd, &dpcm_state_fops); 3213 rtd, &dpcm_state_fops);
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index 2eca85c04a3e..aa9a1fca46fa 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -524,7 +524,7 @@ static void remove_dai(struct snd_soc_component *comp,
524 if (dobj->ops && dobj->ops->dai_unload) 524 if (dobj->ops && dobj->ops->dai_unload)
525 dobj->ops->dai_unload(comp, dobj); 525 dobj->ops->dai_unload(comp, dobj);
526 526
527 list_for_each_entry(dai, &comp->dai_list, list) 527 for_each_component_dais(comp, dai)
528 if (dai->driver == dai_drv) 528 if (dai->driver == dai_drv)
529 dai->driver = NULL; 529 dai->driver = NULL;
530 530
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index e3b9dd634c6d..54dcece52b0c 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -52,205 +52,6 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params)
52} 52}
53EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); 53EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk);
54 54
55int snd_soc_component_enable_pin(struct snd_soc_component *component,
56 const char *pin)
57{
58 struct snd_soc_dapm_context *dapm =
59 snd_soc_component_get_dapm(component);
60 char *full_name;
61 int ret;
62
63 if (!component->name_prefix)
64 return snd_soc_dapm_enable_pin(dapm, pin);
65
66 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
67 if (!full_name)
68 return -ENOMEM;
69
70 ret = snd_soc_dapm_enable_pin(dapm, full_name);
71 kfree(full_name);
72
73 return ret;
74}
75EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
76
77int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
78 const char *pin)
79{
80 struct snd_soc_dapm_context *dapm =
81 snd_soc_component_get_dapm(component);
82 char *full_name;
83 int ret;
84
85 if (!component->name_prefix)
86 return snd_soc_dapm_enable_pin_unlocked(dapm, pin);
87
88 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
89 if (!full_name)
90 return -ENOMEM;
91
92 ret = snd_soc_dapm_enable_pin_unlocked(dapm, full_name);
93 kfree(full_name);
94
95 return ret;
96}
97EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
98
99int snd_soc_component_disable_pin(struct snd_soc_component *component,
100 const char *pin)
101{
102 struct snd_soc_dapm_context *dapm =
103 snd_soc_component_get_dapm(component);
104 char *full_name;
105 int ret;
106
107 if (!component->name_prefix)
108 return snd_soc_dapm_disable_pin(dapm, pin);
109
110 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
111 if (!full_name)
112 return -ENOMEM;
113
114 ret = snd_soc_dapm_disable_pin(dapm, full_name);
115 kfree(full_name);
116
117 return ret;
118}
119EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
120
121int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
122 const char *pin)
123{
124 struct snd_soc_dapm_context *dapm =
125 snd_soc_component_get_dapm(component);
126 char *full_name;
127 int ret;
128
129 if (!component->name_prefix)
130 return snd_soc_dapm_disable_pin_unlocked(dapm, pin);
131
132 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
133 if (!full_name)
134 return -ENOMEM;
135
136 ret = snd_soc_dapm_disable_pin_unlocked(dapm, full_name);
137 kfree(full_name);
138
139 return ret;
140}
141EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
142
143int snd_soc_component_nc_pin(struct snd_soc_component *component,
144 const char *pin)
145{
146 struct snd_soc_dapm_context *dapm =
147 snd_soc_component_get_dapm(component);
148 char *full_name;
149 int ret;
150
151 if (!component->name_prefix)
152 return snd_soc_dapm_nc_pin(dapm, pin);
153
154 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
155 if (!full_name)
156 return -ENOMEM;
157
158 ret = snd_soc_dapm_nc_pin(dapm, full_name);
159 kfree(full_name);
160
161 return ret;
162}
163EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
164
165int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
166 const char *pin)
167{
168 struct snd_soc_dapm_context *dapm =
169 snd_soc_component_get_dapm(component);
170 char *full_name;
171 int ret;
172
173 if (!component->name_prefix)
174 return snd_soc_dapm_nc_pin_unlocked(dapm, pin);
175
176 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
177 if (!full_name)
178 return -ENOMEM;
179
180 ret = snd_soc_dapm_nc_pin_unlocked(dapm, full_name);
181 kfree(full_name);
182
183 return ret;
184}
185EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
186
187int snd_soc_component_get_pin_status(struct snd_soc_component *component,
188 const char *pin)
189{
190 struct snd_soc_dapm_context *dapm =
191 snd_soc_component_get_dapm(component);
192 char *full_name;
193 int ret;
194
195 if (!component->name_prefix)
196 return snd_soc_dapm_get_pin_status(dapm, pin);
197
198 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
199 if (!full_name)
200 return -ENOMEM;
201
202 ret = snd_soc_dapm_get_pin_status(dapm, full_name);
203 kfree(full_name);
204
205 return ret;
206}
207EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
208
209int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
210 const char *pin)
211{
212 struct snd_soc_dapm_context *dapm =
213 snd_soc_component_get_dapm(component);
214 char *full_name;
215 int ret;
216
217 if (!component->name_prefix)
218 return snd_soc_dapm_force_enable_pin(dapm, pin);
219
220 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
221 if (!full_name)
222 return -ENOMEM;
223
224 ret = snd_soc_dapm_force_enable_pin(dapm, full_name);
225 kfree(full_name);
226
227 return ret;
228}
229EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
230
231int snd_soc_component_force_enable_pin_unlocked(
232 struct snd_soc_component *component,
233 const char *pin)
234{
235 struct snd_soc_dapm_context *dapm =
236 snd_soc_component_get_dapm(component);
237 char *full_name;
238 int ret;
239
240 if (!component->name_prefix)
241 return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
242
243 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
244 if (!full_name)
245 return -ENOMEM;
246
247 ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, full_name);
248 kfree(full_name);
249
250 return ret;
251}
252EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
253
254static const struct snd_pcm_hardware dummy_dma_hardware = { 55static const struct snd_pcm_hardware dummy_dma_hardware = {
255 /* Random values to keep userspace happy when checking constraints */ 56 /* Random values to keep userspace happy when checking constraints */
256 .info = SNDRV_PCM_INFO_INTERLEAVED | 57 .info = SNDRV_PCM_INFO_INTERLEAVED |
diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig
index fb01f0ca6027..bb8036ae567e 100644
--- a/sound/soc/sof/Kconfig
+++ b/sound/soc/sof/Kconfig
@@ -36,6 +36,16 @@ config SND_SOC_SOF_ACPI
36 Say Y if you need this option 36 Say Y if you need this option
37 If unsure select "N". 37 If unsure select "N".
38 38
39config SND_SOC_SOF_OF
40 tristate "SOF OF enumeration support"
41 depends on OF || COMPILE_TEST
42 select SND_SOC_SOF
43 select SND_SOC_SOF_OPTIONS
44 help
45 This adds support for Device Tree enumeration. This option is
46 required to enable i.MX8 devices.
47 Say Y if you need this option. If unsure select "N".
48
39config SND_SOC_SOF_OPTIONS 49config SND_SOC_SOF_OPTIONS
40 tristate 50 tristate
41 help 51 help
@@ -163,6 +173,7 @@ config SND_SOC_SOF_PROBE_WORK_QUEUE
163 When selected, the probe is handled in two steps, for example to 173 When selected, the probe is handled in two steps, for example to
164 avoid lockdeps if request_module is used in the probe. 174 avoid lockdeps if request_module is used in the probe.
165 175
176source "sound/soc/sof/imx/Kconfig"
166source "sound/soc/sof/intel/Kconfig" 177source "sound/soc/sof/intel/Kconfig"
167source "sound/soc/sof/xtensa/Kconfig" 178source "sound/soc/sof/xtensa/Kconfig"
168 179
diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile
index 8f14c9d2950b..b0a6f01bdc44 100644
--- a/sound/soc/sof/Makefile
+++ b/sound/soc/sof/Makefile
@@ -5,14 +5,18 @@ snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\
5 5
6snd-sof-pci-objs := sof-pci-dev.o 6snd-sof-pci-objs := sof-pci-dev.o
7snd-sof-acpi-objs := sof-acpi-dev.o 7snd-sof-acpi-objs := sof-acpi-dev.o
8snd-sof-of-objs := sof-of-dev.o
9
8snd-sof-nocodec-objs := nocodec.o 10snd-sof-nocodec-objs := nocodec.o
9 11
10obj-$(CONFIG_SND_SOC_SOF) += snd-sof.o 12obj-$(CONFIG_SND_SOC_SOF) += snd-sof.o
11obj-$(CONFIG_SND_SOC_SOF_NOCODEC) += snd-sof-nocodec.o 13obj-$(CONFIG_SND_SOC_SOF_NOCODEC) += snd-sof-nocodec.o
12 14
13 15
14obj-$(CONFIG_SND_SOC_SOF_ACPI) += sof-acpi-dev.o 16obj-$(CONFIG_SND_SOC_SOF_ACPI) += snd-sof-acpi.o
15obj-$(CONFIG_SND_SOC_SOF_PCI) += sof-pci-dev.o 17obj-$(CONFIG_SND_SOC_SOF_OF) += snd-sof-of.o
18obj-$(CONFIG_SND_SOC_SOF_PCI) += snd-sof-pci.o
16 19
17obj-$(CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL) += intel/ 20obj-$(CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL) += intel/
21obj-$(CONFIG_SND_SOC_SOF_IMX_TOPLEVEL) += imx/
18obj-$(CONFIG_SND_SOC_SOF_XTENSA) += xtensa/ 22obj-$(CONFIG_SND_SOC_SOF_XTENSA) += xtensa/
diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c
index 5beda47cdf9f..81f28f7ff1a0 100644
--- a/sound/soc/sof/core.c
+++ b/sound/soc/sof/core.c
@@ -17,8 +17,8 @@
17#include "ops.h" 17#include "ops.h"
18 18
19/* SOF defaults if not provided by the platform in ms */ 19/* SOF defaults if not provided by the platform in ms */
20#define TIMEOUT_DEFAULT_IPC_MS 5 20#define TIMEOUT_DEFAULT_IPC_MS 500
21#define TIMEOUT_DEFAULT_BOOT_MS 100 21#define TIMEOUT_DEFAULT_BOOT_MS 2000
22 22
23/* 23/*
24 * Generic object lookup APIs. 24 * Generic object lookup APIs.
diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c
index 2388477a965e..54cd431faab7 100644
--- a/sound/soc/sof/debug.c
+++ b/sound/soc/sof/debug.c
@@ -128,6 +128,7 @@ static ssize_t sof_dfsentry_write(struct file *file, const char __user *buffer,
128 unsigned long ipc_duration_ms = 0; 128 unsigned long ipc_duration_ms = 0;
129 bool flood_duration_test = false; 129 bool flood_duration_test = false;
130 unsigned long ipc_count = 0; 130 unsigned long ipc_count = 0;
131 struct dentry *dentry;
131 int err; 132 int err;
132#endif 133#endif
133 size_t size; 134 size_t size;
@@ -149,11 +150,12 @@ static ssize_t sof_dfsentry_write(struct file *file, const char __user *buffer,
149 * ipc_duration_ms test floods the DSP for the time specified 150 * ipc_duration_ms test floods the DSP for the time specified
150 * in the debugfs entry. 151 * in the debugfs entry.
151 */ 152 */
152 if (strcmp(dfse->dfsentry->d_name.name, "ipc_flood_count") && 153 dentry = file->f_path.dentry;
153 strcmp(dfse->dfsentry->d_name.name, "ipc_flood_duration_ms")) 154 if (strcmp(dentry->d_name.name, "ipc_flood_count") &&
155 strcmp(dentry->d_name.name, "ipc_flood_duration_ms"))
154 return -EINVAL; 156 return -EINVAL;
155 157
156 if (!strcmp(dfse->dfsentry->d_name.name, "ipc_flood_duration_ms")) 158 if (!strcmp(dentry->d_name.name, "ipc_flood_duration_ms"))
157 flood_duration_test = true; 159 flood_duration_test = true;
158 160
159 /* test completion criterion */ 161 /* test completion criterion */
@@ -226,8 +228,11 @@ static ssize_t sof_dfsentry_read(struct file *file, char __user *buffer,
226 u8 *buf; 228 u8 *buf;
227 229
228#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST) 230#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST)
229 if ((!strcmp(dfse->dfsentry->d_name.name, "ipc_flood_count") || 231 struct dentry *dentry;
230 !strcmp(dfse->dfsentry->d_name.name, "ipc_flood_duration_ms")) && 232
233 dentry = file->f_path.dentry;
234 if ((!strcmp(dentry->d_name.name, "ipc_flood_count") ||
235 !strcmp(dentry->d_name.name, "ipc_flood_duration_ms")) &&
231 dfse->cache_buf) { 236 dfse->cache_buf) {
232 if (*ppos) 237 if (*ppos)
233 return 0; 238 return 0;
@@ -290,8 +295,7 @@ static ssize_t sof_dfsentry_read(struct file *file, char __user *buffer,
290 if (!pm_runtime_active(sdev->dev) && 295 if (!pm_runtime_active(sdev->dev) &&
291 dfse->access_type == SOF_DEBUGFS_ACCESS_D0_ONLY) { 296 dfse->access_type == SOF_DEBUGFS_ACCESS_D0_ONLY) {
292 dev_err(sdev->dev, 297 dev_err(sdev->dev,
293 "error: debugfs entry %s cannot be read in DSP D3\n", 298 "error: debugfs entry cannot be read in DSP D3\n");
294 dfse->dfsentry->d_name.name);
295 kfree(buf); 299 kfree(buf);
296 return -EINVAL; 300 return -EINVAL;
297 } 301 }
@@ -356,17 +360,11 @@ int snd_sof_debugfs_io_item(struct snd_sof_dev *sdev,
356 } 360 }
357#endif 361#endif
358 362
359 dfse->dfsentry = debugfs_create_file(name, 0444, sdev->debugfs_root, 363 debugfs_create_file(name, 0444, sdev->debugfs_root, dfse,
360 dfse, &sof_dfs_fops); 364 &sof_dfs_fops);
361 if (!dfse->dfsentry) {
362 /* can't rely on debugfs, only log error and keep going */
363 dev_err(sdev->dev, "error: cannot create debugfs entry %s\n",
364 name);
365 } else {
366 /* add to dfsentry list */
367 list_add(&dfse->list, &sdev->dfsentry_list);
368 365
369 } 366 /* add to dfsentry list */
367 list_add(&dfse->list, &sdev->dfsentry_list);
370 368
371 return 0; 369 return 0;
372} 370}
@@ -402,16 +400,10 @@ int snd_sof_debugfs_buf_item(struct snd_sof_dev *sdev,
402 return -ENOMEM; 400 return -ENOMEM;
403#endif 401#endif
404 402
405 dfse->dfsentry = debugfs_create_file(name, mode, sdev->debugfs_root, 403 debugfs_create_file(name, mode, sdev->debugfs_root, dfse,
406 dfse, &sof_dfs_fops); 404 &sof_dfs_fops);
407 if (!dfse->dfsentry) { 405 /* add to dfsentry list */
408 /* can't rely on debugfs, only log error and keep going */ 406 list_add(&dfse->list, &sdev->dfsentry_list);
409 dev_err(sdev->dev, "error: cannot create debugfs entry %s\n",
410 name);
411 } else {
412 /* add to dfsentry list */
413 list_add(&dfse->list, &sdev->dfsentry_list);
414 }
415 407
416 return 0; 408 return 0;
417} 409}
@@ -426,10 +418,6 @@ int snd_sof_dbg_init(struct snd_sof_dev *sdev)
426 418
427 /* use "sof" as top level debugFS dir */ 419 /* use "sof" as top level debugFS dir */
428 sdev->debugfs_root = debugfs_create_dir("sof", NULL); 420 sdev->debugfs_root = debugfs_create_dir("sof", NULL);
429 if (IS_ERR_OR_NULL(sdev->debugfs_root)) {
430 dev_err(sdev->dev, "error: failed to create debugfs directory\n");
431 return 0;
432 }
433 421
434 /* init dfsentry list */ 422 /* init dfsentry list */
435 INIT_LIST_HEAD(&sdev->dfsentry_list); 423 INIT_LIST_HEAD(&sdev->dfsentry_list);
diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig
new file mode 100644
index 000000000000..5acae75f5750
--- /dev/null
+++ b/sound/soc/sof/imx/Kconfig
@@ -0,0 +1,23 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2
3config SND_SOC_SOF_IMX_TOPLEVEL
4 bool "SOF support for NXP i.MX audio DSPs"
5 depends on ARM64|| COMPILE_TEST
6 depends on SND_SOC_SOF_OF
7 help
8 This adds support for Sound Open Firmware for NXP i.MX platforms.
9 Say Y if you have such a device.
10 If unsure select "N".
11
12if SND_SOC_SOF_IMX_TOPLEVEL
13
14config SND_SOC_SOF_IMX8
15 tristate "SOF support for i.MX8"
16 depends on IMX_SCU
17 depends on IMX_DSP
18 help
19 This adds support for Sound Open Firmware for NXP i.MX8 platforms
20 Say Y if you have such a device.
21 If unsure select "N".
22
23endif ## SND_SOC_SOF_IMX_IMX_TOPLEVEL
diff --git a/sound/soc/sof/imx/Makefile b/sound/soc/sof/imx/Makefile
new file mode 100644
index 000000000000..6ef908e8c807
--- /dev/null
+++ b/sound/soc/sof/imx/Makefile
@@ -0,0 +1,4 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2snd-sof-imx8-objs := imx8.o
3
4obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o
diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c
new file mode 100644
index 000000000000..2a22b18e5ec0
--- /dev/null
+++ b/sound/soc/sof/imx/imx8.c
@@ -0,0 +1,394 @@
1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2//
3// Copyright 2019 NXP
4//
5// Author: Daniel Baluta <daniel.baluta@nxp.com>
6//
7// Hardware interface for audio DSP on i.MX8
8
9#include <linux/firmware.h>
10#include <linux/of_platform.h>
11#include <linux/of_address.h>
12#include <linux/of_irq.h>
13#include <linux/pm_domain.h>
14
15#include <linux/module.h>
16#include <sound/sof.h>
17#include <sound/sof/xtensa.h>
18#include <linux/firmware/imx/ipc.h>
19#include <linux/firmware/imx/dsp.h>
20
21#include <linux/firmware/imx/svc/misc.h>
22#include <dt-bindings/firmware/imx/rsrc.h>
23#include "../ops.h"
24
25/* DSP memories */
26#define IRAM_OFFSET 0x10000
27#define IRAM_SIZE (2 * 1024)
28#define DRAM0_OFFSET 0x0
29#define DRAM0_SIZE (32 * 1024)
30#define DRAM1_OFFSET 0x8000
31#define DRAM1_SIZE (32 * 1024)
32#define SYSRAM_OFFSET 0x18000
33#define SYSRAM_SIZE (256 * 1024)
34#define SYSROM_OFFSET 0x58000
35#define SYSROM_SIZE (192 * 1024)
36
37#define RESET_VECTOR_VADDR 0x596f8000
38
39#define MBOX_OFFSET 0x800000
40#define MBOX_SIZE 0x1000
41
42struct imx8_priv {
43 struct device *dev;
44 struct snd_sof_dev *sdev;
45
46 /* DSP IPC handler */
47 struct imx_dsp_ipc *dsp_ipc;
48 struct platform_device *ipc_dev;
49
50 /* System Controller IPC handler */
51 struct imx_sc_ipc *sc_ipc;
52
53 /* Power domain handling */
54 int num_domains;
55 struct device **pd_dev;
56 struct device_link **link;
57
58};
59
60static void imx8_get_reply(struct snd_sof_dev *sdev)
61{
62 struct snd_sof_ipc_msg *msg = sdev->msg;
63 struct sof_ipc_reply reply;
64 int ret = 0;
65
66 if (!msg) {
67 dev_warn(sdev->dev, "unexpected ipc interrupt\n");
68 return;
69 }
70
71 /* get reply */
72 sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
73
74 if (reply.error < 0) {
75 memcpy(msg->reply_data, &reply, sizeof(reply));
76 ret = reply.error;
77 } else {
78 /* reply has correct size? */
79 if (reply.hdr.size != msg->reply_size) {
80 dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
81 msg->reply_size, reply.hdr.size);
82 ret = -EINVAL;
83 }
84
85 /* read the message */
86 if (msg->reply_size > 0)
87 sof_mailbox_read(sdev, sdev->host_box.offset,
88 msg->reply_data, msg->reply_size);
89 }
90
91 msg->reply_error = ret;
92}
93
94static int imx8_get_mailbox_offset(struct snd_sof_dev *sdev)
95{
96 return MBOX_OFFSET;
97}
98
99static int imx8_get_window_offset(struct snd_sof_dev *sdev, u32 id)
100{
101 return MBOX_OFFSET;
102}
103
104static void imx8_dsp_handle_reply(struct imx_dsp_ipc *ipc)
105{
106 struct imx8_priv *priv = imx_dsp_get_data(ipc);
107 unsigned long flags;
108
109 spin_lock_irqsave(&priv->sdev->ipc_lock, flags);
110 imx8_get_reply(priv->sdev);
111 snd_sof_ipc_reply(priv->sdev, 0);
112 spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags);
113}
114
115static void imx8_dsp_handle_request(struct imx_dsp_ipc *ipc)
116{
117 struct imx8_priv *priv = imx_dsp_get_data(ipc);
118
119 snd_sof_ipc_msgs_rx(priv->sdev);
120}
121
122struct imx_dsp_ops dsp_ops = {
123 .handle_reply = imx8_dsp_handle_reply,
124 .handle_request = imx8_dsp_handle_request,
125};
126
127static int imx8_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
128{
129 struct imx8_priv *priv = (struct imx8_priv *)sdev->private;
130
131 sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
132 msg->msg_size);
133 imx_dsp_ring_doorbell(priv->dsp_ipc, 0);
134
135 return 0;
136}
137
138/*
139 * DSP control.
140 */
141static int imx8_run(struct snd_sof_dev *sdev)
142{
143 struct imx8_priv *dsp_priv = (struct imx8_priv *)sdev->private;
144 int ret;
145
146 ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP,
147 IMX_SC_C_OFS_SEL, 1);
148 if (ret < 0) {
149 dev_err(sdev->dev, "Error system address offset source select\n");
150 return ret;
151 }
152
153 ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP,
154 IMX_SC_C_OFS_AUDIO, 0x80);
155 if (ret < 0) {
156 dev_err(sdev->dev, "Error system address offset of AUDIO\n");
157 return ret;
158 }
159
160 ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP,
161 IMX_SC_C_OFS_PERIPH, 0x5A);
162 if (ret < 0) {
163 dev_err(sdev->dev, "Error system address offset of PERIPH %d\n",
164 ret);
165 return ret;
166 }
167
168 ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP,
169 IMX_SC_C_OFS_IRQ, 0x51);
170 if (ret < 0) {
171 dev_err(sdev->dev, "Error system address offset of IRQ\n");
172 return ret;
173 }
174
175 imx_sc_pm_cpu_start(dsp_priv->sc_ipc, IMX_SC_R_DSP, true,
176 RESET_VECTOR_VADDR);
177
178 return 0;
179}
180
181static int imx8_probe(struct snd_sof_dev *sdev)
182{
183 struct platform_device *pdev =
184 container_of(sdev->dev, struct platform_device, dev);
185 struct device_node *np = pdev->dev.of_node;
186 struct device_node *res_node;
187 struct resource *mmio;
188 struct imx8_priv *priv;
189 struct resource res;
190 u32 base, size;
191 int ret = 0;
192 int i;
193
194 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
195 if (!priv)
196 return -ENOMEM;
197
198 sdev->private = priv;
199 priv->dev = sdev->dev;
200 priv->sdev = sdev;
201
202 /* power up device associated power domains */
203 priv->num_domains = of_count_phandle_with_args(np, "power-domains",
204 "#power-domain-cells");
205 if (priv->num_domains < 0) {
206 dev_err(sdev->dev, "no power-domains property in %pOF\n", np);
207 return priv->num_domains;
208 }
209
210 priv->pd_dev = devm_kmalloc_array(&pdev->dev, priv->num_domains,
211 sizeof(*priv->pd_dev), GFP_KERNEL);
212 if (!priv)
213 return -ENOMEM;
214
215 priv->link = devm_kmalloc_array(&pdev->dev, priv->num_domains,
216 sizeof(*priv->link), GFP_KERNEL);
217 if (!priv->link)
218 return -ENOMEM;
219
220 for (i = 0; i < priv->num_domains; i++) {
221 priv->pd_dev[i] = dev_pm_domain_attach_by_id(&pdev->dev, i);
222 if (IS_ERR(priv->pd_dev[i])) {
223 ret = PTR_ERR(priv->pd_dev[i]);
224 goto exit_unroll_pm;
225 }
226 priv->link[i] = device_link_add(&pdev->dev, priv->pd_dev[i],
227 DL_FLAG_STATELESS |
228 DL_FLAG_PM_RUNTIME |
229 DL_FLAG_RPM_ACTIVE);
230 if (!priv->link[i]) {
231 ret = -ENOMEM;
232 dev_pm_domain_detach(priv->pd_dev[i], false);
233 goto exit_unroll_pm;
234 }
235 }
236
237 ret = imx_scu_get_handle(&priv->sc_ipc);
238 if (ret) {
239 dev_err(sdev->dev, "Cannot obtain SCU handle (err = %d)\n",
240 ret);
241 goto exit_unroll_pm;
242 }
243
244 priv->ipc_dev = platform_device_register_data(sdev->dev, "imx-dsp",
245 PLATFORM_DEVID_NONE,
246 pdev, sizeof(*pdev));
247 if (IS_ERR(priv->ipc_dev)) {
248 ret = PTR_ERR(priv->ipc_dev);
249 goto exit_unroll_pm;
250 }
251
252 priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev);
253 if (!priv->dsp_ipc) {
254 /* DSP IPC driver not probed yet, try later */
255 ret = -EPROBE_DEFER;
256 dev_err(sdev->dev, "Failed to get drvdata\n");
257 goto exit_pdev_unregister;
258 }
259
260 imx_dsp_set_data(priv->dsp_ipc, priv);
261 priv->dsp_ipc->ops = &dsp_ops;
262
263 /* DSP base */
264 mmio = platform_get_resource(pdev, IORESOURCE_MEM, 0);
265 if (mmio) {
266 base = mmio->start;
267 size = resource_size(mmio);
268 } else {
269 dev_err(sdev->dev, "error: failed to get DSP base at idx 0\n");
270 ret = -EINVAL;
271 goto exit_pdev_unregister;
272 }
273
274 sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev, base, size);
275 if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) {
276 dev_err(sdev->dev, "failed to ioremap base 0x%x size 0x%x\n",
277 base, size);
278 ret = -ENODEV;
279 goto exit_pdev_unregister;
280 }
281 sdev->mmio_bar = SOF_FW_BLK_TYPE_IRAM;
282
283 res_node = of_parse_phandle(np, "memory-region", 0);
284 if (!res_node) {
285 dev_err(&pdev->dev, "failed to get memory region node\n");
286 ret = -ENODEV;
287 goto exit_pdev_unregister;
288 }
289
290 ret = of_address_to_resource(res_node, 0, &res);
291 if (ret) {
292 dev_err(&pdev->dev, "failed to get reserved region address\n");
293 goto exit_pdev_unregister;
294 }
295
296 sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev, res.start,
297 res.end - res.start +
298 1);
299 if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) {
300 dev_err(sdev->dev, "failed to ioremap mem 0x%x size 0x%x\n",
301 base, size);
302 ret = -ENOMEM;
303 goto exit_pdev_unregister;
304 }
305 sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
306
307 return 0;
308
309exit_pdev_unregister:
310 platform_device_unregister(priv->ipc_dev);
311exit_unroll_pm:
312 while (--i >= 0) {
313 device_link_del(priv->link[i]);
314 dev_pm_domain_detach(priv->pd_dev[i], false);
315 }
316
317 return ret;
318}
319
320static int imx8_remove(struct snd_sof_dev *sdev)
321{
322 struct imx8_priv *priv = (struct imx8_priv *)sdev->private;
323 int i;
324
325 platform_device_unregister(priv->ipc_dev);
326
327 for (i = 0; i < priv->num_domains; i++) {
328 device_link_del(priv->link[i]);
329 dev_pm_domain_detach(priv->pd_dev[i], false);
330 }
331
332 return 0;
333}
334
335/* on i.MX8 there is 1 to 1 match between type and BAR idx */
336static int imx8_get_bar_index(struct snd_sof_dev *sdev, u32 type)
337{
338 return type;
339}
340
341static void imx8_ipc_msg_data(struct snd_sof_dev *sdev,
342 struct snd_pcm_substream *substream,
343 void *p, size_t sz)
344{
345 sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz);
346}
347
348static int imx8_ipc_pcm_params(struct snd_sof_dev *sdev,
349 struct snd_pcm_substream *substream,
350 const struct sof_ipc_pcm_params_reply *reply)
351{
352 return 0;
353}
354
355static struct snd_soc_dai_driver imx8_dai[] = {
356{
357 .name = "esai-port",
358},
359};
360
361/* i.MX8 ops */
362struct snd_sof_dsp_ops sof_imx8_ops = {
363 /* probe and remove */
364 .probe = imx8_probe,
365 .remove = imx8_remove,
366 /* DSP core boot */
367 .run = imx8_run,
368
369 /* Block IO */
370 .block_read = sof_block_read,
371 .block_write = sof_block_write,
372
373 /* ipc */
374 .send_msg = imx8_send_msg,
375 .fw_ready = sof_fw_ready,
376 .get_mailbox_offset = imx8_get_mailbox_offset,
377 .get_window_offset = imx8_get_window_offset,
378
379 .ipc_msg_data = imx8_ipc_msg_data,
380 .ipc_pcm_params = imx8_ipc_pcm_params,
381
382 /* module loading */
383 .load_module = snd_sof_parse_module_memcpy,
384 .get_bar_index = imx8_get_bar_index,
385 /* firmware loading */
386 .load_firmware = snd_sof_load_firmware_memcpy,
387
388 /* DAI drivers */
389 .drv = imx8_dai,
390 .num_drv = 1, /* we have only 1 ESAI interface on i.MX8 */
391};
392EXPORT_SYMBOL(sof_imx8_ops);
393
394MODULE_LICENSE("Dual BSD/GPL");
diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig
index dd14ce92fe10..479ba249e219 100644
--- a/sound/soc/sof/intel/Kconfig
+++ b/sound/soc/sof/intel/Kconfig
@@ -27,6 +27,8 @@ config SND_SOC_SOF_INTEL_PCI
27 select SND_SOC_SOF_ICELAKE if SND_SOC_SOF_ICELAKE_SUPPORT 27 select SND_SOC_SOF_ICELAKE if SND_SOC_SOF_ICELAKE_SUPPORT
28 select SND_SOC_SOF_COMETLAKE_LP if SND_SOC_SOF_COMETLAKE_LP_SUPPORT 28 select SND_SOC_SOF_COMETLAKE_LP if SND_SOC_SOF_COMETLAKE_LP_SUPPORT
29 select SND_SOC_SOF_COMETLAKE_H if SND_SOC_SOF_COMETLAKE_H_SUPPORT 29 select SND_SOC_SOF_COMETLAKE_H if SND_SOC_SOF_COMETLAKE_H_SUPPORT
30 select SND_SOC_SOF_TIGERLAKE if SND_SOC_SOF_TIGERLAKE_SUPPORT
31 select SND_SOC_SOF_ELKHARTLAKE if SND_SOC_SOF_ELKHARTLAKE_SUPPORT
30 help 32 help
31 This option is not user-selectable but automagically handled by 33 This option is not user-selectable but automagically handled by
32 'select' statements at a higher level 34 'select' statements at a higher level
@@ -212,6 +214,36 @@ config SND_SOC_SOF_COMETLAKE_H_SUPPORT
212 Say Y if you have such a device. 214 Say Y if you have such a device.
213 If unsure select "N". 215 If unsure select "N".
214 216
217config SND_SOC_SOF_TIGERLAKE_SUPPORT
218 bool "SOF support for Tigerlake"
219 help
220 This adds support for Sound Open Firmware for Intel(R) platforms
221 using the Tigerlake processors.
222 Say Y if you have such a device.
223 If unsure select "N".
224
225config SND_SOC_SOF_TIGERLAKE
226 tristate
227 select SND_SOC_SOF_HDA_COMMON
228 help
229 This option is not user-selectable but automagically handled by
230 'select' statements at a higher level
231
232config SND_SOC_SOF_ELKHARTLAKE_SUPPORT
233 bool "SOF support for ElkhartLake"
234 help
235 This adds support for Sound Open Firmware for Intel(R) platforms
236 using the ElkhartLake processors.
237 Say Y if you have such a device.
238 If unsure select "N".
239
240config SND_SOC_SOF_ELKHARTLAKE
241 tristate
242 select SND_SOC_SOF_HDA_COMMON
243 help
244 This option is not user-selectable but automagically handled by
245 'select' statements at a higher level
246
215config SND_SOC_SOF_HDA_COMMON 247config SND_SOC_SOF_HDA_COMMON
216 tristate 248 tristate
217 select SND_SOC_SOF_INTEL_COMMON 249 select SND_SOC_SOF_INTEL_COMMON
@@ -254,6 +286,7 @@ config SND_SOC_SOF_HDA
254 tristate 286 tristate
255 select SND_HDA_EXT_CORE if SND_SOC_SOF_HDA_LINK 287 select SND_HDA_EXT_CORE if SND_SOC_SOF_HDA_LINK
256 select SND_SOC_HDAC_HDA if SND_SOC_SOF_HDA_AUDIO_CODEC 288 select SND_SOC_HDAC_HDA if SND_SOC_SOF_HDA_AUDIO_CODEC
289 select SND_INTEL_NHLT if ACPI
257 help 290 help
258 This option is not user-selectable but automagically handled by 291 This option is not user-selectable but automagically handled by
259 'select' statements at a higher level 292 'select' statements at a higher level
diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c
index fd2e26d79796..8dc7a5558da4 100644
--- a/sound/soc/sof/intel/apl.c
+++ b/sound/soc/sof/intel/apl.c
@@ -46,7 +46,9 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
46 46
47 /* ipc */ 47 /* ipc */
48 .send_msg = hda_dsp_ipc_send_msg, 48 .send_msg = hda_dsp_ipc_send_msg,
49 .fw_ready = hda_dsp_ipc_fw_ready, 49 .fw_ready = sof_fw_ready,
50 .get_mailbox_offset = hda_dsp_ipc_get_mailbox_offset,
51 .get_window_offset = hda_dsp_ipc_get_window_offset,
50 52
51 .ipc_msg_data = hda_ipc_msg_data, 53 .ipc_msg_data = hda_ipc_msg_data,
52 .ipc_pcm_params = hda_ipc_pcm_params, 54 .ipc_pcm_params = hda_ipc_pcm_params,
diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c
index 70d524ef9bc0..e282179263e8 100644
--- a/sound/soc/sof/intel/bdw.c
+++ b/sound/soc/sof/intel/bdw.c
@@ -328,153 +328,6 @@ static irqreturn_t bdw_irq_thread(int irq, void *context)
328} 328}
329 329
330/* 330/*
331 * IPC Firmware ready.
332 */
333static void bdw_get_windows(struct snd_sof_dev *sdev)
334{
335 struct sof_ipc_window_elem *elem;
336 u32 outbox_offset = 0;
337 u32 stream_offset = 0;
338 u32 inbox_offset = 0;
339 u32 outbox_size = 0;
340 u32 stream_size = 0;
341 u32 inbox_size = 0;
342 int i;
343
344 if (!sdev->info_window) {
345 dev_err(sdev->dev, "error: have no window info\n");
346 return;
347 }
348
349 for (i = 0; i < sdev->info_window->num_windows; i++) {
350 elem = &sdev->info_window->window[i];
351
352 switch (elem->type) {
353 case SOF_IPC_REGION_UPBOX:
354 inbox_offset = elem->offset + MBOX_OFFSET;
355 inbox_size = elem->size;
356 snd_sof_debugfs_io_item(sdev,
357 sdev->bar[BDW_DSP_BAR] +
358 inbox_offset,
359 elem->size, "inbox",
360 SOF_DEBUGFS_ACCESS_D0_ONLY);
361 break;
362 case SOF_IPC_REGION_DOWNBOX:
363 outbox_offset = elem->offset + MBOX_OFFSET;
364 outbox_size = elem->size;
365 snd_sof_debugfs_io_item(sdev,
366 sdev->bar[BDW_DSP_BAR] +
367 outbox_offset,
368 elem->size, "outbox",
369 SOF_DEBUGFS_ACCESS_D0_ONLY);
370 break;
371 case SOF_IPC_REGION_TRACE:
372 snd_sof_debugfs_io_item(sdev,
373 sdev->bar[BDW_DSP_BAR] +
374 elem->offset +
375 MBOX_OFFSET,
376 elem->size, "etrace",
377 SOF_DEBUGFS_ACCESS_D0_ONLY);
378 break;
379 case SOF_IPC_REGION_DEBUG:
380 snd_sof_debugfs_io_item(sdev,
381 sdev->bar[BDW_DSP_BAR] +
382 elem->offset +
383 MBOX_OFFSET,
384 elem->size, "debug",
385 SOF_DEBUGFS_ACCESS_D0_ONLY);
386 break;
387 case SOF_IPC_REGION_STREAM:
388 stream_offset = elem->offset + MBOX_OFFSET;
389 stream_size = elem->size;
390 snd_sof_debugfs_io_item(sdev,
391 sdev->bar[BDW_DSP_BAR] +
392 stream_offset,
393 elem->size, "stream",
394 SOF_DEBUGFS_ACCESS_D0_ONLY);
395 break;
396 case SOF_IPC_REGION_REGS:
397 snd_sof_debugfs_io_item(sdev,
398 sdev->bar[BDW_DSP_BAR] +
399 elem->offset +
400 MBOX_OFFSET,
401 elem->size, "regs",
402 SOF_DEBUGFS_ACCESS_D0_ONLY);
403 break;
404 case SOF_IPC_REGION_EXCEPTION:
405 sdev->dsp_oops_offset = elem->offset + MBOX_OFFSET;
406 snd_sof_debugfs_io_item(sdev,
407 sdev->bar[BDW_DSP_BAR] +
408 elem->offset +
409 MBOX_OFFSET,
410 elem->size, "exception",
411 SOF_DEBUGFS_ACCESS_D0_ONLY);
412 break;
413 default:
414 dev_err(sdev->dev, "error: get illegal window info\n");
415 return;
416 }
417 }
418
419 if (outbox_size == 0 || inbox_size == 0) {
420 dev_err(sdev->dev, "error: get illegal mailbox window\n");
421 return;
422 }
423
424 snd_sof_dsp_mailbox_init(sdev, inbox_offset, inbox_size,
425 outbox_offset, outbox_size);
426 sdev->stream_box.offset = stream_offset;
427 sdev->stream_box.size = stream_size;
428
429 dev_dbg(sdev->dev, " mailbox upstream 0x%x - size 0x%x\n",
430 inbox_offset, inbox_size);
431 dev_dbg(sdev->dev, " mailbox downstream 0x%x - size 0x%x\n",
432 outbox_offset, outbox_size);
433 dev_dbg(sdev->dev, " stream region 0x%x - size 0x%x\n",
434 stream_offset, stream_size);
435}
436
437/* check for ABI compatibility and create memory windows on first boot */
438static int bdw_fw_ready(struct snd_sof_dev *sdev, u32 msg_id)
439{
440 struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready;
441 u32 offset;
442 int ret;
443
444 /* mailbox must be on 4k boundary */
445 offset = MBOX_OFFSET;
446
447 dev_dbg(sdev->dev, "ipc: DSP is ready 0x%8.8x offset %d\n",
448 msg_id, offset);
449
450 /* no need to re-check version/ABI for subsequent boots */
451 if (!sdev->first_boot)
452 return 0;
453
454 /* copy data from the DSP FW ready offset */
455 sof_block_read(sdev, sdev->mmio_bar, offset, fw_ready,
456 sizeof(*fw_ready));
457
458 snd_sof_dsp_mailbox_init(sdev, fw_ready->dspbox_offset,
459 fw_ready->dspbox_size,
460 fw_ready->hostbox_offset,
461 fw_ready->hostbox_size);
462
463 /* make sure ABI version is compatible */
464 ret = snd_sof_ipc_valid(sdev);
465 if (ret < 0)
466 return ret;
467
468 /* now check for extended data */
469 snd_sof_fw_parse_ext_data(sdev, sdev->mmio_bar, MBOX_OFFSET +
470 sizeof(struct sof_ipc_fw_ready));
471
472 bdw_get_windows(sdev);
473
474 return 0;
475}
476
477/*
478 * IPC Mailbox IO 331 * IPC Mailbox IO
479 */ 332 */
480 333
@@ -527,6 +380,16 @@ static void bdw_get_reply(struct snd_sof_dev *sdev)
527 msg->reply_error = ret; 380 msg->reply_error = ret;
528} 381}
529 382
383static int bdw_get_mailbox_offset(struct snd_sof_dev *sdev)
384{
385 return MBOX_OFFSET;
386}
387
388static int bdw_get_window_offset(struct snd_sof_dev *sdev, u32 id)
389{
390 return MBOX_OFFSET;
391}
392
530static void bdw_host_done(struct snd_sof_dev *sdev) 393static void bdw_host_done(struct snd_sof_dev *sdev)
531{ 394{
532 /* clear BUSY bit and set DONE bit - accept new messages */ 395 /* clear BUSY bit and set DONE bit - accept new messages */
@@ -613,11 +476,8 @@ static int bdw_probe(struct snd_sof_dev *sdev)
613 476
614 /* register our IRQ */ 477 /* register our IRQ */
615 sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc); 478 sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
616 if (sdev->ipc_irq < 0) { 479 if (sdev->ipc_irq < 0)
617 dev_err(sdev->dev, "error: failed to get IRQ at index %d\n",
618 desc->irqindex_host_ipc);
619 return sdev->ipc_irq; 480 return sdev->ipc_irq;
620 }
621 481
622 dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); 482 dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
623 ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq, 483 ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
@@ -680,7 +540,9 @@ const struct snd_sof_dsp_ops sof_bdw_ops = {
680 540
681 /* ipc */ 541 /* ipc */
682 .send_msg = bdw_send_msg, 542 .send_msg = bdw_send_msg,
683 .fw_ready = bdw_fw_ready, 543 .fw_ready = sof_fw_ready,
544 .get_mailbox_offset = bdw_get_mailbox_offset,
545 .get_window_offset = bdw_get_window_offset,
684 546
685 .ipc_msg_data = intel_ipc_msg_data, 547 .ipc_msg_data = intel_ipc_msg_data,
686 .ipc_pcm_params = intel_ipc_pcm_params, 548 .ipc_pcm_params = intel_ipc_pcm_params,
diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c
index 107d711efc3f..5e7a6aaa627a 100644
--- a/sound/soc/sof/intel/byt.c
+++ b/sound/soc/sof/intel/byt.c
@@ -110,153 +110,6 @@ static void byt_dsp_done(struct snd_sof_dev *sdev);
110static void byt_get_reply(struct snd_sof_dev *sdev); 110static void byt_get_reply(struct snd_sof_dev *sdev);
111 111
112/* 112/*
113 * IPC Firmware ready.
114 */
115static void byt_get_windows(struct snd_sof_dev *sdev)
116{
117 struct sof_ipc_window_elem *elem;
118 u32 outbox_offset = 0;
119 u32 stream_offset = 0;
120 u32 inbox_offset = 0;
121 u32 outbox_size = 0;
122 u32 stream_size = 0;
123 u32 inbox_size = 0;
124 int i;
125
126 if (!sdev->info_window) {
127 dev_err(sdev->dev, "error: have no window info\n");
128 return;
129 }
130
131 for (i = 0; i < sdev->info_window->num_windows; i++) {
132 elem = &sdev->info_window->window[i];
133
134 switch (elem->type) {
135 case SOF_IPC_REGION_UPBOX:
136 inbox_offset = elem->offset + MBOX_OFFSET;
137 inbox_size = elem->size;
138 snd_sof_debugfs_io_item(sdev,
139 sdev->bar[BYT_DSP_BAR] +
140 inbox_offset,
141 elem->size, "inbox",
142 SOF_DEBUGFS_ACCESS_D0_ONLY);
143 break;
144 case SOF_IPC_REGION_DOWNBOX:
145 outbox_offset = elem->offset + MBOX_OFFSET;
146 outbox_size = elem->size;
147 snd_sof_debugfs_io_item(sdev,
148 sdev->bar[BYT_DSP_BAR] +
149 outbox_offset,
150 elem->size, "outbox",
151 SOF_DEBUGFS_ACCESS_D0_ONLY);
152 break;
153 case SOF_IPC_REGION_TRACE:
154 snd_sof_debugfs_io_item(sdev,
155 sdev->bar[BYT_DSP_BAR] +
156 elem->offset +
157 MBOX_OFFSET,
158 elem->size, "etrace",
159 SOF_DEBUGFS_ACCESS_D0_ONLY);
160 break;
161 case SOF_IPC_REGION_DEBUG:
162 snd_sof_debugfs_io_item(sdev,
163 sdev->bar[BYT_DSP_BAR] +
164 elem->offset +
165 MBOX_OFFSET,
166 elem->size, "debug",
167 SOF_DEBUGFS_ACCESS_D0_ONLY);
168 break;
169 case SOF_IPC_REGION_STREAM:
170 stream_offset = elem->offset + MBOX_OFFSET;
171 stream_size = elem->size;
172 snd_sof_debugfs_io_item(sdev,
173 sdev->bar[BYT_DSP_BAR] +
174 stream_offset,
175 elem->size, "stream",
176 SOF_DEBUGFS_ACCESS_D0_ONLY);
177 break;
178 case SOF_IPC_REGION_REGS:
179 snd_sof_debugfs_io_item(sdev,
180 sdev->bar[BYT_DSP_BAR] +
181 elem->offset +
182 MBOX_OFFSET,
183 elem->size, "regs",
184 SOF_DEBUGFS_ACCESS_D0_ONLY);
185 break;
186 case SOF_IPC_REGION_EXCEPTION:
187 sdev->dsp_oops_offset = elem->offset + MBOX_OFFSET;
188 snd_sof_debugfs_io_item(sdev,
189 sdev->bar[BYT_DSP_BAR] +
190 elem->offset +
191 MBOX_OFFSET,
192 elem->size, "exception",
193 SOF_DEBUGFS_ACCESS_D0_ONLY);
194 break;
195 default:
196 dev_err(sdev->dev, "error: get illegal window info\n");
197 return;
198 }
199 }
200
201 if (outbox_size == 0 || inbox_size == 0) {
202 dev_err(sdev->dev, "error: get illegal mailbox window\n");
203 return;
204 }
205
206 snd_sof_dsp_mailbox_init(sdev, inbox_offset, inbox_size,
207 outbox_offset, outbox_size);
208 sdev->stream_box.offset = stream_offset;
209 sdev->stream_box.size = stream_size;
210
211 dev_dbg(sdev->dev, " mailbox upstream 0x%x - size 0x%x\n",
212 inbox_offset, inbox_size);
213 dev_dbg(sdev->dev, " mailbox downstream 0x%x - size 0x%x\n",
214 outbox_offset, outbox_size);
215 dev_dbg(sdev->dev, " stream region 0x%x - size 0x%x\n",
216 stream_offset, stream_size);
217}
218
219/* check for ABI compatibility and create memory windows on first boot */
220static int byt_fw_ready(struct snd_sof_dev *sdev, u32 msg_id)
221{
222 struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready;
223 u32 offset;
224 int ret;
225
226 /* mailbox must be on 4k boundary */
227 offset = MBOX_OFFSET;
228
229 dev_dbg(sdev->dev, "ipc: DSP is ready 0x%8.8x offset 0x%x\n",
230 msg_id, offset);
231
232 /* no need to re-check version/ABI for subsequent boots */
233 if (!sdev->first_boot)
234 return 0;
235
236 /* copy data from the DSP FW ready offset */
237 sof_block_read(sdev, sdev->mmio_bar, offset, fw_ready,
238 sizeof(*fw_ready));
239
240 snd_sof_dsp_mailbox_init(sdev, fw_ready->dspbox_offset,
241 fw_ready->dspbox_size,
242 fw_ready->hostbox_offset,
243 fw_ready->hostbox_size);
244
245 /* make sure ABI version is compatible */
246 ret = snd_sof_ipc_valid(sdev);
247 if (ret < 0)
248 return ret;
249
250 /* now check for extended data */
251 snd_sof_fw_parse_ext_data(sdev, sdev->mmio_bar, MBOX_OFFSET +
252 sizeof(struct sof_ipc_fw_ready));
253
254 byt_get_windows(sdev);
255
256 return 0;
257}
258
259/*
260 * Debug 113 * Debug
261 */ 114 */
262 115
@@ -423,6 +276,16 @@ static void byt_get_reply(struct snd_sof_dev *sdev)
423 msg->reply_error = ret; 276 msg->reply_error = ret;
424} 277}
425 278
279static int byt_get_mailbox_offset(struct snd_sof_dev *sdev)
280{
281 return MBOX_OFFSET;
282}
283
284static int byt_get_window_offset(struct snd_sof_dev *sdev, u32 id)
285{
286 return MBOX_OFFSET;
287}
288
426static void byt_host_done(struct snd_sof_dev *sdev) 289static void byt_host_done(struct snd_sof_dev *sdev)
427{ 290{
428 /* clear BUSY bit and set DONE bit - accept new messages */ 291 /* clear BUSY bit and set DONE bit - accept new messages */
@@ -617,7 +480,9 @@ const struct snd_sof_dsp_ops sof_tng_ops = {
617 480
618 /* ipc */ 481 /* ipc */
619 .send_msg = byt_send_msg, 482 .send_msg = byt_send_msg,
620 .fw_ready = byt_fw_ready, 483 .fw_ready = sof_fw_ready,
484 .get_mailbox_offset = byt_get_mailbox_offset,
485 .get_window_offset = byt_get_window_offset,
621 486
622 .ipc_msg_data = intel_ipc_msg_data, 487 .ipc_msg_data = intel_ipc_msg_data,
623 .ipc_pcm_params = intel_ipc_pcm_params, 488 .ipc_pcm_params = intel_ipc_pcm_params,
@@ -728,11 +593,8 @@ static int byt_acpi_probe(struct snd_sof_dev *sdev)
728irq: 593irq:
729 /* register our IRQ */ 594 /* register our IRQ */
730 sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc); 595 sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
731 if (sdev->ipc_irq < 0) { 596 if (sdev->ipc_irq < 0)
732 dev_err(sdev->dev, "error: failed to get IRQ at index %d\n",
733 desc->irqindex_host_ipc);
734 return sdev->ipc_irq; 597 return sdev->ipc_irq;
735 }
736 598
737 dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); 599 dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
738 ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq, 600 ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
@@ -779,7 +641,9 @@ const struct snd_sof_dsp_ops sof_byt_ops = {
779 641
780 /* ipc */ 642 /* ipc */
781 .send_msg = byt_send_msg, 643 .send_msg = byt_send_msg,
782 .fw_ready = byt_fw_ready, 644 .fw_ready = sof_fw_ready,
645 .get_mailbox_offset = byt_get_mailbox_offset,
646 .get_window_offset = byt_get_window_offset,
783 647
784 .ipc_msg_data = intel_ipc_msg_data, 648 .ipc_msg_data = intel_ipc_msg_data,
785 .ipc_pcm_params = intel_ipc_pcm_params, 649 .ipc_pcm_params = intel_ipc_pcm_params,
@@ -836,7 +700,9 @@ const struct snd_sof_dsp_ops sof_cht_ops = {
836 700
837 /* ipc */ 701 /* ipc */
838 .send_msg = byt_send_msg, 702 .send_msg = byt_send_msg,
839 .fw_ready = byt_fw_ready, 703 .fw_ready = sof_fw_ready,
704 .get_mailbox_offset = byt_get_mailbox_offset,
705 .get_window_offset = byt_get_window_offset,
840 706
841 .ipc_msg_data = intel_ipc_msg_data, 707 .ipc_msg_data = intel_ipc_msg_data,
842 .ipc_pcm_params = intel_ipc_pcm_params, 708 .ipc_pcm_params = intel_ipc_pcm_params,
diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index ffd8d4394537..4ddd73762d81 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -204,7 +204,9 @@ const struct snd_sof_dsp_ops sof_cnl_ops = {
204 204
205 /* ipc */ 205 /* ipc */
206 .send_msg = cnl_ipc_send_msg, 206 .send_msg = cnl_ipc_send_msg,
207 .fw_ready = hda_dsp_ipc_fw_ready, 207 .fw_ready = sof_fw_ready,
208 .get_mailbox_offset = hda_dsp_ipc_get_mailbox_offset,
209 .get_window_offset = hda_dsp_ipc_get_window_offset,
208 210
209 .ipc_msg_data = hda_ipc_msg_data, 211 .ipc_msg_data = hda_ipc_msg_data,
210 .ipc_pcm_params = hda_ipc_pcm_params, 212 .ipc_pcm_params = hda_ipc_pcm_params,
@@ -293,3 +295,35 @@ const struct sof_intel_dsp_desc icl_chip_info = {
293 .ssp_base_offset = CNL_SSP_BASE_OFFSET, 295 .ssp_base_offset = CNL_SSP_BASE_OFFSET,
294}; 296};
295EXPORT_SYMBOL(icl_chip_info); 297EXPORT_SYMBOL(icl_chip_info);
298
299const struct sof_intel_dsp_desc tgl_chip_info = {
300 /* Tigerlake */
301 .cores_num = 4,
302 .init_core_mask = 1,
303 .cores_mask = HDA_DSP_CORE_MASK(0),
304 .ipc_req = CNL_DSP_REG_HIPCIDR,
305 .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
306 .ipc_ack = CNL_DSP_REG_HIPCIDA,
307 .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
308 .ipc_ctl = CNL_DSP_REG_HIPCCTL,
309 .rom_init_timeout = 300,
310 .ssp_count = ICL_SSP_COUNT,
311 .ssp_base_offset = CNL_SSP_BASE_OFFSET,
312};
313EXPORT_SYMBOL(tgl_chip_info);
314
315const struct sof_intel_dsp_desc ehl_chip_info = {
316 /* Elkhartlake */
317 .cores_num = 4,
318 .init_core_mask = 1,
319 .cores_mask = HDA_DSP_CORE_MASK(0),
320 .ipc_req = CNL_DSP_REG_HIPCIDR,
321 .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
322 .ipc_ack = CNL_DSP_REG_HIPCIDA,
323 .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
324 .ipc_ctl = CNL_DSP_REG_HIPCCTL,
325 .rom_init_timeout = 300,
326 .ssp_count = ICL_SSP_COUNT,
327 .ssp_base_offset = CNL_SSP_BASE_OFFSET,
328};
329EXPORT_SYMBOL(ehl_chip_info);
diff --git a/sound/soc/sof/intel/hda-bus.c b/sound/soc/sof/intel/hda-bus.c
index a7e6d8227df6..1d2babdda9dd 100644
--- a/sound/soc/sof/intel/hda-bus.c
+++ b/sound/soc/sof/intel/hda-bus.c
@@ -12,82 +12,27 @@
12#include "../sof-priv.h" 12#include "../sof-priv.h"
13#include "hda.h" 13#include "hda.h"
14 14
15#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 15#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
16 16#include "../../codecs/hdac_hda.h"
17static const struct hdac_bus_ops bus_ops = { 17#define sof_hda_ext_ops snd_soc_hdac_hda_get_ops()
18 .command = snd_hdac_bus_send_cmd, 18#else
19 .get_response = snd_hdac_bus_get_response, 19#define sof_hda_ext_ops NULL
20};
21
22#endif 20#endif
23 21
24static void sof_hda_writel(u32 value, u32 __iomem *addr)
25{
26 writel(value, addr);
27}
28
29static u32 sof_hda_readl(u32 __iomem *addr)
30{
31 return readl(addr);
32}
33
34static void sof_hda_writew(u16 value, u16 __iomem *addr)
35{
36 writew(value, addr);
37}
38
39static u16 sof_hda_readw(u16 __iomem *addr)
40{
41 return readw(addr);
42}
43
44static void sof_hda_writeb(u8 value, u8 __iomem *addr)
45{
46 writeb(value, addr);
47}
48
49static u8 sof_hda_readb(u8 __iomem *addr)
50{
51 return readb(addr);
52}
53
54static int sof_hda_dma_alloc_pages(struct hdac_bus *bus, int type,
55 size_t size, struct snd_dma_buffer *buf)
56{
57 return snd_dma_alloc_pages(type, bus->dev, size, buf);
58}
59
60static void sof_hda_dma_free_pages(struct hdac_bus *bus,
61 struct snd_dma_buffer *buf)
62{
63 snd_dma_free_pages(buf);
64}
65
66static const struct hdac_io_ops io_ops = {
67 .reg_writel = sof_hda_writel,
68 .reg_readl = sof_hda_readl,
69 .reg_writew = sof_hda_writew,
70 .reg_readw = sof_hda_readw,
71 .reg_writeb = sof_hda_writeb,
72 .reg_readb = sof_hda_readb,
73 .dma_alloc_pages = sof_hda_dma_alloc_pages,
74 .dma_free_pages = sof_hda_dma_free_pages,
75};
76
77/* 22/*
78 * This can be used for both with/without hda link support. 23 * This can be used for both with/without hda link support.
79 */ 24 */
80void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev, 25void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev)
81 const struct hdac_ext_bus_ops *ext_ops)
82{ 26{
27#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
28 snd_hdac_ext_bus_init(bus, dev, NULL, sof_hda_ext_ops);
29#else /* CONFIG_SND_SOC_SOF_HDA */
83 memset(bus, 0, sizeof(*bus)); 30 memset(bus, 0, sizeof(*bus));
84 bus->dev = dev; 31 bus->dev = dev;
85 32
86 bus->io_ops = &io_ops;
87 INIT_LIST_HEAD(&bus->stream_list); 33 INIT_LIST_HEAD(&bus->stream_list);
88 34
89 bus->irq = -1; 35 bus->irq = -1;
90 bus->ext_ops = ext_ops;
91 36
92 /* 37 /*
93 * There is only one HDA bus atm. keep the index as 0. 38 * There is only one HDA bus atm. keep the index as 0.
@@ -96,16 +41,5 @@ void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev,
96 bus->idx = 0; 41 bus->idx = 0;
97 42
98 spin_lock_init(&bus->reg_lock); 43 spin_lock_init(&bus->reg_lock);
99 44#endif /* CONFIG_SND_SOC_SOF_HDA */
100#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
101 INIT_LIST_HEAD(&bus->codec_list);
102 INIT_LIST_HEAD(&bus->hlink_list);
103
104 mutex_init(&bus->cmd_mutex);
105 mutex_init(&bus->lock);
106 bus->ops = &bus_ops;
107 INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events);
108 bus->cmd_dma_state = true;
109#endif
110
111} 45}
diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c
index b8b37f082309..3ca6795a89ba 100644
--- a/sound/soc/sof/intel/hda-codec.c
+++ b/sound/soc/sof/intel/hda-codec.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <sound/hdaudio_ext.h> 12#include <sound/hdaudio_ext.h>
13#include <sound/hda_register.h>
13#include <sound/hda_codec.h> 14#include <sound/hda_codec.h>
14#include <sound/hda_i915.h> 15#include <sound/hda_i915.h>
15#include <sound/sof.h> 16#include <sound/sof.h>
@@ -37,16 +38,55 @@ static void hda_codec_load_module(struct hda_codec *codec)
37static void hda_codec_load_module(struct hda_codec *codec) {} 38static void hda_codec_load_module(struct hda_codec *codec) {}
38#endif 39#endif
39 40
41/* enable controller wake up event for all codecs with jack connectors */
42void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev)
43{
44 struct hda_bus *hbus = sof_to_hbus(sdev);
45 struct hdac_bus *bus = sof_to_bus(sdev);
46 struct hda_codec *codec;
47 unsigned int mask = 0;
48
49 list_for_each_codec(codec, hbus)
50 if (codec->jacktbl.used)
51 mask |= BIT(codec->core.addr);
52
53 snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask);
54}
55
56/* check jack status after resuming from suspend mode */
57void hda_codec_jack_check(struct snd_sof_dev *sdev)
58{
59 struct hda_bus *hbus = sof_to_hbus(sdev);
60 struct hdac_bus *bus = sof_to_bus(sdev);
61 struct hda_codec *codec;
62
63 /* disable controller Wake Up event*/
64 snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0);
65
66 list_for_each_codec(codec, hbus)
67 /*
68 * Wake up all jack-detecting codecs regardless whether an event
69 * has been recorded in STATESTS
70 */
71 if (codec->jacktbl.used)
72 schedule_delayed_work(&codec->jackpoll_work,
73 codec->jackpoll_interval);
74}
75#else
76void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev) {}
77void hda_codec_jack_check(struct snd_sof_dev *sdev) {}
40#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */ 78#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */
79EXPORT_SYMBOL(hda_codec_jack_wake_enable);
80EXPORT_SYMBOL(hda_codec_jack_check);
41 81
42/* probe individual codec */ 82/* probe individual codec */
43static int hda_codec_probe(struct snd_sof_dev *sdev, int address) 83static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
44{ 84{
45 struct hda_bus *hbus = sof_to_hbus(sdev);
46 struct hdac_device *hdev;
47#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 85#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
48 struct hdac_hda_priv *hda_priv; 86 struct hdac_hda_priv *hda_priv;
49#endif 87#endif
88 struct hda_bus *hbus = sof_to_hbus(sdev);
89 struct hdac_device *hdev;
50 u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) | 90 u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) |
51 (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; 91 (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
52 u32 resp = -1; 92 u32 resp = -1;
@@ -62,8 +102,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
62 address, resp); 102 address, resp);
63 103
64#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 104#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
65 /* snd_hdac_ext_bus_device_exit will use kfree to free hdev */ 105 hda_priv = devm_kzalloc(sdev->dev, sizeof(*hda_priv), GFP_KERNEL);
66 hda_priv = kzalloc(sizeof(*hda_priv), GFP_KERNEL);
67 if (!hda_priv) 106 if (!hda_priv)
68 return -ENOMEM; 107 return -ENOMEM;
69 108
@@ -82,8 +121,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
82 121
83 return 0; 122 return 0;
84#else 123#else
85 /* snd_hdac_ext_bus_device_exit will use kfree to free hdev */ 124 hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL);
86 hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
87 if (!hdev) 125 if (!hdev)
88 return -ENOMEM; 126 return -ENOMEM;
89 127
diff --git a/sound/soc/sof/intel/hda-ctrl.c b/sound/soc/sof/intel/hda-ctrl.c
index ea63f83a509b..bc41028a7a01 100644
--- a/sound/soc/sof/intel/hda-ctrl.c
+++ b/sound/soc/sof/intel/hda-ctrl.c
@@ -164,6 +164,9 @@ int hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev *sdev, bool enable)
164int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset) 164int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)
165{ 165{
166 struct hdac_bus *bus = sof_to_bus(sdev); 166 struct hdac_bus *bus = sof_to_bus(sdev);
167#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
168 struct hdac_ext_link *hlink;
169#endif
167 struct hdac_stream *stream; 170 struct hdac_stream *stream;
168 int sd_offset, ret = 0; 171 int sd_offset, ret = 0;
169 172
@@ -173,11 +176,6 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)
173 hda_dsp_ctrl_misc_clock_gating(sdev, false); 176 hda_dsp_ctrl_misc_clock_gating(sdev, false);
174 177
175 if (full_reset) { 178 if (full_reset) {
176 /* clear WAKESTS */
177 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS,
178 SOF_HDA_WAKESTS_INT_MASK,
179 SOF_HDA_WAKESTS_INT_MASK);
180
181 /* reset HDA controller */ 179 /* reset HDA controller */
182 ret = hda_dsp_ctrl_link_reset(sdev, true); 180 ret = hda_dsp_ctrl_link_reset(sdev, true);
183 if (ret < 0) { 181 if (ret < 0) {
@@ -245,13 +243,18 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)
245 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN, 243 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
246 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN); 244 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN);
247 245
248#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
249 /* program the position buffer */ 246 /* program the position buffer */
250 if (bus->use_posbuf && bus->posbuf.addr) { 247 if (bus->use_posbuf && bus->posbuf.addr) {
251 snd_hdac_chip_writel(bus, DPLBASE, (u32)bus->posbuf.addr); 248 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE,
252 snd_hdac_chip_writel(bus, DPUBASE, 249 (u32)bus->posbuf.addr);
253 upper_32_bits(bus->posbuf.addr)); 250 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPUBASE,
251 upper_32_bits(bus->posbuf.addr));
254 } 252 }
253
254#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
255 /* Reset stream-to-link mapping */
256 list_for_each_entry(hlink, &bus->hlink_list, list)
257 writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
255#endif 258#endif
256 259
257 bus->chip_init = true; 260 bus->chip_init = true;
diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c
index a514f9cf5c9a..8796f385be76 100644
--- a/sound/soc/sof/intel/hda-dai.c
+++ b/sound/soc/sof/intel/hda-dai.c
@@ -210,9 +210,13 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
210 int stream_tag; 210 int stream_tag;
211 int ret; 211 int ret;
212 212
213 link_dev = hda_link_stream_assign(bus, substream); 213 /* get stored dma data if resuming from system suspend */
214 if (!link_dev) 214 link_dev = snd_soc_dai_get_dma_data(dai, substream);
215 return -EBUSY; 215 if (!link_dev) {
216 link_dev = hda_link_stream_assign(bus, substream);
217 if (!link_dev)
218 return -EBUSY;
219 }
216 220
217 stream_tag = hdac_stream(link_dev)->stream_tag; 221 stream_tag = hdac_stream(link_dev)->stream_tag;
218 222
@@ -226,8 +230,6 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
226 230
227 snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev); 231 snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
228 232
229 hda_stream->hw_params_upon_resume = 0;
230
231 link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); 233 link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name);
232 if (!link) 234 if (!link)
233 return -EINVAL; 235 return -EINVAL;
@@ -267,8 +269,7 @@ static int hda_link_pcm_prepare(struct snd_pcm_substream *substream,
267 269
268 hda_stream = hstream_to_sof_hda_stream(link_dev); 270 hda_stream = hstream_to_sof_hda_stream(link_dev);
269 271
270 /* setup hw_params again only if resuming from system suspend */ 272 if (link_dev->link_prepared)
271 if (!hda_stream->hw_params_upon_resume)
272 return 0; 273 return 0;
273 274
274 dev_dbg(sdev->dev, "hda: prepare stream dir %d\n", substream->stream); 275 dev_dbg(sdev->dev, "hda: prepare stream dir %d\n", substream->stream);
@@ -317,22 +318,25 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
317 snd_hdac_ext_link_stream_start(link_dev); 318 snd_hdac_ext_link_stream_start(link_dev);
318 break; 319 break;
319 case SNDRV_PCM_TRIGGER_SUSPEND: 320 case SNDRV_PCM_TRIGGER_SUSPEND:
321 case SNDRV_PCM_TRIGGER_STOP:
320 /* 322 /*
321 * clear and release link DMA channel. It will be assigned when 323 * clear link DMA channel. It will be assigned when
322 * hw_params is set up again after resume. 324 * hw_params is set up again after resume.
323 */ 325 */
324 ret = hda_link_config_ipc(hda_stream, dai->name, 326 ret = hda_link_config_ipc(hda_stream, dai->name,
325 DMA_CHAN_INVALID, substream->stream); 327 DMA_CHAN_INVALID, substream->stream);
326 if (ret < 0) 328 if (ret < 0)
327 return ret; 329 return ret;
328 stream_tag = hdac_stream(link_dev)->stream_tag; 330
329 snd_hdac_ext_link_clear_stream_id(link, stream_tag); 331 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
330 snd_hdac_ext_stream_release(link_dev, 332 stream_tag = hdac_stream(link_dev)->stream_tag;
331 HDAC_EXT_STREAM_TYPE_LINK); 333 snd_hdac_ext_link_clear_stream_id(link, stream_tag);
334 }
335
336 link_dev->link_prepared = 0;
332 337
333 /* fallthrough */ 338 /* fallthrough */
334 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 339 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
335 case SNDRV_PCM_TRIGGER_STOP:
336 snd_hdac_ext_link_stream_clear(link_dev); 340 snd_hdac_ext_link_stream_clear(link_dev);
337 break; 341 break;
338 default: 342 default:
@@ -369,8 +373,12 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream,
369 if (!link) 373 if (!link)
370 return -EINVAL; 374 return -EINVAL;
371 375
372 stream_tag = hdac_stream(link_dev)->stream_tag; 376 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
373 snd_hdac_ext_link_clear_stream_id(link, stream_tag); 377 stream_tag = hdac_stream(link_dev)->stream_tag;
378 snd_hdac_ext_link_clear_stream_id(link, stream_tag);
379 }
380
381 snd_soc_dai_set_dma_data(dai, substream, NULL);
374 snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK); 382 snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK);
375 link_dev->link_prepared = 0; 383 link_dev->link_prepared = 0;
376 384
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index 91de4785b6a3..fb55a3c5afd0 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -282,7 +282,7 @@ void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev)
282 HDA_DSP_REG_HIPCCTL_BUSY | HDA_DSP_REG_HIPCCTL_DONE, 0); 282 HDA_DSP_REG_HIPCCTL_BUSY | HDA_DSP_REG_HIPCCTL_DONE, 0);
283} 283}
284 284
285static int hda_suspend(struct snd_sof_dev *sdev, int state) 285static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
286{ 286{
287 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 287 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
288 const struct sof_intel_dsp_desc *chip = hda->desc; 288 const struct sof_intel_dsp_desc *chip = hda->desc;
@@ -295,6 +295,9 @@ static int hda_suspend(struct snd_sof_dev *sdev, int state)
295 hda_dsp_ipc_int_disable(sdev); 295 hda_dsp_ipc_int_disable(sdev);
296 296
297#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 297#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
298 if (runtime_suspend)
299 hda_codec_jack_wake_enable(sdev);
300
298 /* power down all hda link */ 301 /* power down all hda link */
299 snd_hdac_ext_bus_link_power_down_all(bus); 302 snd_hdac_ext_bus_link_power_down_all(bus);
300#endif 303#endif
@@ -329,7 +332,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, int state)
329 return 0; 332 return 0;
330} 333}
331 334
332static int hda_resume(struct snd_sof_dev *sdev) 335static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
333{ 336{
334#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 337#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
335 struct hdac_bus *bus = sof_to_bus(sdev); 338 struct hdac_bus *bus = sof_to_bus(sdev);
@@ -343,7 +346,6 @@ static int hda_resume(struct snd_sof_dev *sdev)
343 */ 346 */
344 snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0); 347 snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0);
345 348
346#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
347 /* reset and start hda controller */ 349 /* reset and start hda controller */
348 ret = hda_dsp_ctrl_init_chip(sdev, true); 350 ret = hda_dsp_ctrl_init_chip(sdev, true);
349 if (ret < 0) { 351 if (ret < 0) {
@@ -352,46 +354,11 @@ static int hda_resume(struct snd_sof_dev *sdev)
352 return ret; 354 return ret;
353 } 355 }
354 356
355 hda_dsp_ctrl_misc_clock_gating(sdev, false);
356
357 /* Reset stream-to-link mapping */
358 list_for_each_entry(hlink, &bus->hlink_list, list)
359 bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
360
361 hda_dsp_ctrl_misc_clock_gating(sdev, true);
362#else
363
364 hda_dsp_ctrl_misc_clock_gating(sdev, false);
365
366 /* reset controller */
367 ret = hda_dsp_ctrl_link_reset(sdev, true);
368 if (ret < 0) {
369 dev_err(sdev->dev,
370 "error: failed to reset controller during resume\n");
371 return ret;
372 }
373
374 /* take controller out of reset */
375 ret = hda_dsp_ctrl_link_reset(sdev, false);
376 if (ret < 0) {
377 dev_err(sdev->dev,
378 "error: failed to ready controller during resume\n");
379 return ret;
380 }
381
382 /* enable hda bus irq */
383 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
384 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
385 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN);
386
387 hda_dsp_ctrl_misc_clock_gating(sdev, true);
388#endif
389
390 /* enable ppcap interrupt */
391 hda_dsp_ctrl_ppcap_enable(sdev, true);
392 hda_dsp_ctrl_ppcap_int_enable(sdev, true);
393
394#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 357#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
358 /* check jack status */
359 if (runtime_resume)
360 hda_codec_jack_check(sdev);
361
395 /* turn off the links that were off before suspend */ 362 /* turn off the links that were off before suspend */
396 list_for_each_entry(hlink, &bus->hlink_list, list) { 363 list_for_each_entry(hlink, &bus->hlink_list, list) {
397 if (!hlink->ref_count) 364 if (!hlink->ref_count)
@@ -403,19 +370,23 @@ static int hda_resume(struct snd_sof_dev *sdev)
403 snd_hdac_bus_stop_cmd_io(bus); 370 snd_hdac_bus_stop_cmd_io(bus);
404#endif 371#endif
405 372
373 /* enable ppcap interrupt */
374 hda_dsp_ctrl_ppcap_enable(sdev, true);
375 hda_dsp_ctrl_ppcap_int_enable(sdev, true);
376
406 return 0; 377 return 0;
407} 378}
408 379
409int hda_dsp_resume(struct snd_sof_dev *sdev) 380int hda_dsp_resume(struct snd_sof_dev *sdev)
410{ 381{
411 /* init hda controller. DSP cores will be powered up during fw boot */ 382 /* init hda controller. DSP cores will be powered up during fw boot */
412 return hda_resume(sdev); 383 return hda_resume(sdev, false);
413} 384}
414 385
415int hda_dsp_runtime_resume(struct snd_sof_dev *sdev) 386int hda_dsp_runtime_resume(struct snd_sof_dev *sdev)
416{ 387{
417 /* init hda controller. DSP cores will be powered up during fw boot */ 388 /* init hda controller. DSP cores will be powered up during fw boot */
418 return hda_resume(sdev); 389 return hda_resume(sdev, true);
419} 390}
420 391
421int hda_dsp_runtime_idle(struct snd_sof_dev *sdev) 392int hda_dsp_runtime_idle(struct snd_sof_dev *sdev)
@@ -431,19 +402,19 @@ int hda_dsp_runtime_idle(struct snd_sof_dev *sdev)
431 return 0; 402 return 0;
432} 403}
433 404
434int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state) 405int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev)
435{ 406{
436 /* stop hda controller and power dsp off */ 407 /* stop hda controller and power dsp off */
437 return hda_suspend(sdev, state); 408 return hda_suspend(sdev, true);
438} 409}
439 410
440int hda_dsp_suspend(struct snd_sof_dev *sdev, int state) 411int hda_dsp_suspend(struct snd_sof_dev *sdev)
441{ 412{
442 struct hdac_bus *bus = sof_to_bus(sdev); 413 struct hdac_bus *bus = sof_to_bus(sdev);
443 int ret; 414 int ret;
444 415
445 /* stop hda controller and power dsp off */ 416 /* stop hda controller and power dsp off */
446 ret = hda_suspend(sdev, state); 417 ret = hda_suspend(sdev, false);
447 if (ret < 0) { 418 if (ret < 0) {
448 dev_err(bus->dev, "error: suspending dsp\n"); 419 dev_err(bus->dev, "error: suspending dsp\n");
449 return ret; 420 return ret;
@@ -454,30 +425,24 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, int state)
454 425
455int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev) 426int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
456{ 427{
457 struct hdac_bus *bus = sof_to_bus(sdev);
458 struct sof_intel_hda_stream *hda_stream;
459 struct hdac_ext_stream *stream;
460 struct hdac_stream *s;
461
462#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 428#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
429 struct hdac_bus *bus = sof_to_bus(sdev);
463 struct snd_soc_pcm_runtime *rtd; 430 struct snd_soc_pcm_runtime *rtd;
431 struct hdac_ext_stream *stream;
464 struct hdac_ext_link *link; 432 struct hdac_ext_link *link;
433 struct hdac_stream *s;
465 const char *name; 434 const char *name;
466 int stream_tag; 435 int stream_tag;
467#endif
468 436
469 /* set internal flag for BE */ 437 /* set internal flag for BE */
470 list_for_each_entry(s, &bus->stream_list, list) { 438 list_for_each_entry(s, &bus->stream_list, list) {
471 stream = stream_to_hdac_ext_stream(s); 439 stream = stream_to_hdac_ext_stream(s);
472 hda_stream = container_of(stream, struct sof_intel_hda_stream, 440
473 hda_stream);
474 hda_stream->hw_params_upon_resume = 1;
475#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
476 /* 441 /*
477 * clear and release stream. This should already be taken care 442 * clear stream. This should already be taken care for running
478 * for running streams when the SUSPEND trigger is called. 443 * streams when the SUSPEND trigger is called. But paused
479 * But paused streams do not get suspended, so this needs to be 444 * streams do not get suspended, so this needs to be done
480 * done explicitly during suspend. 445 * explicitly during suspend.
481 */ 446 */
482 if (stream->link_substream) { 447 if (stream->link_substream) {
483 rtd = snd_pcm_substream_chip(stream->link_substream); 448 rtd = snd_pcm_substream_chip(stream->link_substream);
@@ -485,12 +450,17 @@ int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
485 link = snd_hdac_ext_bus_get_link(bus, name); 450 link = snd_hdac_ext_bus_get_link(bus, name);
486 if (!link) 451 if (!link)
487 return -EINVAL; 452 return -EINVAL;
453
454 stream->link_prepared = 0;
455
456 if (hdac_stream(stream)->direction ==
457 SNDRV_PCM_STREAM_CAPTURE)
458 continue;
459
488 stream_tag = hdac_stream(stream)->stream_tag; 460 stream_tag = hdac_stream(stream)->stream_tag;
489 snd_hdac_ext_link_clear_stream_id(link, stream_tag); 461 snd_hdac_ext_link_clear_stream_id(link, stream_tag);
490 snd_hdac_ext_stream_release(stream,
491 HDAC_EXT_STREAM_TYPE_LINK);
492 } 462 }
493#endif
494 } 463 }
464#endif
495 return 0; 465 return 0;
496} 466}
diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c
index 2ecba91f5219..6aae6f18b3dc 100644
--- a/sound/soc/sof/intel/hda-ipc.c
+++ b/sound/soc/sof/intel/hda-ipc.c
@@ -266,156 +266,14 @@ out:
266 return ret; 266 return ret;
267} 267}
268 268
269/* IPC Firmware ready */ 269int hda_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev)
270
271static void ipc_get_windows(struct snd_sof_dev *sdev)
272{ 270{
273 struct sof_ipc_window_elem *elem; 271 return HDA_DSP_MBOX_UPLINK_OFFSET;
274 u32 outbox_offset = 0;
275 u32 stream_offset = 0;
276 u32 inbox_offset = 0;
277 u32 outbox_size = 0;
278 u32 stream_size = 0;
279 u32 inbox_size = 0;
280 int i;
281
282 if (!sdev->info_window) {
283 dev_err(sdev->dev, "error: have no window info\n");
284 return;
285 }
286
287 for (i = 0; i < sdev->info_window->num_windows; i++) {
288 elem = &sdev->info_window->window[i];
289
290 switch (elem->type) {
291 case SOF_IPC_REGION_UPBOX:
292 inbox_offset =
293 elem->offset + SRAM_WINDOW_OFFSET(elem->id);
294 inbox_size = elem->size;
295 snd_sof_debugfs_io_item(sdev,
296 sdev->bar[HDA_DSP_BAR] +
297 inbox_offset,
298 elem->size, "inbox",
299 SOF_DEBUGFS_ACCESS_D0_ONLY);
300 break;
301 case SOF_IPC_REGION_DOWNBOX:
302 outbox_offset =
303 elem->offset + SRAM_WINDOW_OFFSET(elem->id);
304 outbox_size = elem->size;
305 snd_sof_debugfs_io_item(sdev,
306 sdev->bar[HDA_DSP_BAR] +
307 outbox_offset,
308 elem->size, "outbox",
309 SOF_DEBUGFS_ACCESS_D0_ONLY);
310 break;
311 case SOF_IPC_REGION_TRACE:
312 snd_sof_debugfs_io_item(sdev,
313 sdev->bar[HDA_DSP_BAR] +
314 elem->offset +
315 SRAM_WINDOW_OFFSET
316 (elem->id),
317 elem->size, "etrace",
318 SOF_DEBUGFS_ACCESS_D0_ONLY);
319 break;
320 case SOF_IPC_REGION_DEBUG:
321 snd_sof_debugfs_io_item(sdev,
322 sdev->bar[HDA_DSP_BAR] +
323 elem->offset +
324 SRAM_WINDOW_OFFSET
325 (elem->id),
326 elem->size, "debug",
327 SOF_DEBUGFS_ACCESS_D0_ONLY);
328 break;
329 case SOF_IPC_REGION_STREAM:
330 stream_offset =
331 elem->offset + SRAM_WINDOW_OFFSET(elem->id);
332 stream_size = elem->size;
333 snd_sof_debugfs_io_item(sdev,
334 sdev->bar[HDA_DSP_BAR] +
335 elem->offset +
336 SRAM_WINDOW_OFFSET
337 (elem->id),
338 elem->size, "stream",
339 SOF_DEBUGFS_ACCESS_D0_ONLY);
340 break;
341 case SOF_IPC_REGION_REGS:
342 snd_sof_debugfs_io_item(sdev,
343 sdev->bar[HDA_DSP_BAR] +
344 elem->offset +
345 SRAM_WINDOW_OFFSET
346 (elem->id),
347 elem->size, "regs",
348 SOF_DEBUGFS_ACCESS_D0_ONLY);
349 break;
350 case SOF_IPC_REGION_EXCEPTION:
351 sdev->dsp_oops_offset = elem->offset +
352 SRAM_WINDOW_OFFSET(elem->id);
353 snd_sof_debugfs_io_item(sdev,
354 sdev->bar[HDA_DSP_BAR] +
355 elem->offset +
356 SRAM_WINDOW_OFFSET
357 (elem->id),
358 elem->size, "exception",
359 SOF_DEBUGFS_ACCESS_D0_ONLY);
360 break;
361 default:
362 dev_err(sdev->dev, "error: get illegal window info\n");
363 return;
364 }
365 }
366
367 if (outbox_size == 0 || inbox_size == 0) {
368 dev_err(sdev->dev, "error: get illegal mailbox window\n");
369 return;
370 }
371
372 snd_sof_dsp_mailbox_init(sdev, inbox_offset, inbox_size,
373 outbox_offset, outbox_size);
374 sdev->stream_box.offset = stream_offset;
375 sdev->stream_box.size = stream_size;
376
377 dev_dbg(sdev->dev, " mailbox upstream 0x%x - size 0x%x\n",
378 inbox_offset, inbox_size);
379 dev_dbg(sdev->dev, " mailbox downstream 0x%x - size 0x%x\n",
380 outbox_offset, outbox_size);
381 dev_dbg(sdev->dev, " stream region 0x%x - size 0x%x\n",
382 stream_offset, stream_size);
383} 272}
384 273
385/* check for ABI compatibility and create memory windows on first boot */ 274int hda_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id)
386int hda_dsp_ipc_fw_ready(struct snd_sof_dev *sdev, u32 msg_id)
387{ 275{
388 struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready; 276 return SRAM_WINDOW_OFFSET(id);
389 u32 offset;
390 int ret;
391
392 /* mailbox must be on 4k boundary */
393 offset = HDA_DSP_MBOX_UPLINK_OFFSET;
394
395 dev_dbg(sdev->dev, "ipc: DSP is ready 0x%8.8x offset 0x%x\n",
396 msg_id, offset);
397
398 /* no need to re-check version/ABI for subsequent boots */
399 if (!sdev->first_boot)
400 return 0;
401
402 /* copy data from the DSP FW ready offset */
403 sof_block_read(sdev, sdev->mmio_bar, offset, fw_ready,
404 sizeof(*fw_ready));
405
406 /* make sure ABI version is compatible */
407 ret = snd_sof_ipc_valid(sdev);
408 if (ret < 0)
409 return ret;
410
411 /* now check for extended data */
412 snd_sof_fw_parse_ext_data(sdev, sdev->mmio_bar,
413 HDA_DSP_MBOX_UPLINK_OFFSET +
414 sizeof(struct sof_ipc_fw_ready));
415
416 ipc_get_windows(sdev);
417
418 return 0;
419} 277}
420 278
421void hda_ipc_msg_data(struct snd_sof_dev *sdev, 279void hda_ipc_msg_data(struct snd_sof_dev *sdev,
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index ae50839fddfe..c72e9a09eee1 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -19,13 +19,11 @@
19#include <sound/hda_register.h> 19#include <sound/hda_register.h>
20 20
21#include <linux/module.h> 21#include <linux/module.h>
22#include <sound/intel-nhlt.h>
22#include <sound/sof.h> 23#include <sound/sof.h>
23#include <sound/sof/xtensa.h> 24#include <sound/sof/xtensa.h>
24#include "../ops.h" 25#include "../ops.h"
25#include "hda.h" 26#include "hda.h"
26#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
27#include "../../codecs/hdac_hda.h"
28#endif
29 27
30#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 28#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
31#include <sound/soc-acpi-intel-match.h> 29#include <sound/soc-acpi-intel-match.h>
@@ -46,6 +44,18 @@ struct hda_dsp_msg_code {
46 const char *msg; 44 const char *msg;
47}; 45};
48 46
47static bool hda_use_msi = IS_ENABLED(CONFIG_PCI);
48#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG)
49module_param_named(use_msi, hda_use_msi, bool, 0444);
50MODULE_PARM_DESC(use_msi, "SOF HDA use PCI MSI mode");
51#endif
52
53#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
54static int hda_dmic_num = -1;
55module_param_named(dmic_num, hda_dmic_num, int, 0444);
56MODULE_PARM_DESC(dmic_num, "SOF HDA DMIC number");
57#endif
58
49static const struct hda_dsp_msg_code hda_dsp_rom_msg[] = { 59static const struct hda_dsp_msg_code hda_dsp_rom_msg[] = {
50 {HDA_DSP_ROM_FW_MANIFEST_LOADED, "status: manifest loaded"}, 60 {HDA_DSP_ROM_FW_MANIFEST_LOADED, "status: manifest loaded"},
51 {HDA_DSP_ROM_FW_FW_LOADED, "status: fw loaded"}, 61 {HDA_DSP_ROM_FW_FW_LOADED, "status: fw loaded"},
@@ -236,7 +246,6 @@ static int hda_init(struct snd_sof_dev *sdev)
236{ 246{
237 struct hda_bus *hbus; 247 struct hda_bus *hbus;
238 struct hdac_bus *bus; 248 struct hdac_bus *bus;
239 struct hdac_ext_bus_ops *ext_ops = NULL;
240 struct pci_dev *pci = to_pci_dev(sdev->dev); 249 struct pci_dev *pci = to_pci_dev(sdev->dev);
241 int ret; 250 int ret;
242 251
@@ -244,10 +253,7 @@ static int hda_init(struct snd_sof_dev *sdev)
244 bus = sof_to_bus(sdev); 253 bus = sof_to_bus(sdev);
245 254
246 /* HDA bus init */ 255 /* HDA bus init */
247#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 256 sof_hda_bus_init(bus, &pci->dev);
248 ext_ops = snd_soc_hdac_hda_get_ops();
249#endif
250 sof_hda_bus_init(bus, &pci->dev, ext_ops);
251 257
252 /* Workaround for a communication error on CFL (bko#199007) and CNL */ 258 /* Workaround for a communication error on CFL (bko#199007) and CNL */
253 if (IS_CFL(pci) || IS_CNL(pci)) 259 if (IS_CFL(pci) || IS_CNL(pci))
@@ -284,8 +290,26 @@ static int hda_init(struct snd_sof_dev *sdev)
284 290
285#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 291#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
286 292
293static int check_nhlt_dmic(struct snd_sof_dev *sdev)
294{
295 struct nhlt_acpi_table *nhlt;
296 int dmic_num;
297
298 nhlt = intel_nhlt_init(sdev->dev);
299 if (nhlt) {
300 dmic_num = intel_nhlt_get_dmic_geo(sdev->dev, nhlt);
301 intel_nhlt_free(nhlt);
302 if (dmic_num == 2 || dmic_num == 4)
303 return dmic_num;
304 }
305
306 return 0;
307}
308
287static const char *fixup_tplg_name(struct snd_sof_dev *sdev, 309static const char *fixup_tplg_name(struct snd_sof_dev *sdev,
288 const char *sof_tplg_filename) 310 const char *sof_tplg_filename,
311 const char *idisp_str,
312 const char *dmic_str)
289{ 313{
290 const char *tplg_filename = NULL; 314 const char *tplg_filename = NULL;
291 char *filename; 315 char *filename;
@@ -299,7 +323,8 @@ static const char *fixup_tplg_name(struct snd_sof_dev *sdev,
299 split_ext = strsep(&filename, "."); 323 split_ext = strsep(&filename, ".");
300 if (split_ext) { 324 if (split_ext) {
301 tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, 325 tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
302 "%s-idisp.tplg", split_ext); 326 "%s%s%s.tplg",
327 split_ext, idisp_str, dmic_str);
303 if (!tplg_filename) 328 if (!tplg_filename)
304 return NULL; 329 return NULL;
305 } 330 }
@@ -318,6 +343,9 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
318 struct snd_sof_pdata *pdata = sdev->pdata; 343 struct snd_sof_pdata *pdata = sdev->pdata;
319 struct snd_soc_acpi_mach *mach; 344 struct snd_soc_acpi_mach *mach;
320 const char *tplg_filename; 345 const char *tplg_filename;
346 const char *idisp_str;
347 const char *dmic_str;
348 int dmic_num;
321 int codec_num = 0; 349 int codec_num = 0;
322 int i; 350 int i;
323#endif 351#endif
@@ -388,17 +416,39 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
388 dev_info(bus->dev, "using HDA machine driver %s now\n", 416 dev_info(bus->dev, "using HDA machine driver %s now\n",
389 hda_mach->drv_name); 417 hda_mach->drv_name);
390 418
391 /* fixup topology file for HDMI only platforms */ 419 if (codec_num == 1)
392 if (codec_num == 1) { 420 idisp_str = "-idisp";
393 /* use local variable for readability */ 421 else
394 tplg_filename = pdata->tplg_filename; 422 idisp_str = "";
395 tplg_filename = fixup_tplg_name(sdev, tplg_filename); 423
396 if (!tplg_filename) { 424 /* first check NHLT for DMICs */
397 hda_codec_i915_exit(sdev); 425 dmic_num = check_nhlt_dmic(sdev);
398 return ret; 426
399 } 427 /* allow for module parameter override */
400 pdata->tplg_filename = tplg_filename; 428 if (hda_dmic_num != -1)
429 dmic_num = hda_dmic_num;
430
431 switch (dmic_num) {
432 case 2:
433 dmic_str = "-2ch";
434 break;
435 case 4:
436 dmic_str = "-4ch";
437 break;
438 default:
439 dmic_num = 0;
440 dmic_str = "";
441 break;
401 } 442 }
443
444 tplg_filename = pdata->tplg_filename;
445 tplg_filename = fixup_tplg_name(sdev, tplg_filename,
446 idisp_str, dmic_str);
447 if (!tplg_filename) {
448 hda_codec_i915_exit(sdev);
449 return ret;
450 }
451 pdata->tplg_filename = tplg_filename;
402 } 452 }
403 } 453 }
404 454
@@ -535,11 +585,18 @@ int hda_dsp_probe(struct snd_sof_dev *sdev)
535 * register our IRQ 585 * register our IRQ
536 * let's try to enable msi firstly 586 * let's try to enable msi firstly
537 * if it fails, use legacy interrupt mode 587 * if it fails, use legacy interrupt mode
538 * TODO: support interrupt mode selection with kernel parameter 588 * TODO: support msi multiple vectors
539 * support msi multiple vectors
540 */ 589 */
541 ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI); 590 if (hda_use_msi && pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI) > 0) {
542 if (ret < 0) { 591 dev_info(sdev->dev, "use msi interrupt mode\n");
592 hdev->irq = pci_irq_vector(pci, 0);
593 /* ipc irq number is the same of hda irq */
594 sdev->ipc_irq = hdev->irq;
595 /* initialised to "false" by kzalloc() */
596 sdev->msi_enabled = true;
597 }
598
599 if (!sdev->msi_enabled) {
543 dev_info(sdev->dev, "use legacy interrupt mode\n"); 600 dev_info(sdev->dev, "use legacy interrupt mode\n");
544 /* 601 /*
545 * in IO-APIC mode, hda->irq and ipc_irq are using the same 602 * in IO-APIC mode, hda->irq and ipc_irq are using the same
@@ -547,13 +604,6 @@ int hda_dsp_probe(struct snd_sof_dev *sdev)
547 */ 604 */
548 hdev->irq = pci->irq; 605 hdev->irq = pci->irq;
549 sdev->ipc_irq = pci->irq; 606 sdev->ipc_irq = pci->irq;
550 sdev->msi_enabled = 0;
551 } else {
552 dev_info(sdev->dev, "use msi interrupt mode\n");
553 hdev->irq = pci_irq_vector(pci, 0);
554 /* ipc irq number is the same of hda irq */
555 sdev->ipc_irq = hdev->irq;
556 sdev->msi_enabled = 1;
557 } 607 }
558 608
559 dev_dbg(sdev->dev, "using HDA IRQ %d\n", hdev->irq); 609 dev_dbg(sdev->dev, "using HDA IRQ %d\n", hdev->irq);
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index d9c17146200b..5591841a1b6f 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -175,7 +175,7 @@
175#define HDA_DSP_STACK_DUMP_SIZE 32 175#define HDA_DSP_STACK_DUMP_SIZE 32
176 176
177/* ROM status/error values */ 177/* ROM status/error values */
178#define HDA_DSP_ROM_STS_MASK 0xf 178#define HDA_DSP_ROM_STS_MASK GENMASK(23, 0)
179#define HDA_DSP_ROM_INIT 0x1 179#define HDA_DSP_ROM_INIT 0x1
180#define HDA_DSP_ROM_FW_MANIFEST_LOADED 0x3 180#define HDA_DSP_ROM_FW_MANIFEST_LOADED 0x3
181#define HDA_DSP_ROM_FW_FW_LOADED 0x4 181#define HDA_DSP_ROM_FW_FW_LOADED 0x4
@@ -418,7 +418,6 @@ struct sof_intel_hda_stream {
418 struct snd_sof_dev *sdev; 418 struct snd_sof_dev *sdev;
419 struct hdac_ext_stream hda_stream; 419 struct hdac_ext_stream hda_stream;
420 struct sof_intel_stream stream; 420 struct sof_intel_stream stream;
421 int hw_params_upon_resume; /* set up hw_params upon resume */
422 int host_reserved; /* reserve host DMA channel */ 421 int host_reserved; /* reserve host DMA channel */
423}; 422};
424 423
@@ -453,9 +452,9 @@ int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev,
453void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev); 452void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev);
454void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev); 453void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev);
455 454
456int hda_dsp_suspend(struct snd_sof_dev *sdev, int state); 455int hda_dsp_suspend(struct snd_sof_dev *sdev);
457int hda_dsp_resume(struct snd_sof_dev *sdev); 456int hda_dsp_resume(struct snd_sof_dev *sdev);
458int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state); 457int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev);
459int hda_dsp_runtime_resume(struct snd_sof_dev *sdev); 458int hda_dsp_runtime_resume(struct snd_sof_dev *sdev);
460int hda_dsp_runtime_idle(struct snd_sof_dev *sdev); 459int hda_dsp_runtime_idle(struct snd_sof_dev *sdev);
461int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev); 460int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev);
@@ -520,7 +519,9 @@ int hda_ipc_pcm_params(struct snd_sof_dev *sdev,
520int hda_dsp_ipc_send_msg(struct snd_sof_dev *sdev, 519int hda_dsp_ipc_send_msg(struct snd_sof_dev *sdev,
521 struct snd_sof_ipc_msg *msg); 520 struct snd_sof_ipc_msg *msg);
522void hda_dsp_ipc_get_reply(struct snd_sof_dev *sdev); 521void hda_dsp_ipc_get_reply(struct snd_sof_dev *sdev);
523int hda_dsp_ipc_fw_ready(struct snd_sof_dev *sdev, u32 msg_id); 522int hda_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev);
523int hda_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id);
524
524irqreturn_t hda_dsp_ipc_irq_handler(int irq, void *context); 525irqreturn_t hda_dsp_ipc_irq_handler(int irq, void *context);
525irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context); 526irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context);
526int hda_dsp_ipc_cmd_done(struct snd_sof_dev *sdev, int dir); 527int hda_dsp_ipc_cmd_done(struct snd_sof_dev *sdev, int dir);
@@ -549,14 +550,15 @@ void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev);
549/* 550/*
550 * HDA bus operations. 551 * HDA bus operations.
551 */ 552 */
552void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev, 553void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev);
553 const struct hdac_ext_bus_ops *ext_ops);
554 554
555#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 555#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
556/* 556/*
557 * HDA Codec operations. 557 * HDA Codec operations.
558 */ 558 */
559int hda_codec_probe_bus(struct snd_sof_dev *sdev); 559int hda_codec_probe_bus(struct snd_sof_dev *sdev);
560void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev);
561void hda_codec_jack_check(struct snd_sof_dev *sdev);
560 562
561#endif /* CONFIG_SND_SOC_SOF_HDA */ 563#endif /* CONFIG_SND_SOC_SOF_HDA */
562 564
@@ -597,5 +599,7 @@ extern const struct sof_intel_dsp_desc apl_chip_info;
597extern const struct sof_intel_dsp_desc cnl_chip_info; 599extern const struct sof_intel_dsp_desc cnl_chip_info;
598extern const struct sof_intel_dsp_desc skl_chip_info; 600extern const struct sof_intel_dsp_desc skl_chip_info;
599extern const struct sof_intel_dsp_desc icl_chip_info; 601extern const struct sof_intel_dsp_desc icl_chip_info;
602extern const struct sof_intel_dsp_desc tgl_chip_info;
603extern const struct sof_intel_dsp_desc ehl_chip_info;
600 604
601#endif 605#endif
diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c
index 20dfca9c93b7..b2f359d2f7e5 100644
--- a/sound/soc/sof/ipc.c
+++ b/sound/soc/sof/ipc.c
@@ -17,12 +17,6 @@
17#include "sof-priv.h" 17#include "sof-priv.h"
18#include "ops.h" 18#include "ops.h"
19 19
20/*
21 * IPC message default size and timeout (ms).
22 * TODO: allow platforms to set size and timeout.
23 */
24#define IPC_TIMEOUT_MS 300
25
26static void ipc_trace_message(struct snd_sof_dev *sdev, u32 msg_id); 20static void ipc_trace_message(struct snd_sof_dev *sdev, u32 msg_id);
27static void ipc_stream_message(struct snd_sof_dev *sdev, u32 msg_cmd); 21static void ipc_stream_message(struct snd_sof_dev *sdev, u32 msg_cmd);
28 22
@@ -211,7 +205,7 @@ static int tx_wait_done(struct snd_sof_ipc *ipc, struct snd_sof_ipc_msg *msg,
211 205
212 /* wait for DSP IPC completion */ 206 /* wait for DSP IPC completion */
213 ret = wait_event_timeout(msg->waitq, msg->ipc_complete, 207 ret = wait_event_timeout(msg->waitq, msg->ipc_complete,
214 msecs_to_jiffies(IPC_TIMEOUT_MS)); 208 msecs_to_jiffies(sdev->ipc_timeout));
215 209
216 if (ret == 0) { 210 if (ret == 0) {
217 dev_err(sdev->dev, "error: ipc timed out for 0x%x size %d\n", 211 dev_err(sdev->dev, "error: ipc timed out for 0x%x size %d\n",
diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c
index 952a19091c58..d7f32745fefe 100644
--- a/sound/soc/sof/loader.c
+++ b/sound/soc/sof/loader.c
@@ -87,12 +87,180 @@ int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offset)
87} 87}
88EXPORT_SYMBOL(snd_sof_fw_parse_ext_data); 88EXPORT_SYMBOL(snd_sof_fw_parse_ext_data);
89 89
90/*
91 * IPC Firmware ready.
92 */
93static void sof_get_windows(struct snd_sof_dev *sdev)
94{
95 struct sof_ipc_window_elem *elem;
96 u32 outbox_offset = 0;
97 u32 stream_offset = 0;
98 u32 inbox_offset = 0;
99 u32 outbox_size = 0;
100 u32 stream_size = 0;
101 u32 inbox_size = 0;
102 int window_offset;
103 int bar;
104 int i;
105
106 if (!sdev->info_window) {
107 dev_err(sdev->dev, "error: have no window info\n");
108 return;
109 }
110
111 bar = snd_sof_dsp_get_bar_index(sdev, SOF_FW_BLK_TYPE_SRAM);
112 if (bar < 0) {
113 dev_err(sdev->dev, "error: have no bar mapping\n");
114 return;
115 }
116
117 for (i = 0; i < sdev->info_window->num_windows; i++) {
118 elem = &sdev->info_window->window[i];
119
120 window_offset = snd_sof_dsp_get_window_offset(sdev, elem->id);
121 if (window_offset < 0) {
122 dev_warn(sdev->dev, "warn: no offset for window %d\n",
123 elem->id);
124 continue;
125 }
126
127 switch (elem->type) {
128 case SOF_IPC_REGION_UPBOX:
129 inbox_offset = window_offset + elem->offset;
130 inbox_size = elem->size;
131 snd_sof_debugfs_io_item(sdev,
132 sdev->bar[bar] +
133 inbox_offset,
134 elem->size, "inbox",
135 SOF_DEBUGFS_ACCESS_D0_ONLY);
136 break;
137 case SOF_IPC_REGION_DOWNBOX:
138 outbox_offset = window_offset + elem->offset;
139 outbox_size = elem->size;
140 snd_sof_debugfs_io_item(sdev,
141 sdev->bar[bar] +
142 outbox_offset,
143 elem->size, "outbox",
144 SOF_DEBUGFS_ACCESS_D0_ONLY);
145 break;
146 case SOF_IPC_REGION_TRACE:
147 snd_sof_debugfs_io_item(sdev,
148 sdev->bar[bar] +
149 window_offset +
150 elem->offset,
151 elem->size, "etrace",
152 SOF_DEBUGFS_ACCESS_D0_ONLY);
153 break;
154 case SOF_IPC_REGION_DEBUG:
155 snd_sof_debugfs_io_item(sdev,
156 sdev->bar[bar] +
157 window_offset +
158 elem->offset,
159 elem->size, "debug",
160 SOF_DEBUGFS_ACCESS_D0_ONLY);
161 break;
162 case SOF_IPC_REGION_STREAM:
163 stream_offset = window_offset + elem->offset;
164 stream_size = elem->size;
165 snd_sof_debugfs_io_item(sdev,
166 sdev->bar[bar] +
167 stream_offset,
168 elem->size, "stream",
169 SOF_DEBUGFS_ACCESS_D0_ONLY);
170 break;
171 case SOF_IPC_REGION_REGS:
172 snd_sof_debugfs_io_item(sdev,
173 sdev->bar[bar] +
174 window_offset +
175 elem->offset,
176 elem->size, "regs",
177 SOF_DEBUGFS_ACCESS_D0_ONLY);
178 break;
179 case SOF_IPC_REGION_EXCEPTION:
180 sdev->dsp_oops_offset = window_offset + elem->offset;
181 snd_sof_debugfs_io_item(sdev,
182 sdev->bar[bar] +
183 window_offset +
184 elem->offset,
185 elem->size, "exception",
186 SOF_DEBUGFS_ACCESS_D0_ONLY);
187 break;
188 default:
189 dev_err(sdev->dev, "error: get illegal window info\n");
190 return;
191 }
192 }
193
194 if (outbox_size == 0 || inbox_size == 0) {
195 dev_err(sdev->dev, "error: get illegal mailbox window\n");
196 return;
197 }
198
199 snd_sof_dsp_mailbox_init(sdev, inbox_offset, inbox_size,
200 outbox_offset, outbox_size);
201 sdev->stream_box.offset = stream_offset;
202 sdev->stream_box.size = stream_size;
203
204 dev_dbg(sdev->dev, " mailbox upstream 0x%x - size 0x%x\n",
205 inbox_offset, inbox_size);
206 dev_dbg(sdev->dev, " mailbox downstream 0x%x - size 0x%x\n",
207 outbox_offset, outbox_size);
208 dev_dbg(sdev->dev, " stream region 0x%x - size 0x%x\n",
209 stream_offset, stream_size);
210}
211
212/* check for ABI compatibility and create memory windows on first boot */
213int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id)
214{
215 struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready;
216 int offset;
217 int bar;
218 int ret;
219
220 /* mailbox must be on 4k boundary */
221 offset = snd_sof_dsp_get_mailbox_offset(sdev);
222 if (offset < 0) {
223 dev_err(sdev->dev, "error: have no mailbox offset\n");
224 return offset;
225 }
226
227 bar = snd_sof_dsp_get_bar_index(sdev, SOF_FW_BLK_TYPE_SRAM);
228 if (bar < 0) {
229 dev_err(sdev->dev, "error: have no bar mapping\n");
230 return -EINVAL;
231 }
232
233 dev_dbg(sdev->dev, "ipc: DSP is ready 0x%8.8x offset 0x%x\n",
234 msg_id, offset);
235
236 /* no need to re-check version/ABI for subsequent boots */
237 if (!sdev->first_boot)
238 return 0;
239
240 /* copy data from the DSP FW ready offset */
241 sof_block_read(sdev, bar, offset, fw_ready, sizeof(*fw_ready));
242
243 /* make sure ABI version is compatible */
244 ret = snd_sof_ipc_valid(sdev);
245 if (ret < 0)
246 return ret;
247
248 /* now check for extended data */
249 snd_sof_fw_parse_ext_data(sdev, bar, offset +
250 sizeof(struct sof_ipc_fw_ready));
251
252 sof_get_windows(sdev);
253
254 return 0;
255}
256EXPORT_SYMBOL(sof_fw_ready);
257
90/* generic module parser for mmaped DSPs */ 258/* generic module parser for mmaped DSPs */
91int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev, 259int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev,
92 struct snd_sof_mod_hdr *module) 260 struct snd_sof_mod_hdr *module)
93{ 261{
94 struct snd_sof_blk_hdr *block; 262 struct snd_sof_blk_hdr *block;
95 int count; 263 int count, bar;
96 u32 offset; 264 u32 offset;
97 size_t remaining; 265 size_t remaining;
98 266
@@ -123,11 +291,19 @@ int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev,
123 291
124 switch (block->type) { 292 switch (block->type) {
125 case SOF_FW_BLK_TYPE_RSRVD0: 293 case SOF_FW_BLK_TYPE_RSRVD0:
126 case SOF_FW_BLK_TYPE_SRAM...SOF_FW_BLK_TYPE_RSRVD14: 294 case SOF_FW_BLK_TYPE_ROM...SOF_FW_BLK_TYPE_RSRVD14:
127 continue; /* not handled atm */ 295 continue; /* not handled atm */
128 case SOF_FW_BLK_TYPE_IRAM: 296 case SOF_FW_BLK_TYPE_IRAM:
129 case SOF_FW_BLK_TYPE_DRAM: 297 case SOF_FW_BLK_TYPE_DRAM:
298 case SOF_FW_BLK_TYPE_SRAM:
130 offset = block->offset; 299 offset = block->offset;
300 bar = snd_sof_dsp_get_bar_index(sdev, block->type);
301 if (bar < 0) {
302 dev_err(sdev->dev,
303 "error: no BAR mapping for block type 0x%x\n",
304 block->type);
305 return bar;
306 }
131 break; 307 break;
132 default: 308 default:
133 dev_err(sdev->dev, "error: bad type 0x%x for block 0x%x\n", 309 dev_err(sdev->dev, "error: bad type 0x%x for block 0x%x\n",
@@ -145,7 +321,7 @@ int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev,
145 block->size); 321 block->size);
146 return -EINVAL; 322 return -EINVAL;
147 } 323 }
148 snd_sof_dsp_block_write(sdev, sdev->mmio_bar, offset, 324 snd_sof_dsp_block_write(sdev, bar, offset,
149 block + 1, block->size); 325 block + 1, block->size);
150 326
151 if (remaining < block->size) { 327 if (remaining < block->size) {
diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h
index b1c27615b805..824d36fe59fd 100644
--- a/sound/soc/sof/ops.h
+++ b/sound/soc/sof/ops.h
@@ -100,6 +100,43 @@ static inline int snd_sof_dsp_post_fw_run(struct snd_sof_dev *sdev)
100 return 0; 100 return 0;
101} 101}
102 102
103/* misc */
104
105/**
106 * snd_sof_dsp_get_bar_index - Maps a section type with a BAR index
107 *
108 * @sdev: sof device
109 * @type: section type as described by snd_sof_fw_blk_type
110 *
111 * Returns the corresponding BAR index (a positive integer) or -EINVAL
112 * in case there is no mapping
113 */
114static inline int snd_sof_dsp_get_bar_index(struct snd_sof_dev *sdev, u32 type)
115{
116 if (sof_ops(sdev)->get_bar_index)
117 return sof_ops(sdev)->get_bar_index(sdev, type);
118
119 return sdev->mmio_bar;
120}
121
122static inline int snd_sof_dsp_get_mailbox_offset(struct snd_sof_dev *sdev)
123{
124 if (sof_ops(sdev)->get_mailbox_offset)
125 return sof_ops(sdev)->get_mailbox_offset(sdev);
126
127 dev_err(sdev->dev, "error: %s not defined\n", __func__);
128 return -ENOTSUPP;
129}
130
131static inline int snd_sof_dsp_get_window_offset(struct snd_sof_dev *sdev,
132 u32 id)
133{
134 if (sof_ops(sdev)->get_window_offset)
135 return sof_ops(sdev)->get_window_offset(sdev, id);
136
137 dev_err(sdev->dev, "error: %s not defined\n", __func__);
138 return -ENOTSUPP;
139}
103/* power management */ 140/* power management */
104static inline int snd_sof_dsp_resume(struct snd_sof_dev *sdev) 141static inline int snd_sof_dsp_resume(struct snd_sof_dev *sdev)
105{ 142{
@@ -109,10 +146,10 @@ static inline int snd_sof_dsp_resume(struct snd_sof_dev *sdev)
109 return 0; 146 return 0;
110} 147}
111 148
112static inline int snd_sof_dsp_suspend(struct snd_sof_dev *sdev, int state) 149static inline int snd_sof_dsp_suspend(struct snd_sof_dev *sdev)
113{ 150{
114 if (sof_ops(sdev)->suspend) 151 if (sof_ops(sdev)->suspend)
115 return sof_ops(sdev)->suspend(sdev, state); 152 return sof_ops(sdev)->suspend(sdev);
116 153
117 return 0; 154 return 0;
118} 155}
@@ -125,11 +162,10 @@ static inline int snd_sof_dsp_runtime_resume(struct snd_sof_dev *sdev)
125 return 0; 162 return 0;
126} 163}
127 164
128static inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev, 165static inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev)
129 int state)
130{ 166{
131 if (sof_ops(sdev)->runtime_suspend) 167 if (sof_ops(sdev)->runtime_suspend)
132 return sof_ops(sdev)->runtime_suspend(sdev, state); 168 return sof_ops(sdev)->runtime_suspend(sdev);
133 169
134 return 0; 170 return 0;
135} 171}
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 334e9d59b1ba..e3f6a6dc0f36 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -208,11 +208,31 @@ static int sof_pcm_hw_params(struct snd_pcm_substream *substream,
208 if (ret < 0) 208 if (ret < 0)
209 return ret; 209 return ret;
210 210
211 spcm->prepared[substream->stream] = true;
212
211 /* save pcm hw_params */ 213 /* save pcm hw_params */
212 memcpy(&spcm->params[substream->stream], params, sizeof(*params)); 214 memcpy(&spcm->params[substream->stream], params, sizeof(*params));
213 215
214 /* clear hw_params_upon_resume flag */ 216 return ret;
215 spcm->hw_params_upon_resume[substream->stream] = 0; 217}
218
219static int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream,
220 struct snd_sof_dev *sdev,
221 struct snd_sof_pcm *spcm)
222{
223 struct sof_ipc_stream stream;
224 struct sof_ipc_reply reply;
225 int ret;
226
227 stream.hdr.size = sizeof(stream);
228 stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
229 stream.comp_id = spcm->stream[substream->stream].comp_id;
230
231 /* send IPC to the DSP */
232 ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
233 sizeof(stream), &reply, sizeof(reply));
234 if (!ret)
235 spcm->prepared[substream->stream] = false;
216 236
217 return ret; 237 return ret;
218} 238}
@@ -224,8 +244,6 @@ static int sof_pcm_hw_free(struct snd_pcm_substream *substream)
224 snd_soc_rtdcom_lookup(rtd, DRV_NAME); 244 snd_soc_rtdcom_lookup(rtd, DRV_NAME);
225 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); 245 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
226 struct snd_sof_pcm *spcm; 246 struct snd_sof_pcm *spcm;
227 struct sof_ipc_stream stream;
228 struct sof_ipc_reply reply;
229 int ret; 247 int ret;
230 248
231 /* nothing to do for BE */ 249 /* nothing to do for BE */
@@ -236,16 +254,13 @@ static int sof_pcm_hw_free(struct snd_pcm_substream *substream)
236 if (!spcm) 254 if (!spcm)
237 return -EINVAL; 255 return -EINVAL;
238 256
257 if (!spcm->prepared[substream->stream])
258 return 0;
259
239 dev_dbg(sdev->dev, "pcm: free stream %d dir %d\n", spcm->pcm.pcm_id, 260 dev_dbg(sdev->dev, "pcm: free stream %d dir %d\n", spcm->pcm.pcm_id,
240 substream->stream); 261 substream->stream);
241 262
242 stream.hdr.size = sizeof(stream); 263 ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
243 stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
244 stream.comp_id = spcm->stream[substream->stream].comp_id;
245
246 /* send IPC to the DSP */
247 ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
248 sizeof(stream), &reply, sizeof(reply));
249 264
250 snd_pcm_lib_free_pages(substream); 265 snd_pcm_lib_free_pages(substream);
251 266
@@ -278,11 +293,7 @@ static int sof_pcm_prepare(struct snd_pcm_substream *substream)
278 if (!spcm) 293 if (!spcm)
279 return -EINVAL; 294 return -EINVAL;
280 295
281 /* 296 if (spcm->prepared[substream->stream])
282 * check if hw_params needs to be set-up again.
283 * This is only needed when resuming from system sleep.
284 */
285 if (!spcm->hw_params_upon_resume[substream->stream])
286 return 0; 297 return 0;
287 298
288 dev_dbg(sdev->dev, "pcm: prepare stream %d dir %d\n", spcm->pcm.pcm_id, 299 dev_dbg(sdev->dev, "pcm: prepare stream %d dir %d\n", spcm->pcm.pcm_id,
@@ -311,6 +322,7 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
311 struct snd_sof_pcm *spcm; 322 struct snd_sof_pcm *spcm;
312 struct sof_ipc_stream stream; 323 struct sof_ipc_stream stream;
313 struct sof_ipc_reply reply; 324 struct sof_ipc_reply reply;
325 bool reset_hw_params = false;
314 int ret; 326 int ret;
315 327
316 /* nothing to do for BE */ 328 /* nothing to do for BE */
@@ -351,6 +363,7 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
351 case SNDRV_PCM_TRIGGER_SUSPEND: 363 case SNDRV_PCM_TRIGGER_SUSPEND:
352 case SNDRV_PCM_TRIGGER_STOP: 364 case SNDRV_PCM_TRIGGER_STOP:
353 stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP; 365 stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP;
366 reset_hw_params = true;
354 break; 367 break;
355 default: 368 default:
356 dev_err(sdev->dev, "error: unhandled trigger cmd %d\n", cmd); 369 dev_err(sdev->dev, "error: unhandled trigger cmd %d\n", cmd);
@@ -363,21 +376,10 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
363 ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream, 376 ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
364 sizeof(stream), &reply, sizeof(reply)); 377 sizeof(stream), &reply, sizeof(reply));
365 378
366 if (ret < 0 || cmd != SNDRV_PCM_TRIGGER_SUSPEND) 379 if (!ret && reset_hw_params)
367 return ret; 380 ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
368 381
369 /* 382 return ret;
370 * The hw_free op is usually called when the pcm stream is closed.
371 * Since the stream is not closed during suspend, the DSP needs to be
372 * notified explicitly to free pcm to prevent errors upon resume.
373 */
374 stream.hdr.size = sizeof(stream);
375 stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
376 stream.comp_id = spcm->stream[substream->stream].comp_id;
377
378 /* send IPC to the DSP */
379 return sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
380 sizeof(stream), &reply, sizeof(reply));
381} 383}
382 384
383static snd_pcm_uframes_t sof_pcm_pointer(struct snd_pcm_substream *substream) 385static snd_pcm_uframes_t sof_pcm_pointer(struct snd_pcm_substream *substream)
@@ -481,6 +483,7 @@ static int sof_pcm_open(struct snd_pcm_substream *substream)
481 spcm->stream[substream->stream].posn.host_posn = 0; 483 spcm->stream[substream->stream].posn.host_posn = 0;
482 spcm->stream[substream->stream].posn.dai_posn = 0; 484 spcm->stream[substream->stream].posn.dai_posn = 0;
483 spcm->stream[substream->stream].substream = substream; 485 spcm->stream[substream->stream].substream = substream;
486 spcm->prepared[substream->stream] = false;
484 487
485 ret = snd_sof_pcm_platform_open(sdev, substream); 488 ret = snd_sof_pcm_platform_open(sdev, substream);
486 if (ret < 0) 489 if (ret < 0)
@@ -672,6 +675,9 @@ static int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
672 case SOF_DAI_INTEL_HDA: 675 case SOF_DAI_INTEL_HDA:
673 /* do nothing for HDA dai_link */ 676 /* do nothing for HDA dai_link */
674 break; 677 break;
678 case SOF_DAI_INTEL_ALH:
679 /* do nothing for ALH dai_link */
680 break;
675 default: 681 default:
676 dev_err(sdev->dev, "error: invalid DAI type %d\n", 682 dev_err(sdev->dev, "error: invalid DAI type %d\n",
677 dai->dai_config->type); 683 dai->dai_config->type);
diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c
index 278abfd10490..e23beaeefe00 100644
--- a/sound/soc/sof/pm.c
+++ b/sound/soc/sof/pm.c
@@ -233,7 +233,7 @@ static int sof_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
233 233
234 state = substream->runtime->status->state; 234 state = substream->runtime->status->state;
235 if (state == SNDRV_PCM_STATE_SUSPENDED) 235 if (state == SNDRV_PCM_STATE_SUSPENDED)
236 spcm->hw_params_upon_resume[dir] = 1; 236 spcm->prepared[dir] = false;
237 } 237 }
238 } 238 }
239 239
@@ -377,9 +377,9 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
377 377
378 /* power down all DSP cores */ 378 /* power down all DSP cores */
379 if (runtime_suspend) 379 if (runtime_suspend)
380 ret = snd_sof_dsp_runtime_suspend(sdev, 0); 380 ret = snd_sof_dsp_runtime_suspend(sdev);
381 else 381 else
382 ret = snd_sof_dsp_suspend(sdev, 0); 382 ret = snd_sof_dsp_suspend(sdev);
383 if (ret < 0) 383 if (ret < 0)
384 dev_err(sdev->dev, 384 dev_err(sdev->dev,
385 "error: failed to power down DSP during suspend %d\n", 385 "error: failed to power down DSP during suspend %d\n",
diff --git a/sound/soc/sof/sof-of-dev.c b/sound/soc/sof/sof-of-dev.c
new file mode 100644
index 000000000000..28a9692974e5
--- /dev/null
+++ b/sound/soc/sof/sof-of-dev.c
@@ -0,0 +1,143 @@
1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2//
3// Copyright 2019 NXP
4//
5// Author: Daniel Baluta <daniel.baluta@nxp.com>
6//
7
8#include <linux/firmware.h>
9#include <linux/module.h>
10#include <linux/pm_runtime.h>
11#include <sound/sof.h>
12
13#include "ops.h"
14
15extern struct snd_sof_dsp_ops sof_imx8_ops;
16
17/* platform specific devices */
18#if IS_ENABLED(CONFIG_SND_SOC_SOF_IMX8)
19static struct sof_dev_desc sof_of_imx8qxp_desc = {
20 .default_fw_path = "imx/sof",
21 .default_tplg_path = "imx/sof-tplg",
22 .nocodec_fw_filename = "sof-imx8.ri",
23 .nocodec_tplg_filename = "sof-imx8-nocodec.tplg",
24 .ops = &sof_imx8_ops,
25};
26#endif
27
28static const struct dev_pm_ops sof_of_pm = {
29 SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume)
30 SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume,
31 NULL)
32};
33
34static void sof_of_probe_complete(struct device *dev)
35{
36 /* allow runtime_pm */
37 pm_runtime_set_autosuspend_delay(dev, SND_SOF_SUSPEND_DELAY_MS);
38 pm_runtime_use_autosuspend(dev);
39 pm_runtime_enable(dev);
40}
41
42static int sof_of_probe(struct platform_device *pdev)
43{
44 struct device *dev = &pdev->dev;
45 const struct sof_dev_desc *desc;
46 /*TODO: create a generic snd_soc_xxx_mach */
47 struct snd_soc_acpi_mach *mach;
48 struct snd_sof_pdata *sof_pdata;
49 const struct snd_sof_dsp_ops *ops;
50 int ret;
51
52 dev_info(&pdev->dev, "DT DSP detected");
53
54 sof_pdata = devm_kzalloc(dev, sizeof(*sof_pdata), GFP_KERNEL);
55 if (!sof_pdata)
56 return -ENOMEM;
57
58 desc = device_get_match_data(dev);
59 if (!desc)
60 return -ENODEV;
61
62 /* get ops for platform */
63 ops = desc->ops;
64 if (!ops) {
65 dev_err(dev, "error: no matching DT descriptor ops\n");
66 return -ENODEV;
67 }
68
69#if IS_ENABLED(CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE)
70 /* force nocodec mode */
71 dev_warn(dev, "Force to use nocodec mode\n");
72 mach = devm_kzalloc(dev, sizeof(*mach), GFP_KERNEL);
73 if (!mach)
74 return -ENOMEM;
75 ret = sof_nocodec_setup(dev, sof_pdata, mach, desc, ops);
76 if (ret < 0)
77 return ret;
78#else
79 /* TODO: implement case where we actually have a codec */
80 return -ENODEV;
81#endif
82
83 if (mach)
84 mach->mach_params.platform = dev_name(dev);
85
86 sof_pdata->machine = mach;
87 sof_pdata->desc = desc;
88 sof_pdata->dev = &pdev->dev;
89 sof_pdata->platform = dev_name(dev);
90
91 /* TODO: read alternate fw and tplg filenames from DT */
92 sof_pdata->fw_filename_prefix = sof_pdata->desc->default_fw_path;
93 sof_pdata->tplg_filename_prefix = sof_pdata->desc->default_tplg_path;
94
95#if IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
96 /* set callback to enable runtime_pm */
97 sof_pdata->sof_probe_complete = sof_of_probe_complete;
98#endif
99 /* call sof helper for DSP hardware probe */
100 ret = snd_sof_device_probe(dev, sof_pdata);
101 if (ret) {
102 dev_err(dev, "error: failed to probe DSP hardware\n");
103 return ret;
104 }
105
106#if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
107 sof_of_probe_complete(dev);
108#endif
109
110 return ret;
111}
112
113static int sof_of_remove(struct platform_device *pdev)
114{
115 pm_runtime_disable(&pdev->dev);
116
117 /* call sof helper for DSP hardware remove */
118 snd_sof_device_remove(&pdev->dev);
119
120 return 0;
121}
122
123static const struct of_device_id sof_of_ids[] = {
124#if IS_ENABLED(CONFIG_SND_SOC_SOF_IMX8)
125 { .compatible = "fsl,imx8qxp-dsp", .data = &sof_of_imx8qxp_desc},
126#endif
127 { }
128};
129MODULE_DEVICE_TABLE(of, sof_of_ids);
130
131/* DT driver definition */
132static struct platform_driver snd_sof_of_driver = {
133 .probe = sof_of_probe,
134 .remove = sof_of_remove,
135 .driver = {
136 .name = "sof-audio-of",
137 .pm = &sof_of_pm,
138 .of_match_table = sof_of_ids,
139 },
140};
141module_platform_driver(snd_sof_of_driver);
142
143MODULE_LICENSE("Dual BSD/GPL");
diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
index 65d1bac4c6b8..d66412a77873 100644
--- a/sound/soc/sof/sof-pci-dev.c
+++ b/sound/soc/sof/sof-pci-dev.c
@@ -203,6 +203,42 @@ static const struct sof_dev_desc kbl_desc = {
203}; 203};
204#endif 204#endif
205 205
206#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
207static const struct sof_dev_desc tgl_desc = {
208 .machines = snd_soc_acpi_intel_tgl_machines,
209 .resindex_lpe_base = 0,
210 .resindex_pcicfg_base = -1,
211 .resindex_imr_base = -1,
212 .irqindex_host_ipc = -1,
213 .resindex_dma_base = -1,
214 .chip_info = &tgl_chip_info,
215 .default_fw_path = "intel/sof",
216 .default_tplg_path = "intel/sof-tplg",
217 .nocodec_fw_filename = "sof-tgl.ri",
218 .nocodec_tplg_filename = "sof-tgl-nocodec.tplg",
219 .ops = &sof_cnl_ops,
220 .arch_ops = &sof_xtensa_arch_ops
221};
222#endif
223
224#if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)
225static const struct sof_dev_desc ehl_desc = {
226 .machines = snd_soc_acpi_intel_ehl_machines,
227 .resindex_lpe_base = 0,
228 .resindex_pcicfg_base = -1,
229 .resindex_imr_base = -1,
230 .irqindex_host_ipc = -1,
231 .resindex_dma_base = -1,
232 .chip_info = &ehl_chip_info,
233 .default_fw_path = "intel/sof",
234 .default_tplg_path = "intel/sof-tplg",
235 .nocodec_fw_filename = "sof-ehl.ri",
236 .nocodec_tplg_filename = "sof-ehl-nocodec.tplg",
237 .ops = &sof_cnl_ops,
238 .arch_ops = &sof_xtensa_arch_ops
239};
240#endif
241
206static const struct dev_pm_ops sof_pci_pm = { 242static const struct dev_pm_ops sof_pci_pm = {
207 SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume) 243 SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume)
208 SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, 244 SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume,
@@ -223,6 +259,9 @@ static void sof_pci_probe_complete(struct device *dev)
223 */ 259 */
224 pm_runtime_allow(dev); 260 pm_runtime_allow(dev);
225 261
262 /* mark last_busy for pm_runtime to make sure not suspend immediately */
263 pm_runtime_mark_last_busy(dev);
264
226 /* follow recommendation in pci-driver.c to decrement usage counter */ 265 /* follow recommendation in pci-driver.c to decrement usage counter */
227 pm_runtime_put_noidle(dev); 266 pm_runtime_put_noidle(dev);
228} 267}
@@ -382,6 +421,14 @@ static const struct pci_device_id sof_pci_ids[] = {
382 { PCI_DEVICE(0x8086, 0x06c8), 421 { PCI_DEVICE(0x8086, 0x06c8),
383 .driver_data = (unsigned long)&cml_desc}, 422 .driver_data = (unsigned long)&cml_desc},
384#endif 423#endif
424#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
425 { PCI_DEVICE(0x8086, 0xa0c8),
426 .driver_data = (unsigned long)&tgl_desc},
427#endif
428#if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)
429 { PCI_DEVICE(0x8086, 0x4b55),
430 .driver_data = (unsigned long)&ehl_desc},
431#endif
385 { 0, } 432 { 0, }
386}; 433};
387MODULE_DEVICE_TABLE(pci, sof_pci_ids); 434MODULE_DEVICE_TABLE(pci, sof_pci_ids);
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index b8c0b2a22684..730f3259dd02 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -171,10 +171,9 @@ struct snd_sof_dsp_ops {
171 int (*post_fw_run)(struct snd_sof_dev *sof_dev); /* optional */ 171 int (*post_fw_run)(struct snd_sof_dev *sof_dev); /* optional */
172 172
173 /* DSP PM */ 173 /* DSP PM */
174 int (*suspend)(struct snd_sof_dev *sof_dev, int state); /* optional */ 174 int (*suspend)(struct snd_sof_dev *sof_dev); /* optional */
175 int (*resume)(struct snd_sof_dev *sof_dev); /* optional */ 175 int (*resume)(struct snd_sof_dev *sof_dev); /* optional */
176 int (*runtime_suspend)(struct snd_sof_dev *sof_dev, 176 int (*runtime_suspend)(struct snd_sof_dev *sof_dev); /* optional */
177 int state); /* optional */
178 int (*runtime_resume)(struct snd_sof_dev *sof_dev); /* optional */ 177 int (*runtime_resume)(struct snd_sof_dev *sof_dev); /* optional */
179 int (*runtime_idle)(struct snd_sof_dev *sof_dev); /* optional */ 178 int (*runtime_idle)(struct snd_sof_dev *sof_dev); /* optional */
180 int (*set_hw_params_upon_resume)(struct snd_sof_dev *sdev); /* optional */ 179 int (*set_hw_params_upon_resume)(struct snd_sof_dev *sdev); /* optional */
@@ -196,6 +195,13 @@ struct snd_sof_dsp_ops {
196 int (*trace_trigger)(struct snd_sof_dev *sdev, 195 int (*trace_trigger)(struct snd_sof_dev *sdev,
197 int cmd); /* optional */ 196 int cmd); /* optional */
198 197
198 /* misc */
199 int (*get_bar_index)(struct snd_sof_dev *sdev,
200 u32 type); /* optional */
201 int (*get_mailbox_offset)(struct snd_sof_dev *sdev);/* mandatory for common loader code */
202 int (*get_window_offset)(struct snd_sof_dev *sdev,
203 u32 id);/* mandatory for common loader code */
204
199 /* DAI ops */ 205 /* DAI ops */
200 struct snd_soc_dai_driver *drv; 206 struct snd_soc_dai_driver *drv;
201 int num_drv; 207 int num_drv;
@@ -228,7 +234,6 @@ enum sof_debugfs_access_type {
228 234
229/* FS entry for debug files that can expose DSP memories, registers */ 235/* FS entry for debug files that can expose DSP memories, registers */
230struct snd_sof_dfsentry { 236struct snd_sof_dfsentry {
231 struct dentry *dfsentry;
232 size_t size; 237 size_t size;
233 enum sof_dfsentry_type type; 238 enum sof_dfsentry_type type;
234 /* 239 /*
@@ -297,7 +302,7 @@ struct snd_sof_pcm {
297 struct snd_sof_pcm_stream stream[2]; 302 struct snd_sof_pcm_stream stream[2];
298 struct list_head list; /* list in sdev pcm list */ 303 struct list_head list; /* list in sdev pcm list */
299 struct snd_pcm_hw_params params[2]; 304 struct snd_pcm_hw_params params[2];
300 int hw_params_upon_resume[2]; /* set up hw_params upon resume */ 305 bool prepared[2]; /* PCM_PARAMS set successfully */
301}; 306};
302 307
303/* ALSA SOF Kcontrol device */ 308/* ALSA SOF Kcontrol device */
@@ -433,7 +438,7 @@ struct snd_sof_dev {
433 u32 dtrace_error; 438 u32 dtrace_error;
434 u32 dtrace_draining; 439 u32 dtrace_draining;
435 440
436 u32 msi_enabled; 441 bool msi_enabled;
437 442
438 void *private; /* core does not touch this */ 443 void *private; /* core does not touch this */
439}; 444};
@@ -637,6 +642,8 @@ void sof_block_write(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *src,
637void sof_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *dest, 642void sof_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *dest,
638 size_t size); 643 size_t size);
639 644
645int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id);
646
640void intel_ipc_msg_data(struct snd_sof_dev *sdev, 647void intel_ipc_msg_data(struct snd_sof_dev *sdev,
641 struct snd_pcm_substream *substream, 648 struct snd_pcm_substream *substream,
642 void *p, size_t sz); 649 void *p, size_t sz);
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index 432ae343f960..fc85efbad378 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -42,6 +42,13 @@
42/* size of tplg abi in byte */ 42/* size of tplg abi in byte */
43#define SOF_TPLG_ABI_SIZE 3 43#define SOF_TPLG_ABI_SIZE 3
44 44
45struct sof_widget_data {
46 int ctrl_type;
47 int ipc_cmd;
48 struct sof_abi_hdr *pdata;
49 struct snd_sof_control *control;
50};
51
45/* send pcm params ipc */ 52/* send pcm params ipc */
46static int ipc_pcm_params(struct snd_sof_widget *swidget, int dir) 53static int ipc_pcm_params(struct snd_sof_widget *swidget, int dir)
47{ 54{
@@ -339,6 +346,9 @@ static const struct sof_dai_types sof_dais[] = {
339 {"SSP", SOF_DAI_INTEL_SSP}, 346 {"SSP", SOF_DAI_INTEL_SSP},
340 {"HDA", SOF_DAI_INTEL_HDA}, 347 {"HDA", SOF_DAI_INTEL_HDA},
341 {"DMIC", SOF_DAI_INTEL_DMIC}, 348 {"DMIC", SOF_DAI_INTEL_DMIC},
349 {"ALH", SOF_DAI_INTEL_ALH},
350 {"SAI", SOF_DAI_IMX_SAI},
351 {"ESAI", SOF_DAI_IMX_ESAI},
342}; 352};
343 353
344static enum sof_ipc_dai_type find_dai(const char *name) 354static enum sof_ipc_dai_type find_dai(const char *name)
@@ -748,6 +758,9 @@ static const struct sof_topology_token ssp_tokens[] = {
748 get_token_u16, 758 get_token_u16,
749 offsetof(struct sof_ipc_dai_ssp_params, 759 offsetof(struct sof_ipc_dai_ssp_params,
750 tdm_per_slot_padding_flag), 0}, 760 tdm_per_slot_padding_flag), 0},
761 {SOF_TKN_INTEL_SSP_BCLK_DELAY, SND_SOC_TPLG_TUPLE_TYPE_WORD,
762 get_token_u32,
763 offsetof(struct sof_ipc_dai_ssp_params, bclk_delay), 0},
751 764
752}; 765};
753 766
@@ -1739,51 +1752,34 @@ err:
1739 return ret; 1752 return ret;
1740} 1753}
1741 1754
1742static int sof_process_load(struct snd_soc_component *scomp, int index, 1755static int sof_get_control_data(struct snd_sof_dev *sdev,
1743 struct snd_sof_widget *swidget, 1756 struct snd_soc_dapm_widget *widget,
1744 struct snd_soc_tplg_dapm_widget *tw, 1757 struct sof_widget_data *wdata,
1745 struct sof_ipc_comp_reply *r, 1758 size_t *size)
1746 int type)
1747{ 1759{
1748 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1749 struct snd_soc_tplg_private *private = &tw->priv;
1750 struct snd_soc_dapm_widget *widget = swidget->widget;
1751 const struct snd_kcontrol_new *kc; 1760 const struct snd_kcontrol_new *kc;
1752 struct soc_bytes_ext *sbe;
1753 struct soc_mixer_control *sm; 1761 struct soc_mixer_control *sm;
1762 struct soc_bytes_ext *sbe;
1754 struct soc_enum *se; 1763 struct soc_enum *se;
1755 struct snd_sof_control *scontrol = NULL; 1764 int i;
1756 struct sof_abi_hdr *pdata = NULL;
1757 struct sof_ipc_comp_process *process;
1758 size_t ipc_size, ipc_data_size = 0;
1759 int ret, i, offset = 0;
1760 1765
1761 if (type == SOF_COMP_NONE) { 1766 *size = 0;
1762 dev_err(sdev->dev, "error: invalid process comp type %d\n",
1763 type);
1764 return -EINVAL;
1765 }
1766 1767
1767 /*
1768 * get possible component controls - get size of all pdata,
1769 * then memcpy with headers
1770 */
1771 for (i = 0; i < widget->num_kcontrols; i++) { 1768 for (i = 0; i < widget->num_kcontrols; i++) {
1772
1773 kc = &widget->kcontrol_news[i]; 1769 kc = &widget->kcontrol_news[i];
1774 1770
1775 switch (widget->dobj.widget.kcontrol_type) { 1771 switch (widget->dobj.widget.kcontrol_type) {
1776 case SND_SOC_TPLG_TYPE_MIXER: 1772 case SND_SOC_TPLG_TYPE_MIXER:
1777 sm = (struct soc_mixer_control *)kc->private_value; 1773 sm = (struct soc_mixer_control *)kc->private_value;
1778 scontrol = sm->dobj.private; 1774 wdata[i].control = sm->dobj.private;
1779 break; 1775 break;
1780 case SND_SOC_TPLG_TYPE_BYTES: 1776 case SND_SOC_TPLG_TYPE_BYTES:
1781 sbe = (struct soc_bytes_ext *)kc->private_value; 1777 sbe = (struct soc_bytes_ext *)kc->private_value;
1782 scontrol = sbe->dobj.private; 1778 wdata[i].control = sbe->dobj.private;
1783 break; 1779 break;
1784 case SND_SOC_TPLG_TYPE_ENUM: 1780 case SND_SOC_TPLG_TYPE_ENUM:
1785 se = (struct soc_enum *)kc->private_value; 1781 se = (struct soc_enum *)kc->private_value;
1786 scontrol = se->dobj.private; 1782 wdata[i].control = se->dobj.private;
1787 break; 1783 break;
1788 default: 1784 default:
1789 dev_err(sdev->dev, "error: unknown kcontrol type %d in widget %s\n", 1785 dev_err(sdev->dev, "error: unknown kcontrol type %d in widget %s\n",
@@ -1792,31 +1788,97 @@ static int sof_process_load(struct snd_soc_component *scomp, int index,
1792 return -EINVAL; 1788 return -EINVAL;
1793 } 1789 }
1794 1790
1795 if (!scontrol) { 1791 if (!wdata[i].control) {
1796 dev_err(sdev->dev, "error: no scontrol for widget %s\n", 1792 dev_err(sdev->dev, "error: no scontrol for widget %s\n",
1797 widget->name); 1793 widget->name);
1798 return -EINVAL; 1794 return -EINVAL;
1799 } 1795 }
1800 1796
1801 /* don't include if no private data */ 1797 wdata[i].pdata = wdata[i].control->control_data->data;
1802 pdata = scontrol->control_data->data; 1798 if (!wdata[i].pdata)
1803 if (!pdata) 1799 return -EINVAL;
1804 continue;
1805 1800
1806 /* make sure data is valid - data can be updated at runtime */ 1801 /* make sure data is valid - data can be updated at runtime */
1807 if (pdata->magic != SOF_ABI_MAGIC) 1802 if (wdata[i].pdata->magic != SOF_ABI_MAGIC)
1808 continue; 1803 return -EINVAL;
1804
1805 *size += wdata[i].pdata->size;
1806
1807 /* get data type */
1808 switch (wdata[i].control->cmd) {
1809 case SOF_CTRL_CMD_VOLUME:
1810 case SOF_CTRL_CMD_ENUM:
1811 case SOF_CTRL_CMD_SWITCH:
1812 wdata[i].ipc_cmd = SOF_IPC_COMP_SET_VALUE;
1813 wdata[i].ctrl_type = SOF_CTRL_TYPE_VALUE_CHAN_SET;
1814 break;
1815 case SOF_CTRL_CMD_BINARY:
1816 wdata[i].ipc_cmd = SOF_IPC_COMP_SET_DATA;
1817 wdata[i].ctrl_type = SOF_CTRL_TYPE_DATA_SET;
1818 break;
1819 default:
1820 break;
1821 }
1822 }
1823
1824 return 0;
1825}
1826
1827static int sof_process_load(struct snd_soc_component *scomp, int index,
1828 struct snd_sof_widget *swidget,
1829 struct snd_soc_tplg_dapm_widget *tw,
1830 struct sof_ipc_comp_reply *r,
1831 int type)
1832{
1833 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1834 struct snd_soc_dapm_widget *widget = swidget->widget;
1835 struct snd_soc_tplg_private *private = &tw->priv;
1836 struct sof_ipc_comp_process *process = NULL;
1837 struct sof_widget_data *wdata = NULL;
1838 size_t ipc_data_size = 0;
1839 size_t ipc_size;
1840 int offset = 0;
1841 int ret = 0;
1842 int i;
1809 1843
1810 ipc_data_size += pdata->size; 1844 if (type == SOF_COMP_NONE) {
1845 dev_err(sdev->dev, "error: invalid process comp type %d\n",
1846 type);
1847 return -EINVAL;
1848 }
1849
1850 /* allocate struct for widget control data sizes and types */
1851 if (widget->num_kcontrols) {
1852 wdata = kcalloc(widget->num_kcontrols,
1853 sizeof(*wdata),
1854 GFP_KERNEL);
1855
1856 if (!wdata)
1857 return -ENOMEM;
1858
1859 /* get possible component controls and get size of all pdata */
1860 ret = sof_get_control_data(sdev, widget, wdata,
1861 &ipc_data_size);
1862
1863 if (ret < 0)
1864 goto out;
1811 } 1865 }
1812 1866
1813 ipc_size = sizeof(struct sof_ipc_comp_process) + 1867 ipc_size = sizeof(struct sof_ipc_comp_process) +
1814 le32_to_cpu(private->size) + 1868 le32_to_cpu(private->size) +
1815 ipc_data_size; 1869 ipc_data_size;
1816 1870
1871 /* we are exceeding max ipc size, config needs to be sent separately */
1872 if (ipc_size > SOF_IPC_MSG_MAX_SIZE) {
1873 ipc_size -= ipc_data_size;
1874 ipc_data_size = 0;
1875 }
1876
1817 process = kzalloc(ipc_size, GFP_KERNEL); 1877 process = kzalloc(ipc_size, GFP_KERNEL);
1818 if (!process) 1878 if (!process) {
1819 return -ENOMEM; 1879 ret = -ENOMEM;
1880 goto out;
1881 }
1820 1882
1821 /* configure iir IPC message */ 1883 /* configure iir IPC message */
1822 process->comp.hdr.size = ipc_size; 1884 process->comp.hdr.size = ipc_size;
@@ -1842,40 +1904,13 @@ static int sof_process_load(struct snd_soc_component *scomp, int index,
1842 * get possible component controls - get size of all pdata, 1904 * get possible component controls - get size of all pdata,
1843 * then memcpy with headers 1905 * then memcpy with headers
1844 */ 1906 */
1845 for (i = 0; i < widget->num_kcontrols; i++) { 1907 if (ipc_data_size) {
1846 kc = &widget->kcontrol_news[i]; 1908 for (i = 0; i < widget->num_kcontrols; i++) {
1847 1909 memcpy(&process->data + offset,
1848 switch (widget->dobj.widget.kcontrol_type) { 1910 wdata[i].pdata->data,
1849 case SND_SOC_TPLG_TYPE_MIXER: 1911 wdata[i].pdata->size);
1850 sm = (struct soc_mixer_control *)kc->private_value; 1912 offset += wdata[i].pdata->size;
1851 scontrol = sm->dobj.private;
1852 break;
1853 case SND_SOC_TPLG_TYPE_BYTES:
1854 sbe = (struct soc_bytes_ext *)kc->private_value;
1855 scontrol = sbe->dobj.private;
1856 break;
1857 case SND_SOC_TPLG_TYPE_ENUM:
1858 se = (struct soc_enum *)kc->private_value;
1859 scontrol = se->dobj.private;
1860 break;
1861 default:
1862 dev_err(sdev->dev, "error: unknown kcontrol type %d in widget %s\n",
1863 widget->dobj.widget.kcontrol_type,
1864 widget->name);
1865 return -EINVAL;
1866 } 1913 }
1867
1868 /* don't include if no private data */
1869 pdata = scontrol->control_data->data;
1870 if (!pdata)
1871 continue;
1872
1873 /* make sure data is valid - data can be updated at runtime */
1874 if (pdata->magic != SOF_ABI_MAGIC)
1875 continue;
1876
1877 memcpy(&process->data + offset, pdata->data, pdata->size);
1878 offset += pdata->size;
1879 } 1914 }
1880 1915
1881 process->size = ipc_data_size; 1916 process->size = ipc_data_size;
@@ -1883,10 +1918,35 @@ static int sof_process_load(struct snd_soc_component *scomp, int index,
1883 1918
1884 ret = sof_ipc_tx_message(sdev->ipc, process->comp.hdr.cmd, process, 1919 ret = sof_ipc_tx_message(sdev->ipc, process->comp.hdr.cmd, process,
1885 ipc_size, r, sizeof(*r)); 1920 ipc_size, r, sizeof(*r));
1886 if (ret >= 0) 1921
1887 return ret; 1922 if (ret < 0) {
1923 dev_err(sdev->dev, "error: create process failed\n");
1924 goto err;
1925 }
1926
1927 /* we sent the data in single message so return */
1928 if (ipc_data_size)
1929 goto out;
1930
1931 /* send control data with large message supported method */
1932 for (i = 0; i < widget->num_kcontrols; i++) {
1933 wdata[i].control->readback_offset = 0;
1934 ret = snd_sof_ipc_set_get_comp_data(sdev->ipc, wdata[i].control,
1935 wdata[i].ipc_cmd,
1936 wdata[i].ctrl_type,
1937 wdata[i].control->cmd,
1938 true);
1939 if (ret != 0) {
1940 dev_err(sdev->dev, "error: send control failed\n");
1941 break;
1942 }
1943 }
1944
1888err: 1945err:
1889 kfree(process); 1946 if (ret < 0)
1947 kfree(process);
1948out:
1949 kfree(wdata);
1890 return ret; 1950 return ret;
1891} 1951}
1892 1952
@@ -2457,6 +2517,26 @@ static int sof_link_ssp_load(struct snd_soc_component *scomp, int index,
2457 return ret; 2517 return ret;
2458} 2518}
2459 2519
2520static int sof_link_sai_load(struct snd_soc_component *scomp, int index,
2521 struct snd_soc_dai_link *link,
2522 struct snd_soc_tplg_link_config *cfg,
2523 struct snd_soc_tplg_hw_config *hw_config,
2524 struct sof_ipc_dai_config *config)
2525{
2526 /*TODO: Add implementation */
2527 return 0;
2528}
2529
2530static int sof_link_esai_load(struct snd_soc_component *scomp, int index,
2531 struct snd_soc_dai_link *link,
2532 struct snd_soc_tplg_link_config *cfg,
2533 struct snd_soc_tplg_hw_config *hw_config,
2534 struct sof_ipc_dai_config *config)
2535{
2536 /*TODO: Add implementation */
2537 return 0;
2538}
2539
2460static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, 2540static int sof_link_dmic_load(struct snd_soc_component *scomp, int index,
2461 struct snd_soc_dai_link *link, 2541 struct snd_soc_dai_link *link,
2462 struct snd_soc_tplg_link_config *cfg, 2542 struct snd_soc_tplg_link_config *cfg,
@@ -2685,6 +2765,40 @@ static int sof_link_hda_load(struct snd_soc_component *scomp, int index,
2685 return ret; 2765 return ret;
2686} 2766}
2687 2767
2768static int sof_link_alh_load(struct snd_soc_component *scomp, int index,
2769 struct snd_soc_dai_link *link,
2770 struct snd_soc_tplg_link_config *cfg,
2771 struct snd_soc_tplg_hw_config *hw_config,
2772 struct sof_ipc_dai_config *config)
2773{
2774 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
2775 struct sof_ipc_reply reply;
2776 u32 size = sizeof(*config);
2777 int ret;
2778
2779 /* init IPC */
2780 config->hdr.size = size;
2781
2782 /* send message to DSP */
2783 ret = sof_ipc_tx_message(sdev->ipc,
2784 config->hdr.cmd, config, size, &reply,
2785 sizeof(reply));
2786
2787 if (ret < 0) {
2788 dev_err(sdev->dev, "error: failed to set DAI config for ALH %d\n",
2789 config->dai_index);
2790 return ret;
2791 }
2792
2793 /* set config for all DAI's with name matching the link name */
2794 ret = sof_set_dai_config(sdev, size, link, config);
2795 if (ret < 0)
2796 dev_err(sdev->dev, "error: failed to save DAI config for ALH %d\n",
2797 config->dai_index);
2798
2799 return ret;
2800}
2801
2688/* DAI link - used for any driver specific init */ 2802/* DAI link - used for any driver specific init */
2689static int sof_link_load(struct snd_soc_component *scomp, int index, 2803static int sof_link_load(struct snd_soc_component *scomp, int index,
2690 struct snd_soc_dai_link *link, 2804 struct snd_soc_dai_link *link,
@@ -2781,6 +2895,18 @@ static int sof_link_load(struct snd_soc_component *scomp, int index,
2781 ret = sof_link_hda_load(scomp, index, link, cfg, hw_config, 2895 ret = sof_link_hda_load(scomp, index, link, cfg, hw_config,
2782 &config); 2896 &config);
2783 break; 2897 break;
2898 case SOF_DAI_INTEL_ALH:
2899 ret = sof_link_alh_load(scomp, index, link, cfg, hw_config,
2900 &config);
2901 break;
2902 case SOF_DAI_IMX_SAI:
2903 ret = sof_link_sai_load(scomp, index, link, cfg, hw_config,
2904 &config);
2905 break;
2906 case SOF_DAI_IMX_ESAI:
2907 ret = sof_link_esai_load(scomp, index, link, cfg, hw_config,
2908 &config);
2909 break;
2784 default: 2910 default:
2785 dev_err(sdev->dev, "error: invalid DAI type %d\n", config.type); 2911 dev_err(sdev->dev, "error: invalid DAI type %d\n", config.type);
2786 ret = -EINVAL; 2912 ret = -EINVAL;
@@ -2838,7 +2964,8 @@ found:
2838 switch (sof_dai->dai_config->type) { 2964 switch (sof_dai->dai_config->type) {
2839 case SOF_DAI_INTEL_SSP: 2965 case SOF_DAI_INTEL_SSP:
2840 case SOF_DAI_INTEL_DMIC: 2966 case SOF_DAI_INTEL_DMIC:
2841 /* no resource needs to be released for SSP and DMIC */ 2967 case SOF_DAI_INTEL_ALH:
2968 /* no resource needs to be released for SSP, DMIC and ALH */
2842 break; 2969 break;
2843 case SOF_DAI_INTEL_HDA: 2970 case SOF_DAI_INTEL_HDA:
2844 ret = sof_link_hda_unload(sdev, link); 2971 ret = sof_link_hda_unload(sdev, link);
diff --git a/sound/soc/sof/trace.c b/sound/soc/sof/trace.c
index befed975161c..4c3cff031fd6 100644
--- a/sound/soc/sof/trace.c
+++ b/sound/soc/sof/trace.c
@@ -148,13 +148,8 @@ static int trace_debugfs_create(struct snd_sof_dev *sdev)
148 dfse->size = sdev->dmatb.bytes; 148 dfse->size = sdev->dmatb.bytes;
149 dfse->sdev = sdev; 149 dfse->sdev = sdev;
150 150
151 dfse->dfsentry = debugfs_create_file("trace", 0444, sdev->debugfs_root, 151 debugfs_create_file("trace", 0444, sdev->debugfs_root, dfse,
152 dfse, &sof_dfs_trace_fops); 152 &sof_dfs_trace_fops);
153 if (!dfse->dfsentry) {
154 /* can't rely on debugfs, only log error and keep going */
155 dev_err(sdev->dev,
156 "error: cannot create debugfs entry for trace\n");
157 }
158 153
159 return 0; 154 return 0;
160} 155}
diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c
index 78a6a360b4a6..4b68d6ee75da 100644
--- a/sound/soc/spear/spdif_in.c
+++ b/sound/soc/spear/spdif_in.c
@@ -202,12 +202,11 @@ static int spdif_in_probe(struct platform_device *pdev)
202{ 202{
203 struct spdif_in_dev *host; 203 struct spdif_in_dev *host;
204 struct spear_spdif_platform_data *pdata; 204 struct spear_spdif_platform_data *pdata;
205 struct resource *res, *res_fifo; 205 struct resource *res_fifo;
206 void __iomem *io_base; 206 void __iomem *io_base;
207 int ret; 207 int ret;
208 208
209 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 209 io_base = devm_platform_ioremap_resource(pdev, 0);
210 io_base = devm_ioremap_resource(&pdev->dev, res);
211 if (IS_ERR(io_base)) 210 if (IS_ERR(io_base))
212 return PTR_ERR(io_base); 211 return PTR_ERR(io_base);
213 212
diff --git a/sound/soc/sprd/sprd-mcdt.c b/sound/soc/sprd/sprd-mcdt.c
index 7448015a4935..f439e5503a3c 100644
--- a/sound/soc/sprd/sprd-mcdt.c
+++ b/sound/soc/sprd/sprd-mcdt.c
@@ -959,10 +959,8 @@ static int sprd_mcdt_probe(struct platform_device *pdev)
959 platform_set_drvdata(pdev, mcdt); 959 platform_set_drvdata(pdev, mcdt);
960 960
961 irq = platform_get_irq(pdev, 0); 961 irq = platform_get_irq(pdev, 0);
962 if (irq < 0) { 962 if (irq < 0)
963 dev_err(&pdev->dev, "Failed to get MCDT interrupt\n");
964 return irq; 963 return irq;
965 }
966 964
967 ret = devm_request_irq(&pdev->dev, irq, sprd_mcdt_irq_handler, 965 ret = devm_request_irq(&pdev->dev, irq, sprd_mcdt_irq_handler,
968 0, "sprd-mcdt", mcdt); 966 0, "sprd-mcdt", mcdt);
diff --git a/sound/soc/sti/sti_uniperif.c b/sound/soc/sti/sti_uniperif.c
index 645bcbe91601..ee4a0151e63e 100644
--- a/sound/soc/sti/sti_uniperif.c
+++ b/sound/soc/sti/sti_uniperif.c
@@ -426,10 +426,8 @@ static int sti_uniperiph_cpu_dai_of(struct device_node *node,
426 UNIPERIF_FIFO_DATA_OFFSET(uni); 426 UNIPERIF_FIFO_DATA_OFFSET(uni);
427 427
428 uni->irq = platform_get_irq(priv->pdev, 0); 428 uni->irq = platform_get_irq(priv->pdev, 0);
429 if (uni->irq < 0) { 429 if (uni->irq < 0)
430 dev_err(dev, "Failed to get IRQ resource\n");
431 return -ENXIO; 430 return -ENXIO;
432 }
433 431
434 uni->type = dev_data->type; 432 uni->type = dev_data->type;
435 433
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c
index ba6452dab69b..3e7226a53e53 100644
--- a/sound/soc/stm/stm32_i2s.c
+++ b/sound/soc/stm/stm32_i2s.c
@@ -855,11 +855,8 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev,
855 855
856 /* Get irqs */ 856 /* Get irqs */
857 irq = platform_get_irq(pdev, 0); 857 irq = platform_get_irq(pdev, 0);
858 if (irq < 0) { 858 if (irq < 0)
859 if (irq != -EPROBE_DEFER)
860 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
861 return irq; 859 return irq;
862 }
863 860
864 ret = devm_request_irq(&pdev->dev, irq, stm32_i2s_isr, IRQF_ONESHOT, 861 ret = devm_request_irq(&pdev->dev, irq, stm32_i2s_isr, IRQF_ONESHOT,
865 dev_name(&pdev->dev), i2s); 862 dev_name(&pdev->dev), i2s);
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c
index 63f68e663676..ef4273361d0d 100644
--- a/sound/soc/stm/stm32_sai.c
+++ b/sound/soc/stm/stm32_sai.c
@@ -152,7 +152,6 @@ static int stm32_sai_probe(struct platform_device *pdev)
152{ 152{
153 struct stm32_sai_data *sai; 153 struct stm32_sai_data *sai;
154 struct reset_control *rst; 154 struct reset_control *rst;
155 struct resource *res;
156 const struct of_device_id *of_id; 155 const struct of_device_id *of_id;
157 u32 val; 156 u32 val;
158 int ret; 157 int ret;
@@ -161,8 +160,7 @@ static int stm32_sai_probe(struct platform_device *pdev)
161 if (!sai) 160 if (!sai)
162 return -ENOMEM; 161 return -ENOMEM;
163 162
164 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 163 sai->base = devm_platform_ioremap_resource(pdev, 0);
165 sai->base = devm_ioremap_resource(&pdev->dev, res);
166 if (IS_ERR(sai->base)) 164 if (IS_ERR(sai->base))
167 return PTR_ERR(sai->base); 165 return PTR_ERR(sai->base);
168 166
@@ -195,10 +193,8 @@ static int stm32_sai_probe(struct platform_device *pdev)
195 193
196 /* init irqs */ 194 /* init irqs */
197 sai->irq = platform_get_irq(pdev, 0); 195 sai->irq = platform_get_irq(pdev, 0);
198 if (sai->irq < 0) { 196 if (sai->irq < 0)
199 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
200 return sai->irq; 197 return sai->irq;
201 }
202 198
203 /* reset */ 199 /* reset */
204 rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); 200 rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c
index ee71b898897b..cd4b235fce57 100644
--- a/sound/soc/stm/stm32_spdifrx.c
+++ b/sound/soc/stm/stm32_spdifrx.c
@@ -909,10 +909,8 @@ static int stm32_spdifrx_parse_of(struct platform_device *pdev,
909 } 909 }
910 910
911 spdifrx->irq = platform_get_irq(pdev, 0); 911 spdifrx->irq = platform_get_irq(pdev, 0);
912 if (spdifrx->irq < 0) { 912 if (spdifrx->irq < 0)
913 dev_err(&pdev->dev, "No irq for node %s\n", pdev->name);
914 return spdifrx->irq; 913 return spdifrx->irq;
915 }
916 914
917 return 0; 915 return 0;
918} 916}
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 619073e7d972..ee448d5e07a6 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -1424,7 +1424,7 @@ static const struct snd_soc_dapm_route sun8i_codec_card_routes[] = {
1424}; 1424};
1425 1425
1426static struct snd_soc_aux_dev aux_dev = { 1426static struct snd_soc_aux_dev aux_dev = {
1427 .name = "Codec Analog Controls", 1427 .dlc = COMP_EMPTY(),
1428}; 1428};
1429 1429
1430static struct snd_soc_card *sun8i_a23_codec_create_card(struct device *dev) 1430static struct snd_soc_card *sun8i_a23_codec_create_card(struct device *dev)
@@ -1436,10 +1436,10 @@ static struct snd_soc_card *sun8i_a23_codec_create_card(struct device *dev)
1436 if (!card) 1436 if (!card)
1437 return ERR_PTR(-ENOMEM); 1437 return ERR_PTR(-ENOMEM);
1438 1438
1439 aux_dev.codec_of_node = of_parse_phandle(dev->of_node, 1439 aux_dev.dlc.of_node = of_parse_phandle(dev->of_node,
1440 "allwinner,codec-analog-controls", 1440 "allwinner,codec-analog-controls",
1441 0); 1441 0);
1442 if (!aux_dev.codec_of_node) { 1442 if (!aux_dev.dlc.of_node) {
1443 dev_err(dev, "Can't find analog controls for codec.\n"); 1443 dev_err(dev, "Can't find analog controls for codec.\n");
1444 return ERR_PTR(-EINVAL); 1444 return ERR_PTR(-EINVAL);
1445 }; 1445 };
@@ -1474,10 +1474,10 @@ static struct snd_soc_card *sun8i_h3_codec_create_card(struct device *dev)
1474 if (!card) 1474 if (!card)
1475 return ERR_PTR(-ENOMEM); 1475 return ERR_PTR(-ENOMEM);
1476 1476
1477 aux_dev.codec_of_node = of_parse_phandle(dev->of_node, 1477 aux_dev.dlc.of_node = of_parse_phandle(dev->of_node,
1478 "allwinner,codec-analog-controls", 1478 "allwinner,codec-analog-controls",
1479 0); 1479 0);
1480 if (!aux_dev.codec_of_node) { 1480 if (!aux_dev.dlc.of_node) {
1481 dev_err(dev, "Can't find analog controls for codec.\n"); 1481 dev_err(dev, "Can't find analog controls for codec.\n");
1482 return ERR_PTR(-EINVAL); 1482 return ERR_PTR(-EINVAL);
1483 }; 1483 };
@@ -1512,10 +1512,10 @@ static struct snd_soc_card *sun8i_v3s_codec_create_card(struct device *dev)
1512 if (!card) 1512 if (!card)
1513 return ERR_PTR(-ENOMEM); 1513 return ERR_PTR(-ENOMEM);
1514 1514
1515 aux_dev.codec_of_node = of_parse_phandle(dev->of_node, 1515 aux_dev.dlc.of_node = of_parse_phandle(dev->of_node,
1516 "allwinner,codec-analog-controls", 1516 "allwinner,codec-analog-controls",
1517 0); 1517 0);
1518 if (!aux_dev.codec_of_node) { 1518 if (!aux_dev.dlc.of_node) {
1519 dev_err(dev, "Can't find analog controls for codec.\n"); 1519 dev_err(dev, "Can't find analog controls for codec.\n");
1520 return ERR_PTR(-EINVAL); 1520 return ERR_PTR(-EINVAL);
1521 }; 1521 };
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 85c3b2c8cd77..d0a8d5810c0a 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -46,8 +46,6 @@
46#define SUN4I_I2S_FMT0_FMT_RIGHT_J (2 << 0) 46#define SUN4I_I2S_FMT0_FMT_RIGHT_J (2 << 0)
47#define SUN4I_I2S_FMT0_FMT_LEFT_J (1 << 0) 47#define SUN4I_I2S_FMT0_FMT_LEFT_J (1 << 0)
48#define SUN4I_I2S_FMT0_FMT_I2S (0 << 0) 48#define SUN4I_I2S_FMT0_FMT_I2S (0 << 0)
49#define SUN4I_I2S_FMT0_POLARITY_INVERTED (1)
50#define SUN4I_I2S_FMT0_POLARITY_NORMAL (0)
51 49
52#define SUN4I_I2S_FMT1_REG 0x08 50#define SUN4I_I2S_FMT1_REG 0x08
53#define SUN4I_I2S_FIFO_TX_REG 0x0c 51#define SUN4I_I2S_FIFO_TX_REG 0x0c
@@ -76,10 +74,11 @@
76#define SUN4I_I2S_CLK_DIV_MCLK_MASK GENMASK(3, 0) 74#define SUN4I_I2S_CLK_DIV_MCLK_MASK GENMASK(3, 0)
77#define SUN4I_I2S_CLK_DIV_MCLK(mclk) ((mclk) << 0) 75#define SUN4I_I2S_CLK_DIV_MCLK(mclk) ((mclk) << 0)
78 76
79#define SUN4I_I2S_RX_CNT_REG 0x28 77#define SUN4I_I2S_TX_CNT_REG 0x28
80#define SUN4I_I2S_TX_CNT_REG 0x2c 78#define SUN4I_I2S_RX_CNT_REG 0x2c
81 79
82#define SUN4I_I2S_TX_CHAN_SEL_REG 0x30 80#define SUN4I_I2S_TX_CHAN_SEL_REG 0x30
81#define SUN4I_I2S_CHAN_SEL_MASK GENMASK(2, 0)
83#define SUN4I_I2S_CHAN_SEL(num_chan) (((num_chan) - 1) << 0) 82#define SUN4I_I2S_CHAN_SEL(num_chan) (((num_chan) - 1) << 0)
84 83
85#define SUN4I_I2S_TX_CHAN_MAP_REG 0x34 84#define SUN4I_I2S_TX_CHAN_MAP_REG 0x34
@@ -92,8 +91,19 @@
92#define SUN8I_I2S_CTRL_BCLK_OUT BIT(18) 91#define SUN8I_I2S_CTRL_BCLK_OUT BIT(18)
93#define SUN8I_I2S_CTRL_LRCK_OUT BIT(17) 92#define SUN8I_I2S_CTRL_LRCK_OUT BIT(17)
94 93
94#define SUN8I_I2S_CTRL_MODE_MASK GENMASK(5, 4)
95#define SUN8I_I2S_CTRL_MODE_RIGHT (2 << 4)
96#define SUN8I_I2S_CTRL_MODE_LEFT (1 << 4)
97#define SUN8I_I2S_CTRL_MODE_PCM (0 << 4)
98
99#define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK BIT(19)
100#define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED (1 << 19)
101#define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL (0 << 19)
95#define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8) 102#define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8)
96#define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8) 103#define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8)
104#define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK BIT(7)
105#define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED (1 << 7)
106#define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL (0 << 7)
97 107
98#define SUN8I_I2S_INT_STA_REG 0x0c 108#define SUN8I_I2S_INT_STA_REG 0x0c
99#define SUN8I_I2S_FIFO_TX_REG 0x20 109#define SUN8I_I2S_FIFO_TX_REG 0x20
@@ -120,52 +130,33 @@ struct sun4i_i2s;
120 * struct sun4i_i2s_quirks - Differences between SoC variants. 130 * struct sun4i_i2s_quirks - Differences between SoC variants.
121 * 131 *
122 * @has_reset: SoC needs reset deasserted. 132 * @has_reset: SoC needs reset deasserted.
123 * @has_slave_select_bit: SoC has a bit to enable slave mode.
124 * @has_fmt_set_lrck_period: SoC requires lrclk period to be set.
125 * @has_chcfg: tx and rx slot number need to be set.
126 * @has_chsel_tx_chen: SoC requires that the tx channels are enabled.
127 * @has_chsel_offset: SoC uses offset for selecting dai operational mode.
128 * @reg_offset_txdata: offset of the tx fifo. 133 * @reg_offset_txdata: offset of the tx fifo.
129 * @sun4i_i2s_regmap: regmap config to use. 134 * @sun4i_i2s_regmap: regmap config to use.
130 * @mclk_offset: Value by which mclkdiv needs to be adjusted.
131 * @bclk_offset: Value by which bclkdiv needs to be adjusted.
132 * @field_clkdiv_mclk_en: regmap field to enable mclk output. 135 * @field_clkdiv_mclk_en: regmap field to enable mclk output.
133 * @field_fmt_wss: regmap field to set word select size. 136 * @field_fmt_wss: regmap field to set word select size.
134 * @field_fmt_sr: regmap field to set sample resolution. 137 * @field_fmt_sr: regmap field to set sample resolution.
135 * @field_fmt_bclk: regmap field to set clk polarity.
136 * @field_fmt_lrclk: regmap field to set frame polarity.
137 * @field_fmt_mode: regmap field to set the operational mode.
138 * @field_txchanmap: location of the tx channel mapping register.
139 * @field_rxchanmap: location of the rx channel mapping register.
140 * @field_txchansel: location of the tx channel select bit fields.
141 * @field_rxchansel: location of the rx channel select bit fields.
142 */ 138 */
143struct sun4i_i2s_quirks { 139struct sun4i_i2s_quirks {
144 bool has_reset; 140 bool has_reset;
145 bool has_slave_select_bit;
146 bool has_fmt_set_lrck_period;
147 bool has_chcfg;
148 bool has_chsel_tx_chen;
149 bool has_chsel_offset;
150 unsigned int reg_offset_txdata; /* TX FIFO */ 141 unsigned int reg_offset_txdata; /* TX FIFO */
151 const struct regmap_config *sun4i_i2s_regmap; 142 const struct regmap_config *sun4i_i2s_regmap;
152 unsigned int mclk_offset;
153 unsigned int bclk_offset;
154 143
155 /* Register fields for i2s */ 144 /* Register fields for i2s */
156 struct reg_field field_clkdiv_mclk_en; 145 struct reg_field field_clkdiv_mclk_en;
157 struct reg_field field_fmt_wss; 146 struct reg_field field_fmt_wss;
158 struct reg_field field_fmt_sr; 147 struct reg_field field_fmt_sr;
159 struct reg_field field_fmt_bclk;
160 struct reg_field field_fmt_lrclk;
161 struct reg_field field_fmt_mode;
162 struct reg_field field_txchanmap;
163 struct reg_field field_rxchanmap;
164 struct reg_field field_txchansel;
165 struct reg_field field_rxchansel;
166 148
149 const struct sun4i_i2s_clk_div *bclk_dividers;
150 unsigned int num_bclk_dividers;
151 const struct sun4i_i2s_clk_div *mclk_dividers;
152 unsigned int num_mclk_dividers;
153
154 unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *);
167 s8 (*get_sr)(const struct sun4i_i2s *, int); 155 s8 (*get_sr)(const struct sun4i_i2s *, int);
168 s8 (*get_wss)(const struct sun4i_i2s *, int); 156 s8 (*get_wss)(const struct sun4i_i2s *, int);
157 int (*set_chan_cfg)(const struct sun4i_i2s *,
158 const struct snd_pcm_hw_params *);
159 int (*set_fmt)(const struct sun4i_i2s *, unsigned int);
169}; 160};
170 161
171struct sun4i_i2s { 162struct sun4i_i2s {
@@ -174,7 +165,10 @@ struct sun4i_i2s {
174 struct regmap *regmap; 165 struct regmap *regmap;
175 struct reset_control *rst; 166 struct reset_control *rst;
176 167
168 unsigned int format;
177 unsigned int mclk_freq; 169 unsigned int mclk_freq;
170 unsigned int slots;
171 unsigned int slot_width;
178 172
179 struct snd_dmaengine_dai_dma_data capture_dma_data; 173 struct snd_dmaengine_dai_dma_data capture_dma_data;
180 struct snd_dmaengine_dai_dma_data playback_dma_data; 174 struct snd_dmaengine_dai_dma_data playback_dma_data;
@@ -183,13 +177,6 @@ struct sun4i_i2s {
183 struct regmap_field *field_clkdiv_mclk_en; 177 struct regmap_field *field_clkdiv_mclk_en;
184 struct regmap_field *field_fmt_wss; 178 struct regmap_field *field_fmt_wss;
185 struct regmap_field *field_fmt_sr; 179 struct regmap_field *field_fmt_sr;
186 struct regmap_field *field_fmt_bclk;
187 struct regmap_field *field_fmt_lrclk;
188 struct regmap_field *field_fmt_mode;
189 struct regmap_field *field_txchanmap;
190 struct regmap_field *field_rxchanmap;
191 struct regmap_field *field_txchansel;
192 struct regmap_field *field_rxchansel;
193 180
194 const struct sun4i_i2s_quirks *variant; 181 const struct sun4i_i2s_quirks *variant;
195}; 182};
@@ -221,15 +208,46 @@ static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
221 /* TODO - extend divide ratio supported by newer SoCs */ 208 /* TODO - extend divide ratio supported by newer SoCs */
222}; 209};
223 210
211static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div[] = {
212 { .div = 1, .val = 1 },
213 { .div = 2, .val = 2 },
214 { .div = 4, .val = 3 },
215 { .div = 6, .val = 4 },
216 { .div = 8, .val = 5 },
217 { .div = 12, .val = 6 },
218 { .div = 16, .val = 7 },
219 { .div = 24, .val = 8 },
220 { .div = 32, .val = 9 },
221 { .div = 48, .val = 10 },
222 { .div = 64, .val = 11 },
223 { .div = 96, .val = 12 },
224 { .div = 128, .val = 13 },
225 { .div = 176, .val = 14 },
226 { .div = 192, .val = 15 },
227};
228
229static unsigned long sun4i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
230{
231 return i2s->mclk_freq;
232}
233
234static unsigned long sun8i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
235{
236 return clk_get_rate(i2s->mod_clk);
237}
238
224static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s, 239static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
225 unsigned int oversample_rate, 240 unsigned long parent_rate,
241 unsigned int sampling_rate,
242 unsigned int channels,
226 unsigned int word_size) 243 unsigned int word_size)
227{ 244{
228 int div = oversample_rate / word_size / 2; 245 const struct sun4i_i2s_clk_div *dividers = i2s->variant->bclk_dividers;
246 int div = parent_rate / sampling_rate / word_size / channels;
229 int i; 247 int i;
230 248
231 for (i = 0; i < ARRAY_SIZE(sun4i_i2s_bclk_div); i++) { 249 for (i = 0; i < i2s->variant->num_bclk_dividers; i++) {
232 const struct sun4i_i2s_clk_div *bdiv = &sun4i_i2s_bclk_div[i]; 250 const struct sun4i_i2s_clk_div *bdiv = &dividers[i];
233 251
234 if (bdiv->div == div) 252 if (bdiv->div == div)
235 return bdiv->val; 253 return bdiv->val;
@@ -239,15 +257,15 @@ static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
239} 257}
240 258
241static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s, 259static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
242 unsigned int oversample_rate, 260 unsigned long parent_rate,
243 unsigned int module_rate, 261 unsigned long mclk_rate)
244 unsigned int sampling_rate)
245{ 262{
246 int div = module_rate / sampling_rate / oversample_rate; 263 const struct sun4i_i2s_clk_div *dividers = i2s->variant->mclk_dividers;
264 int div = parent_rate / mclk_rate;
247 int i; 265 int i;
248 266
249 for (i = 0; i < ARRAY_SIZE(sun4i_i2s_mclk_div); i++) { 267 for (i = 0; i < i2s->variant->num_mclk_dividers; i++) {
250 const struct sun4i_i2s_clk_div *mdiv = &sun4i_i2s_mclk_div[i]; 268 const struct sun4i_i2s_clk_div *mdiv = &dividers[i];
251 269
252 if (mdiv->div == div) 270 if (mdiv->div == div)
253 return mdiv->val; 271 return mdiv->val;
@@ -270,10 +288,11 @@ static bool sun4i_i2s_oversample_is_valid(unsigned int oversample)
270 288
271static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai, 289static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
272 unsigned int rate, 290 unsigned int rate,
273 unsigned int word_size) 291 unsigned int slots,
292 unsigned int slot_width)
274{ 293{
275 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 294 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
276 unsigned int oversample_rate, clk_rate; 295 unsigned int oversample_rate, clk_rate, bclk_parent_rate;
277 int bclk_div, mclk_div; 296 int bclk_div, mclk_div;
278 int ret; 297 int ret;
279 298
@@ -315,36 +334,26 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
315 return -EINVAL; 334 return -EINVAL;
316 } 335 }
317 336
318 bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate, 337 bclk_parent_rate = i2s->variant->get_bclk_parent_rate(i2s);
319 word_size); 338 bclk_div = sun4i_i2s_get_bclk_div(i2s, bclk_parent_rate,
339 rate, slots, slot_width);
320 if (bclk_div < 0) { 340 if (bclk_div < 0) {
321 dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div); 341 dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div);
322 return -EINVAL; 342 return -EINVAL;
323 } 343 }
324 344
325 mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate, 345 mclk_div = sun4i_i2s_get_mclk_div(i2s, clk_rate, i2s->mclk_freq);
326 clk_rate, rate);
327 if (mclk_div < 0) { 346 if (mclk_div < 0) {
328 dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div); 347 dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div);
329 return -EINVAL; 348 return -EINVAL;
330 } 349 }
331 350
332 /* Adjust the clock division values if needed */
333 bclk_div += i2s->variant->bclk_offset;
334 mclk_div += i2s->variant->mclk_offset;
335
336 regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG, 351 regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
337 SUN4I_I2S_CLK_DIV_BCLK(bclk_div) | 352 SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
338 SUN4I_I2S_CLK_DIV_MCLK(mclk_div)); 353 SUN4I_I2S_CLK_DIV_MCLK(mclk_div));
339 354
340 regmap_field_write(i2s->field_clkdiv_mclk_en, 1); 355 regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
341 356
342 /* Set sync period */
343 if (i2s->variant->has_fmt_set_lrck_period)
344 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
345 SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
346 SUN8I_I2S_FMT0_LRCK_PERIOD(32));
347
348 return 0; 357 return 0;
349} 358}
350 359
@@ -381,45 +390,105 @@ static s8 sun8i_i2s_get_sr_wss(const struct sun4i_i2s *i2s, int width)
381 return (width - 8) / 4 + 1; 390 return (width - 8) / 4 + 1;
382} 391}
383 392
384static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, 393static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
385 struct snd_pcm_hw_params *params, 394 const struct snd_pcm_hw_params *params)
386 struct snd_soc_dai *dai)
387{ 395{
388 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 396 unsigned int channels = params_channels(params);
389 int sr, wss, channels;
390 u32 width;
391 397
392 channels = params_channels(params); 398 /* Map the channels for playback and capture */
393 if (channels != 2) { 399 regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210);
394 dev_err(dai->dev, "Unsupported number of channels: %d\n", 400 regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210);
395 channels);
396 return -EINVAL;
397 }
398 401
399 if (i2s->variant->has_chcfg) { 402 /* Configure the channels */
400 regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, 403 regmap_update_bits(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
401 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK, 404 SUN4I_I2S_CHAN_SEL_MASK,
402 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels)); 405 SUN4I_I2S_CHAN_SEL(channels));
403 regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, 406 regmap_update_bits(i2s->regmap, SUN4I_I2S_RX_CHAN_SEL_REG,
404 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK, 407 SUN4I_I2S_CHAN_SEL_MASK,
405 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels)); 408 SUN4I_I2S_CHAN_SEL(channels));
406 } 409
410 return 0;
411}
412
413static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
414 const struct snd_pcm_hw_params *params)
415{
416 unsigned int channels = params_channels(params);
417 unsigned int slots = channels;
418 unsigned int lrck_period;
419
420 if (i2s->slots)
421 slots = i2s->slots;
407 422
408 /* Map the channels for playback and capture */ 423 /* Map the channels for playback and capture */
409 regmap_field_write(i2s->field_txchanmap, 0x76543210); 424 regmap_write(i2s->regmap, SUN8I_I2S_TX_CHAN_MAP_REG, 0x76543210);
410 regmap_field_write(i2s->field_rxchanmap, 0x00003210); 425 regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, 0x76543210);
411 426
412 /* Configure the channels */ 427 /* Configure the channels */
413 regmap_field_write(i2s->field_txchansel, 428 regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
414 SUN4I_I2S_CHAN_SEL(params_channels(params))); 429 SUN4I_I2S_CHAN_SEL_MASK,
430 SUN4I_I2S_CHAN_SEL(channels));
431 regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
432 SUN4I_I2S_CHAN_SEL_MASK,
433 SUN4I_I2S_CHAN_SEL(channels));
434
435 regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
436 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
437 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
438 regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
439 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
440 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
441
442 switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
443 case SND_SOC_DAIFMT_DSP_A:
444 case SND_SOC_DAIFMT_DSP_B:
445 case SND_SOC_DAIFMT_LEFT_J:
446 case SND_SOC_DAIFMT_RIGHT_J:
447 lrck_period = params_physical_width(params) * slots;
448 break;
449
450 case SND_SOC_DAIFMT_I2S:
451 lrck_period = params_physical_width(params);
452 break;
453
454 default:
455 return -EINVAL;
456 }
457
458 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
459 SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
460 SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
461
462 regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
463 SUN8I_I2S_TX_CHAN_EN_MASK,
464 SUN8I_I2S_TX_CHAN_EN(channels));
465
466 return 0;
467}
415 468
416 regmap_field_write(i2s->field_rxchansel, 469static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
417 SUN4I_I2S_CHAN_SEL(params_channels(params))); 470 struct snd_pcm_hw_params *params,
471 struct snd_soc_dai *dai)
472{
473 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
474 unsigned int word_size = params_width(params);
475 unsigned int slot_width = params_physical_width(params);
476 unsigned int channels = params_channels(params);
477 unsigned int slots = channels;
478 int ret, sr, wss;
479 u32 width;
480
481 if (i2s->slots)
482 slots = i2s->slots;
483
484 if (i2s->slot_width)
485 slot_width = i2s->slot_width;
418 486
419 if (i2s->variant->has_chsel_tx_chen) 487 ret = i2s->variant->set_chan_cfg(i2s, params);
420 regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, 488 if (ret < 0) {
421 SUN8I_I2S_TX_CHAN_EN_MASK, 489 dev_err(dai->dev, "Invalid channel configuration\n");
422 SUN8I_I2S_TX_CHAN_EN(channels)); 490 return ret;
491 }
423 492
424 switch (params_physical_width(params)) { 493 switch (params_physical_width(params)) {
425 case 16: 494 case 16:
@@ -432,11 +501,11 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
432 } 501 }
433 i2s->playback_dma_data.addr_width = width; 502 i2s->playback_dma_data.addr_width = width;
434 503
435 sr = i2s->variant->get_sr(i2s, params_width(params)); 504 sr = i2s->variant->get_sr(i2s, word_size);
436 if (sr < 0) 505 if (sr < 0)
437 return -EINVAL; 506 return -EINVAL;
438 507
439 wss = i2s->variant->get_wss(i2s, params_width(params)); 508 wss = i2s->variant->get_wss(i2s, slot_width);
440 if (wss < 0) 509 if (wss < 0)
441 return -EINVAL; 510 return -EINVAL;
442 511
@@ -444,126 +513,193 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
444 regmap_field_write(i2s->field_fmt_sr, sr); 513 regmap_field_write(i2s->field_fmt_sr, sr);
445 514
446 return sun4i_i2s_set_clk_rate(dai, params_rate(params), 515 return sun4i_i2s_set_clk_rate(dai, params_rate(params),
447 params_width(params)); 516 slots, slot_width);
448} 517}
449 518
450static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 519static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
520 unsigned int fmt)
451{ 521{
452 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
453 u32 val; 522 u32 val;
454 u32 offset = 0; 523
455 u32 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL; 524 /* DAI clock polarity */
456 u32 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL; 525 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
526 case SND_SOC_DAIFMT_IB_IF:
527 /* Invert both clocks */
528 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
529 SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
530 break;
531 case SND_SOC_DAIFMT_IB_NF:
532 /* Invert bit clock */
533 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED;
534 break;
535 case SND_SOC_DAIFMT_NB_IF:
536 /* Invert frame clock */
537 val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
538 break;
539 case SND_SOC_DAIFMT_NB_NF:
540 val = 0;
541 break;
542 default:
543 return -EINVAL;
544 }
545
546 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
547 SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK |
548 SUN4I_I2S_FMT0_BCLK_POLARITY_MASK,
549 val);
457 550
458 /* DAI Mode */ 551 /* DAI Mode */
459 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 552 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
460 case SND_SOC_DAIFMT_I2S: 553 case SND_SOC_DAIFMT_I2S:
461 val = SUN4I_I2S_FMT0_FMT_I2S; 554 val = SUN4I_I2S_FMT0_FMT_I2S;
462 offset = 1;
463 break; 555 break;
556
464 case SND_SOC_DAIFMT_LEFT_J: 557 case SND_SOC_DAIFMT_LEFT_J:
465 val = SUN4I_I2S_FMT0_FMT_LEFT_J; 558 val = SUN4I_I2S_FMT0_FMT_LEFT_J;
466 break; 559 break;
560
467 case SND_SOC_DAIFMT_RIGHT_J: 561 case SND_SOC_DAIFMT_RIGHT_J:
468 val = SUN4I_I2S_FMT0_FMT_RIGHT_J; 562 val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
469 break; 563 break;
564
470 default: 565 default:
471 dev_err(dai->dev, "Unsupported format: %d\n",
472 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
473 return -EINVAL; 566 return -EINVAL;
474 } 567 }
475 568
476 if (i2s->variant->has_chsel_offset) { 569 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
477 /* 570 SUN4I_I2S_FMT0_FMT_MASK, val);
478 * offset being set indicates that we're connected to an i2s
479 * device, however offset is only used on the sun8i block and
480 * i2s shares the same setting with the LJ format. Increment
481 * val so that the bit to value to write is correct.
482 */
483 if (offset > 0)
484 val++;
485 /* blck offset determines whether i2s or LJ */
486 regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
487 SUN8I_I2S_TX_CHAN_OFFSET_MASK,
488 SUN8I_I2S_TX_CHAN_OFFSET(offset));
489
490 regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
491 SUN8I_I2S_TX_CHAN_OFFSET_MASK,
492 SUN8I_I2S_TX_CHAN_OFFSET(offset));
493 }
494 571
495 regmap_field_write(i2s->field_fmt_mode, val); 572 /* DAI clock master masks */
573 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
574 case SND_SOC_DAIFMT_CBS_CFS:
575 /* BCLK and LRCLK master */
576 val = SUN4I_I2S_CTRL_MODE_MASTER;
577 break;
496 578
497 /* DAI clock polarity */ 579 case SND_SOC_DAIFMT_CBM_CFM:
580 /* BCLK and LRCLK slave */
581 val = SUN4I_I2S_CTRL_MODE_SLAVE;
582 break;
583
584 default:
585 return -EINVAL;
586 }
587 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
588 SUN4I_I2S_CTRL_MODE_MASK, val);
589 return 0;
590}
591
592static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
593 unsigned int fmt)
594{
595 u32 mode, val;
596 u8 offset;
597
598 /*
599 * DAI clock polarity
600 *
601 * The setup for LRCK contradicts the datasheet, but under a
602 * scope it's clear that the LRCK polarity is reversed
603 * compared to the expected polarity on the bus.
604 */
498 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 605 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
499 case SND_SOC_DAIFMT_IB_IF: 606 case SND_SOC_DAIFMT_IB_IF:
500 /* Invert both clocks */ 607 /* Invert both clocks */
501 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; 608 val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
502 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED;
503 break; 609 break;
504 case SND_SOC_DAIFMT_IB_NF: 610 case SND_SOC_DAIFMT_IB_NF:
505 /* Invert bit clock */ 611 /* Invert bit clock */
506 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; 612 val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED |
613 SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
507 break; 614 break;
508 case SND_SOC_DAIFMT_NB_IF: 615 case SND_SOC_DAIFMT_NB_IF:
509 /* Invert frame clock */ 616 /* Invert frame clock */
510 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; 617 val = 0;
511 break; 618 break;
512 case SND_SOC_DAIFMT_NB_NF: 619 case SND_SOC_DAIFMT_NB_NF:
620 val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
513 break; 621 break;
514 default: 622 default:
515 dev_err(dai->dev, "Unsupported clock polarity: %d\n",
516 fmt & SND_SOC_DAIFMT_INV_MASK);
517 return -EINVAL; 623 return -EINVAL;
518 } 624 }
519 625
520 regmap_field_write(i2s->field_fmt_bclk, bclk_polarity); 626 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
521 regmap_field_write(i2s->field_fmt_lrclk, lrclk_polarity); 627 SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
522 628 SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
523 if (i2s->variant->has_slave_select_bit) { 629 val);
524 /* DAI clock master masks */ 630
525 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 631 /* DAI Mode */
526 case SND_SOC_DAIFMT_CBS_CFS: 632 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
527 /* BCLK and LRCLK master */ 633 case SND_SOC_DAIFMT_DSP_A:
528 val = SUN4I_I2S_CTRL_MODE_MASTER; 634 mode = SUN8I_I2S_CTRL_MODE_PCM;
529 break; 635 offset = 1;
530 case SND_SOC_DAIFMT_CBM_CFM: 636 break;
531 /* BCLK and LRCLK slave */ 637
532 val = SUN4I_I2S_CTRL_MODE_SLAVE; 638 case SND_SOC_DAIFMT_DSP_B:
533 break; 639 mode = SUN8I_I2S_CTRL_MODE_PCM;
534 default: 640 offset = 0;
535 dev_err(dai->dev, "Unsupported slave setting: %d\n", 641 break;
536 fmt & SND_SOC_DAIFMT_MASTER_MASK); 642
537 return -EINVAL; 643 case SND_SOC_DAIFMT_I2S:
538 } 644 mode = SUN8I_I2S_CTRL_MODE_LEFT;
539 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 645 offset = 1;
540 SUN4I_I2S_CTRL_MODE_MASK, 646 break;
541 val); 647
542 } else { 648 case SND_SOC_DAIFMT_LEFT_J:
543 /* 649 mode = SUN8I_I2S_CTRL_MODE_LEFT;
544 * The newer i2s block does not have a slave select bit, 650 offset = 0;
545 * instead the clk pins are configured as inputs. 651 break;
546 */ 652
547 /* DAI clock master masks */ 653 case SND_SOC_DAIFMT_RIGHT_J:
548 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 654 mode = SUN8I_I2S_CTRL_MODE_RIGHT;
549 case SND_SOC_DAIFMT_CBS_CFS: 655 offset = 0;
550 /* BCLK and LRCLK master */ 656 break;
551 val = SUN8I_I2S_CTRL_BCLK_OUT | 657
552 SUN8I_I2S_CTRL_LRCK_OUT; 658 default:
553 break; 659 return -EINVAL;
554 case SND_SOC_DAIFMT_CBM_CFM: 660 }
555 /* BCLK and LRCLK slave */ 661
556 val = 0; 662 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
557 break; 663 SUN8I_I2S_CTRL_MODE_MASK, mode);
558 default: 664 regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
559 dev_err(dai->dev, "Unsupported slave setting: %d\n", 665 SUN8I_I2S_TX_CHAN_OFFSET_MASK,
560 fmt & SND_SOC_DAIFMT_MASTER_MASK); 666 SUN8I_I2S_TX_CHAN_OFFSET(offset));
561 return -EINVAL; 667 regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
562 } 668 SUN8I_I2S_TX_CHAN_OFFSET_MASK,
563 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 669 SUN8I_I2S_TX_CHAN_OFFSET(offset));
564 SUN8I_I2S_CTRL_BCLK_OUT | 670
565 SUN8I_I2S_CTRL_LRCK_OUT, 671 /* DAI clock master masks */
566 val); 672 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
673 case SND_SOC_DAIFMT_CBS_CFS:
674 /* BCLK and LRCLK master */
675 val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT;
676 break;
677
678 case SND_SOC_DAIFMT_CBM_CFM:
679 /* BCLK and LRCLK slave */
680 val = 0;
681 break;
682
683 default:
684 return -EINVAL;
685 }
686
687 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
688 SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
689 val);
690
691 return 0;
692}
693
694static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
695{
696 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
697 int ret;
698
699 ret = i2s->variant->set_fmt(i2s, fmt);
700 if (ret) {
701 dev_err(dai->dev, "Unsupported format configuration\n");
702 return ret;
567 } 703 }
568 704
569 /* Set significant bits in our FIFOs */ 705 /* Set significant bits in our FIFOs */
@@ -572,6 +708,9 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
572 SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK, 708 SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
573 SUN4I_I2S_FIFO_CTRL_TX_MODE(1) | 709 SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
574 SUN4I_I2S_FIFO_CTRL_RX_MODE(1)); 710 SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
711
712 i2s->format = fmt;
713
575 return 0; 714 return 0;
576} 715}
577 716
@@ -687,10 +826,26 @@ static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
687 return 0; 826 return 0;
688} 827}
689 828
829static int sun4i_i2s_set_tdm_slot(struct snd_soc_dai *dai,
830 unsigned int tx_mask, unsigned int rx_mask,
831 int slots, int slot_width)
832{
833 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
834
835 if (slots > 8)
836 return -EINVAL;
837
838 i2s->slots = slots;
839 i2s->slot_width = slot_width;
840
841 return 0;
842}
843
690static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = { 844static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
691 .hw_params = sun4i_i2s_hw_params, 845 .hw_params = sun4i_i2s_hw_params,
692 .set_fmt = sun4i_i2s_set_fmt, 846 .set_fmt = sun4i_i2s_set_fmt,
693 .set_sysclk = sun4i_i2s_set_sysclk, 847 .set_sysclk = sun4i_i2s_set_sysclk,
848 .set_tdm_slot = sun4i_i2s_set_tdm_slot,
694 .trigger = sun4i_i2s_trigger, 849 .trigger = sun4i_i2s_trigger,
695}; 850};
696 851
@@ -711,15 +866,15 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
711 .probe = sun4i_i2s_dai_probe, 866 .probe = sun4i_i2s_dai_probe,
712 .capture = { 867 .capture = {
713 .stream_name = "Capture", 868 .stream_name = "Capture",
714 .channels_min = 2, 869 .channels_min = 1,
715 .channels_max = 2, 870 .channels_max = 8,
716 .rates = SNDRV_PCM_RATE_8000_192000, 871 .rates = SNDRV_PCM_RATE_8000_192000,
717 .formats = SNDRV_PCM_FMTBIT_S16_LE, 872 .formats = SNDRV_PCM_FMTBIT_S16_LE,
718 }, 873 },
719 .playback = { 874 .playback = {
720 .stream_name = "Playback", 875 .stream_name = "Playback",
721 .channels_min = 2, 876 .channels_min = 1,
722 .channels_max = 2, 877 .channels_max = 8,
723 .rates = SNDRV_PCM_RATE_8000_192000, 878 .rates = SNDRV_PCM_RATE_8000_192000,
724 .formats = SNDRV_PCM_FMTBIT_S16_LE, 879 .formats = SNDRV_PCM_FMTBIT_S16_LE,
725 }, 880 },
@@ -913,16 +1068,15 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
913 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), 1068 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
914 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), 1069 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
915 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), 1070 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
916 .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), 1071 .bclk_dividers = sun4i_i2s_bclk_div,
917 .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), 1072 .num_bclk_dividers = ARRAY_SIZE(sun4i_i2s_bclk_div),
918 .has_slave_select_bit = true, 1073 .mclk_dividers = sun4i_i2s_mclk_div,
919 .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), 1074 .num_mclk_dividers = ARRAY_SIZE(sun4i_i2s_mclk_div),
920 .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), 1075 .get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate,
921 .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
922 .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
923 .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
924 .get_sr = sun4i_i2s_get_sr, 1076 .get_sr = sun4i_i2s_get_sr,
925 .get_wss = sun4i_i2s_get_wss, 1077 .get_wss = sun4i_i2s_get_wss,
1078 .set_chan_cfg = sun4i_i2s_set_chan_cfg,
1079 .set_fmt = sun4i_i2s_set_soc_fmt,
926}; 1080};
927 1081
928static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { 1082static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
@@ -932,18 +1086,22 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
932 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), 1086 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
933 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), 1087 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
934 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), 1088 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
935 .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), 1089 .bclk_dividers = sun4i_i2s_bclk_div,
936 .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), 1090 .num_bclk_dividers = ARRAY_SIZE(sun4i_i2s_bclk_div),
937 .has_slave_select_bit = true, 1091 .mclk_dividers = sun4i_i2s_mclk_div,
938 .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), 1092 .num_mclk_dividers = ARRAY_SIZE(sun4i_i2s_mclk_div),
939 .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), 1093 .get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate,
940 .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
941 .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
942 .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
943 .get_sr = sun4i_i2s_get_sr, 1094 .get_sr = sun4i_i2s_get_sr,
944 .get_wss = sun4i_i2s_get_wss, 1095 .get_wss = sun4i_i2s_get_wss,
1096 .set_chan_cfg = sun4i_i2s_set_chan_cfg,
1097 .set_fmt = sun4i_i2s_set_soc_fmt,
945}; 1098};
946 1099
1100/*
1101 * This doesn't describe the TDM controller documented in the A83t
1102 * datasheet, but the three undocumented I2S controller that use the
1103 * older design.
1104 */
947static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = { 1105static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
948 .has_reset = true, 1106 .has_reset = true,
949 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, 1107 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG,
@@ -951,59 +1109,51 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
951 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), 1109 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
952 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), 1110 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
953 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), 1111 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
954 .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), 1112 .bclk_dividers = sun4i_i2s_bclk_div,
955 .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), 1113 .num_bclk_dividers = ARRAY_SIZE(sun4i_i2s_bclk_div),
956 .has_slave_select_bit = true, 1114 .mclk_dividers = sun4i_i2s_mclk_div,
957 .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), 1115 .num_mclk_dividers = ARRAY_SIZE(sun4i_i2s_mclk_div),
958 .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), 1116 .get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate,
959 .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), 1117 .get_sr = sun4i_i2s_get_sr,
960 .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), 1118 .get_wss = sun4i_i2s_get_wss,
961 .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), 1119 .set_chan_cfg = sun4i_i2s_set_chan_cfg,
962 .get_sr = sun8i_i2s_get_sr_wss, 1120 .set_fmt = sun4i_i2s_set_soc_fmt,
963 .get_wss = sun8i_i2s_get_sr_wss,
964}; 1121};
965 1122
966static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { 1123static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
967 .has_reset = true, 1124 .has_reset = true,
968 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, 1125 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG,
969 .sun4i_i2s_regmap = &sun8i_i2s_regmap_config, 1126 .sun4i_i2s_regmap = &sun8i_i2s_regmap_config,
970 .mclk_offset = 1,
971 .bclk_offset = 2,
972 .has_fmt_set_lrck_period = true,
973 .has_chcfg = true,
974 .has_chsel_tx_chen = true,
975 .has_chsel_offset = true,
976 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8), 1127 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
977 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2), 1128 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
978 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6), 1129 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
979 .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), 1130 .bclk_dividers = sun8i_i2s_clk_div,
980 .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19), 1131 .num_bclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div),
981 .field_fmt_mode = REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5), 1132 .mclk_dividers = sun8i_i2s_clk_div,
982 .field_txchanmap = REG_FIELD(SUN8I_I2S_TX_CHAN_MAP_REG, 0, 31), 1133 .num_mclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div),
983 .field_rxchanmap = REG_FIELD(SUN8I_I2S_RX_CHAN_MAP_REG, 0, 31), 1134 .get_bclk_parent_rate = sun8i_i2s_get_bclk_parent_rate,
984 .field_txchansel = REG_FIELD(SUN8I_I2S_TX_CHAN_SEL_REG, 0, 2),
985 .field_rxchansel = REG_FIELD(SUN8I_I2S_RX_CHAN_SEL_REG, 0, 2),
986 .get_sr = sun8i_i2s_get_sr_wss, 1135 .get_sr = sun8i_i2s_get_sr_wss,
987 .get_wss = sun8i_i2s_get_sr_wss, 1136 .get_wss = sun8i_i2s_get_sr_wss,
1137 .set_chan_cfg = sun8i_i2s_set_chan_cfg,
1138 .set_fmt = sun8i_i2s_set_soc_fmt,
988}; 1139};
989 1140
990static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { 1141static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
991 .has_reset = true, 1142 .has_reset = true,
992 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, 1143 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG,
993 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, 1144 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config,
994 .has_slave_select_bit = true,
995 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), 1145 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
996 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), 1146 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
997 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), 1147 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
998 .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), 1148 .bclk_dividers = sun4i_i2s_bclk_div,
999 .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), 1149 .num_bclk_dividers = ARRAY_SIZE(sun4i_i2s_bclk_div),
1000 .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), 1150 .mclk_dividers = sun4i_i2s_mclk_div,
1001 .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), 1151 .num_mclk_dividers = ARRAY_SIZE(sun4i_i2s_mclk_div),
1002 .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), 1152 .get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate,
1003 .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
1004 .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
1005 .get_sr = sun4i_i2s_get_sr, 1153 .get_sr = sun4i_i2s_get_sr,
1006 .get_wss = sun4i_i2s_get_wss, 1154 .get_wss = sun4i_i2s_get_wss,
1155 .set_chan_cfg = sun4i_i2s_set_chan_cfg,
1156 .set_fmt = sun4i_i2s_set_soc_fmt,
1007}; 1157};
1008 1158
1009static int sun4i_i2s_init_regmap_fields(struct device *dev, 1159static int sun4i_i2s_init_regmap_fields(struct device *dev,
@@ -1027,46 +1177,7 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev,
1027 if (IS_ERR(i2s->field_fmt_sr)) 1177 if (IS_ERR(i2s->field_fmt_sr))
1028 return PTR_ERR(i2s->field_fmt_sr); 1178 return PTR_ERR(i2s->field_fmt_sr);
1029 1179
1030 i2s->field_fmt_bclk = 1180 return 0;
1031 devm_regmap_field_alloc(dev, i2s->regmap,
1032 i2s->variant->field_fmt_bclk);
1033 if (IS_ERR(i2s->field_fmt_bclk))
1034 return PTR_ERR(i2s->field_fmt_bclk);
1035
1036 i2s->field_fmt_lrclk =
1037 devm_regmap_field_alloc(dev, i2s->regmap,
1038 i2s->variant->field_fmt_lrclk);
1039 if (IS_ERR(i2s->field_fmt_lrclk))
1040 return PTR_ERR(i2s->field_fmt_lrclk);
1041
1042 i2s->field_fmt_mode =
1043 devm_regmap_field_alloc(dev, i2s->regmap,
1044 i2s->variant->field_fmt_mode);
1045 if (IS_ERR(i2s->field_fmt_mode))
1046 return PTR_ERR(i2s->field_fmt_mode);
1047
1048 i2s->field_txchanmap =
1049 devm_regmap_field_alloc(dev, i2s->regmap,
1050 i2s->variant->field_txchanmap);
1051 if (IS_ERR(i2s->field_txchanmap))
1052 return PTR_ERR(i2s->field_txchanmap);
1053
1054 i2s->field_rxchanmap =
1055 devm_regmap_field_alloc(dev, i2s->regmap,
1056 i2s->variant->field_rxchanmap);
1057 if (IS_ERR(i2s->field_rxchanmap))
1058 return PTR_ERR(i2s->field_rxchanmap);
1059
1060 i2s->field_txchansel =
1061 devm_regmap_field_alloc(dev, i2s->regmap,
1062 i2s->variant->field_txchansel);
1063 if (IS_ERR(i2s->field_txchansel))
1064 return PTR_ERR(i2s->field_txchansel);
1065
1066 i2s->field_rxchansel =
1067 devm_regmap_field_alloc(dev, i2s->regmap,
1068 i2s->variant->field_rxchansel);
1069 return PTR_ERR_OR_ZERO(i2s->field_rxchansel);
1070} 1181}
1071 1182
1072static int sun4i_i2s_probe(struct platform_device *pdev) 1183static int sun4i_i2s_probe(struct platform_device *pdev)
@@ -1087,10 +1198,8 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
1087 return PTR_ERR(regs); 1198 return PTR_ERR(regs);
1088 1199
1089 irq = platform_get_irq(pdev, 0); 1200 irq = platform_get_irq(pdev, 0);
1090 if (irq < 0) { 1201 if (irq < 0)
1091 dev_err(&pdev->dev, "Can't retrieve our interrupt\n");
1092 return irq; 1202 return irq;
1093 }
1094 1203
1095 i2s->variant = of_device_get_match_data(&pdev->dev); 1204 i2s->variant = of_device_get_match_data(&pdev->dev);
1096 if (!i2s->variant) { 1205 if (!i2s->variant) {
@@ -1154,7 +1263,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
1154 goto err_suspend; 1263 goto err_suspend;
1155 } 1264 }
1156 1265
1157 ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 1266 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
1158 if (ret) { 1267 if (ret) {
1159 dev_err(&pdev->dev, "Could not register PCM\n"); 1268 dev_err(&pdev->dev, "Could not register PCM\n");
1160 goto err_suspend; 1269 goto err_suspend;
@@ -1185,8 +1294,6 @@ static int sun4i_i2s_remove(struct platform_device *pdev)
1185{ 1294{
1186 struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev); 1295 struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev);
1187 1296
1188 snd_dmaengine_pcm_unregister(&pdev->dev);
1189
1190 pm_runtime_disable(&pdev->dev); 1297 pm_runtime_disable(&pdev->dev);
1191 if (!pm_runtime_status_suspended(&pdev->dev)) 1298 if (!pm_runtime_status_suspended(&pdev->dev))
1192 sun4i_i2s_runtime_suspend(&pdev->dev); 1299 sun4i_i2s_runtime_suspend(&pdev->dev);
diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index 6d1de565350e..f5b7069bcca2 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -459,12 +459,10 @@ MODULE_DEVICE_TABLE(of, sun50i_codec_analog_of_match);
459 459
460static int sun50i_codec_analog_probe(struct platform_device *pdev) 460static int sun50i_codec_analog_probe(struct platform_device *pdev)
461{ 461{
462 struct resource *res;
463 struct regmap *regmap; 462 struct regmap *regmap;
464 void __iomem *base; 463 void __iomem *base;
465 464
466 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 465 base = devm_platform_ioremap_resource(pdev, 0);
467 base = devm_ioremap_resource(&pdev->dev, res);
468 if (IS_ERR(base)) { 466 if (IS_ERR(base)) {
469 dev_err(&pdev->dev, "Failed to map the registers\n"); 467 dev_err(&pdev->dev, "Failed to map the registers\n");
470 return PTR_ERR(base); 468 return PTR_ERR(base);
diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
index e92aeedd6feb..be872eefa61e 100644
--- a/sound/soc/sunxi/sun8i-codec-analog.c
+++ b/sound/soc/sunxi/sun8i-codec-analog.c
@@ -819,12 +819,10 @@ MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
819 819
820static int sun8i_codec_analog_probe(struct platform_device *pdev) 820static int sun8i_codec_analog_probe(struct platform_device *pdev)
821{ 821{
822 struct resource *res;
823 struct regmap *regmap; 822 struct regmap *regmap;
824 void __iomem *base; 823 void __iomem *base;
825 824
826 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 825 base = devm_platform_ioremap_resource(pdev, 0);
827 base = devm_ioremap_resource(&pdev->dev, res);
828 if (IS_ERR(base)) { 826 if (IS_ERR(base)) {
829 dev_err(&pdev->dev, "Failed to map the registers\n"); 827 dev_err(&pdev->dev, "Failed to map the registers\n");
830 return PTR_ERR(base); 828 return PTR_ERR(base);
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 0e0e8ebaa571..55798bc8eae2 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -533,7 +533,6 @@ static const struct regmap_config sun8i_codec_regmap_config = {
533 533
534static int sun8i_codec_probe(struct platform_device *pdev) 534static int sun8i_codec_probe(struct platform_device *pdev)
535{ 535{
536 struct resource *res_base;
537 struct sun8i_codec *scodec; 536 struct sun8i_codec *scodec;
538 void __iomem *base; 537 void __iomem *base;
539 int ret; 538 int ret;
@@ -556,8 +555,7 @@ static int sun8i_codec_probe(struct platform_device *pdev)
556 return PTR_ERR(scodec->clk_bus); 555 return PTR_ERR(scodec->clk_bus);
557 } 556 }
558 557
559 res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); 558 base = devm_platform_ioremap_resource(pdev, 0);
560 base = devm_ioremap_resource(&pdev->dev, res_base);
561 if (IS_ERR(base)) { 559 if (IS_ERR(base)) {
562 dev_err(&pdev->dev, "Failed to map the registers\n"); 560 dev_err(&pdev->dev, "Failed to map the registers\n");
563 return PTR_ERR(base); 561 return PTR_ERR(base);
diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c
index 10f9c3b19c88..1070b2710d5e 100644
--- a/sound/soc/tegra/tegra20_das.c
+++ b/sound/soc/tegra/tegra20_das.c
@@ -120,7 +120,6 @@ static const struct regmap_config tegra20_das_regmap_config = {
120 120
121static int tegra20_das_probe(struct platform_device *pdev) 121static int tegra20_das_probe(struct platform_device *pdev)
122{ 122{
123 struct resource *res;
124 void __iomem *regs; 123 void __iomem *regs;
125 int ret = 0; 124 int ret = 0;
126 125
@@ -134,8 +133,7 @@ static int tegra20_das_probe(struct platform_device *pdev)
134 } 133 }
135 das->dev = &pdev->dev; 134 das->dev = &pdev->dev;
136 135
137 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 136 regs = devm_platform_ioremap_resource(pdev, 0);
138 regs = devm_ioremap_resource(&pdev->dev, res);
139 if (IS_ERR(regs)) { 137 if (IS_ERR(regs)) {
140 ret = PTR_ERR(regs); 138 ret = PTR_ERR(regs);
141 goto err; 139 goto err;
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index 952381260dc3..635eacbd28d4 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -511,7 +511,7 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
511 const struct tegra30_ahub_soc_data *soc_data; 511 const struct tegra30_ahub_soc_data *soc_data;
512 struct reset_control *rst; 512 struct reset_control *rst;
513 int i; 513 int i;
514 struct resource *res0, *res1; 514 struct resource *res0;
515 void __iomem *regs_apbif, *regs_ahub; 515 void __iomem *regs_apbif, *regs_ahub;
516 int ret = 0; 516 int ret = 0;
517 517
@@ -587,8 +587,7 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
587 } 587 }
588 regcache_cache_only(ahub->regmap_apbif, true); 588 regcache_cache_only(ahub->regmap_apbif, true);
589 589
590 res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); 590 regs_ahub = devm_platform_ioremap_resource(pdev, 1);
591 regs_ahub = devm_ioremap_resource(&pdev->dev, res1);
592 if (IS_ERR(regs_ahub)) 591 if (IS_ERR(regs_ahub))
593 return PTR_ERR(regs_ahub); 592 return PTR_ERR(regs_ahub);
594 593
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index ac6983c6bd72..e6d548fa980b 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -368,7 +368,6 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
368 struct tegra30_i2s *i2s; 368 struct tegra30_i2s *i2s;
369 const struct of_device_id *match; 369 const struct of_device_id *match;
370 u32 cif_ids[2]; 370 u32 cif_ids[2];
371 struct resource *mem;
372 void __iomem *regs; 371 void __iomem *regs;
373 int ret; 372 int ret;
374 373
@@ -406,8 +405,7 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
406 goto err; 405 goto err;
407 } 406 }
408 407
409 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 408 regs = devm_platform_ioremap_resource(pdev, 0);
410 regs = devm_ioremap_resource(&pdev->dev, mem);
411 if (IS_ERR(regs)) { 409 if (IS_ERR(regs)) {
412 ret = PTR_ERR(regs); 410 ret = PTR_ERR(regs);
413 goto err_clk_put; 411 goto err_clk_put;
diff --git a/sound/soc/ti/Kconfig b/sound/soc/ti/Kconfig
index 2197f3e1eaed..87a9b9dd4e98 100644
--- a/sound/soc/ti/Kconfig
+++ b/sound/soc/ti/Kconfig
@@ -12,7 +12,7 @@ config SND_SOC_TI_SDMA_PCM
12 12
13comment "Texas Instruments DAI support for:" 13comment "Texas Instruments DAI support for:"
14config SND_SOC_DAVINCI_ASP 14config SND_SOC_DAVINCI_ASP
15 tristate "daVinci Audio Serial Port (ASP) or McBSP suport" 15 tristate "daVinci Audio Serial Port (ASP) or McBSP support"
16 depends on ARCH_DAVINCI || COMPILE_TEST 16 depends on ARCH_DAVINCI || COMPILE_TEST
17 select SND_SOC_TI_EDMA_PCM 17 select SND_SOC_TI_EDMA_PCM
18 help 18 help
@@ -33,7 +33,7 @@ config SND_SOC_DAVINCI_MCASP
33 - Keystone devices 33 - Keystone devices
34 34
35config SND_SOC_DAVINCI_VCIF 35config SND_SOC_DAVINCI_VCIF
36 tristate "daVinci Voice Interface (VCIF) suport" 36 tristate "daVinci Voice Interface (VCIF) support"
37 depends on ARCH_DAVINCI || COMPILE_TEST 37 depends on ARCH_DAVINCI || COMPILE_TEST
38 select SND_SOC_TI_EDMA_PCM 38 select SND_SOC_TI_EDMA_PCM
39 help 39 help
diff --git a/sound/soc/ti/davinci-evm.c b/sound/soc/ti/davinci-evm.c
index bfd8d1a03ba7..686b23d7a90d 100644
--- a/sound/soc/ti/davinci-evm.c
+++ b/sound/soc/ti/davinci-evm.c
@@ -68,7 +68,7 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
68 68
69 /* set the CPU system clock */ 69 /* set the CPU system clock */
70 ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT); 70 ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
71 if (ret < 0) 71 if (ret < 0 && ret != -ENOTSUPP)
72 return ret; 72 return ret;
73 73
74 return 0; 74 return 0;
diff --git a/sound/soc/ti/davinci-i2s.c b/sound/soc/ti/davinci-i2s.c
index 27afdbb9adf3..d89b5c928c4d 100644
--- a/sound/soc/ti/davinci-i2s.c
+++ b/sound/soc/ti/davinci-i2s.c
@@ -598,6 +598,8 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
598} 598}
599 599
600#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 600#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
601#define DAVINCI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
602 SNDRV_PCM_FMTBIT_S32_LE)
601 603
602static const struct snd_soc_dai_ops davinci_i2s_dai_ops = { 604static const struct snd_soc_dai_ops davinci_i2s_dai_ops = {
603 .shutdown = davinci_i2s_shutdown, 605 .shutdown = davinci_i2s_shutdown,
@@ -625,12 +627,14 @@ static struct snd_soc_dai_driver davinci_i2s_dai = {
625 .channels_min = 2, 627 .channels_min = 2,
626 .channels_max = 2, 628 .channels_max = 2,
627 .rates = DAVINCI_I2S_RATES, 629 .rates = DAVINCI_I2S_RATES,
628 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 630 .formats = DAVINCI_I2S_FORMATS,
631 },
629 .capture = { 632 .capture = {
630 .channels_min = 2, 633 .channels_min = 2,
631 .channels_max = 2, 634 .channels_max = 2,
632 .rates = DAVINCI_I2S_RATES, 635 .rates = DAVINCI_I2S_RATES,
633 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 636 .formats = DAVINCI_I2S_FORMATS,
637 },
634 .ops = &davinci_i2s_dai_ops, 638 .ops = &davinci_i2s_dai_ops,
635 639
636}; 640};
diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c
index bc7bf15ed7a4..7aa3c32e4a49 100644
--- a/sound/soc/ti/davinci-mcasp.c
+++ b/sound/soc/ti/davinci-mcasp.c
@@ -109,6 +109,8 @@ struct davinci_mcasp {
109 109
110 /* Used for comstraint setting on the second stream */ 110 /* Used for comstraint setting on the second stream */
111 u32 channels; 111 u32 channels;
112 int max_format_width;
113 u8 active_serializers[2];
112 114
113#ifdef CONFIG_GPIOLIB 115#ifdef CONFIG_GPIOLIB
114 struct gpio_chip gpio_chip; 116 struct gpio_chip gpio_chip;
@@ -466,6 +468,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
466 /* FS need to be inverted */ 468 /* FS need to be inverted */
467 inv_fs = true; 469 inv_fs = true;
468 break; 470 break;
471 case SND_SOC_DAIFMT_RIGHT_J:
469 case SND_SOC_DAIFMT_LEFT_J: 472 case SND_SOC_DAIFMT_LEFT_J:
470 /* configure a full-word SYNC pulse (LRCLK) */ 473 /* configure a full-word SYNC pulse (LRCLK) */
471 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); 474 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
@@ -759,34 +762,30 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
759 int sample_width) 762 int sample_width)
760{ 763{
761 u32 fmt; 764 u32 fmt;
762 u32 tx_rotate = (sample_width / 4) & 0x7; 765 u32 tx_rotate, rx_rotate, slot_width;
763 u32 mask = (1ULL << sample_width) - 1; 766 u32 mask = (1ULL << sample_width) - 1;
764 u32 slot_width = sample_width;
765
766 /*
767 * For captured data we should not rotate, inversion and masking is
768 * enoguh to get the data to the right position:
769 * Format data from bus after reverse (XRBUF)
770 * S16_LE: |LSB|MSB|xxx|xxx| |xxx|xxx|MSB|LSB|
771 * S24_3LE: |LSB|DAT|MSB|xxx| |xxx|MSB|DAT|LSB|
772 * S24_LE: |LSB|DAT|MSB|xxx| |xxx|MSB|DAT|LSB|
773 * S32_LE: |LSB|DAT|DAT|MSB| |MSB|DAT|DAT|LSB|
774 */
775 u32 rx_rotate = 0;
776 767
768 if (mcasp->slot_width)
769 slot_width = mcasp->slot_width;
770 else if (mcasp->max_format_width)
771 slot_width = mcasp->max_format_width;
772 else
773 slot_width = sample_width;
777 /* 774 /*
778 * Setting the tdm slot width either with set_clkdiv() or 775 * TX rotation:
779 * set_tdm_slot() allows us to for example send 32 bits per 776 * right aligned formats: rotate w/ slot_width
780 * channel to the codec, while only 16 of them carry audio 777 * left aligned formats: rotate w/ sample_width
781 * payload. 778 *
779 * RX rotation:
780 * right aligned formats: no rotation needed
781 * left aligned formats: rotate w/ (slot_width - sample_width)
782 */ 782 */
783 if (mcasp->slot_width) { 783 if ((mcasp->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
784 /* 784 SND_SOC_DAIFMT_RIGHT_J) {
785 * When we have more bclk then it is needed for the 785 tx_rotate = (slot_width / 4) & 0x7;
786 * data, we need to use the rotation to move the 786 rx_rotate = 0;
787 * received samples to have correct alignment. 787 } else {
788 */ 788 tx_rotate = (sample_width / 4) & 0x7;
789 slot_width = mcasp->slot_width;
790 rx_rotate = (slot_width - sample_width) / 4; 789 rx_rotate = (slot_width - sample_width) / 4;
791 } 790 }
792 791
@@ -819,6 +818,7 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
819 u8 rx_ser = 0; 818 u8 rx_ser = 0;
820 u8 slots = mcasp->tdm_slots; 819 u8 slots = mcasp->tdm_slots;
821 u8 max_active_serializers = (channels + slots - 1) / slots; 820 u8 max_active_serializers = (channels + slots - 1) / slots;
821 u8 max_rx_serializers, max_tx_serializers;
822 int active_serializers, numevt; 822 int active_serializers, numevt;
823 u32 reg; 823 u32 reg;
824 /* Default configuration */ 824 /* Default configuration */
@@ -828,22 +828,28 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
828 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 828 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
829 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); 829 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
830 mcasp_clr_bits(mcasp, DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS); 830 mcasp_clr_bits(mcasp, DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS);
831 max_tx_serializers = max_active_serializers;
832 max_rx_serializers =
833 mcasp->active_serializers[SNDRV_PCM_STREAM_CAPTURE];
831 } else { 834 } else {
832 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); 835 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
833 mcasp_clr_bits(mcasp, DAVINCI_MCASP_REVTCTL_REG, RXDATADMADIS); 836 mcasp_clr_bits(mcasp, DAVINCI_MCASP_REVTCTL_REG, RXDATADMADIS);
837 max_tx_serializers =
838 mcasp->active_serializers[SNDRV_PCM_STREAM_PLAYBACK];
839 max_rx_serializers = max_active_serializers;
834 } 840 }
835 841
836 for (i = 0; i < mcasp->num_serializer; i++) { 842 for (i = 0; i < mcasp->num_serializer; i++) {
837 mcasp_set_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), 843 mcasp_set_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
838 mcasp->serial_dir[i]); 844 mcasp->serial_dir[i]);
839 if (mcasp->serial_dir[i] == TX_MODE && 845 if (mcasp->serial_dir[i] == TX_MODE &&
840 tx_ser < max_active_serializers) { 846 tx_ser < max_tx_serializers) {
841 mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), 847 mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
842 mcasp->dismod, DISMOD_MASK); 848 mcasp->dismod, DISMOD_MASK);
843 set_bit(PIN_BIT_AXR(i), &mcasp->pdir); 849 set_bit(PIN_BIT_AXR(i), &mcasp->pdir);
844 tx_ser++; 850 tx_ser++;
845 } else if (mcasp->serial_dir[i] == RX_MODE && 851 } else if (mcasp->serial_dir[i] == RX_MODE &&
846 rx_ser < max_active_serializers) { 852 rx_ser < max_rx_serializers) {
847 clear_bit(PIN_BIT_AXR(i), &mcasp->pdir); 853 clear_bit(PIN_BIT_AXR(i), &mcasp->pdir);
848 rx_ser++; 854 rx_ser++;
849 } else { 855 } else {
@@ -890,7 +896,8 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
890 } else { 896 } else {
891 dma_data->maxburst = 0; 897 dma_data->maxburst = 0;
892 } 898 }
893 return 0; 899
900 goto out;
894 } 901 }
895 902
896 if (period_words % active_serializers) { 903 if (period_words % active_serializers) {
@@ -920,6 +927,9 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
920 numevt = 0; 927 numevt = 0;
921 dma_data->maxburst = numevt; 928 dma_data->maxburst = numevt;
922 929
930out:
931 mcasp->active_serializers[stream] = active_serializers;
932
923 return 0; 933 return 0;
924} 934}
925 935
@@ -1159,6 +1169,37 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
1159 int period_size = params_period_size(params); 1169 int period_size = params_period_size(params);
1160 int ret; 1170 int ret;
1161 1171
1172 switch (params_format(params)) {
1173 case SNDRV_PCM_FORMAT_U8:
1174 case SNDRV_PCM_FORMAT_S8:
1175 word_length = 8;
1176 break;
1177
1178 case SNDRV_PCM_FORMAT_U16_LE:
1179 case SNDRV_PCM_FORMAT_S16_LE:
1180 word_length = 16;
1181 break;
1182
1183 case SNDRV_PCM_FORMAT_U24_3LE:
1184 case SNDRV_PCM_FORMAT_S24_3LE:
1185 word_length = 24;
1186 break;
1187
1188 case SNDRV_PCM_FORMAT_U24_LE:
1189 case SNDRV_PCM_FORMAT_S24_LE:
1190 word_length = 24;
1191 break;
1192
1193 case SNDRV_PCM_FORMAT_U32_LE:
1194 case SNDRV_PCM_FORMAT_S32_LE:
1195 word_length = 32;
1196 break;
1197
1198 default:
1199 printk(KERN_WARNING "davinci-mcasp: unsupported PCM format");
1200 return -EINVAL;
1201 }
1202
1162 ret = davinci_mcasp_set_dai_fmt(cpu_dai, mcasp->dai_fmt); 1203 ret = davinci_mcasp_set_dai_fmt(cpu_dai, mcasp->dai_fmt);
1163 if (ret) 1204 if (ret)
1164 return ret; 1205 return ret;
@@ -1193,41 +1234,13 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
1193 if (ret) 1234 if (ret)
1194 return ret; 1235 return ret;
1195 1236
1196 switch (params_format(params)) {
1197 case SNDRV_PCM_FORMAT_U8:
1198 case SNDRV_PCM_FORMAT_S8:
1199 word_length = 8;
1200 break;
1201
1202 case SNDRV_PCM_FORMAT_U16_LE:
1203 case SNDRV_PCM_FORMAT_S16_LE:
1204 word_length = 16;
1205 break;
1206
1207 case SNDRV_PCM_FORMAT_U24_3LE:
1208 case SNDRV_PCM_FORMAT_S24_3LE:
1209 word_length = 24;
1210 break;
1211
1212 case SNDRV_PCM_FORMAT_U24_LE:
1213 case SNDRV_PCM_FORMAT_S24_LE:
1214 word_length = 24;
1215 break;
1216
1217 case SNDRV_PCM_FORMAT_U32_LE:
1218 case SNDRV_PCM_FORMAT_S32_LE:
1219 word_length = 32;
1220 break;
1221
1222 default:
1223 printk(KERN_WARNING "davinci-mcasp: unsupported PCM format");
1224 return -EINVAL;
1225 }
1226
1227 davinci_config_channel_size(mcasp, word_length); 1237 davinci_config_channel_size(mcasp, word_length);
1228 1238
1229 if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) 1239 if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) {
1230 mcasp->channels = channels; 1240 mcasp->channels = channels;
1241 if (!mcasp->max_format_width)
1242 mcasp->max_format_width = word_length;
1243 }
1231 1244
1232 return 0; 1245 return 0;
1233} 1246}
@@ -1279,6 +1292,28 @@ static int davinci_mcasp_hw_rule_slot_width(struct snd_pcm_hw_params *params,
1279 return snd_mask_refine(fmt, &nfmt); 1292 return snd_mask_refine(fmt, &nfmt);
1280} 1293}
1281 1294
1295static int davinci_mcasp_hw_rule_format_width(struct snd_pcm_hw_params *params,
1296 struct snd_pcm_hw_rule *rule)
1297{
1298 struct davinci_mcasp_ruledata *rd = rule->private;
1299 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1300 struct snd_mask nfmt;
1301 int i, format_width;
1302
1303 snd_mask_none(&nfmt);
1304 format_width = rd->mcasp->max_format_width;
1305
1306 for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
1307 if (snd_mask_test(fmt, i)) {
1308 if (snd_pcm_format_width(i) == format_width) {
1309 snd_mask_set(&nfmt, i);
1310 }
1311 }
1312 }
1313
1314 return snd_mask_refine(fmt, &nfmt);
1315}
1316
1282static const unsigned int davinci_mcasp_dai_rates[] = { 1317static const unsigned int davinci_mcasp_dai_rates[] = {
1283 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 1318 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
1284 88200, 96000, 176400, 192000, 1319 88200, 96000, 176400, 192000,
@@ -1433,12 +1468,13 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1433 max_channels *= tdm_slots; 1468 max_channels *= tdm_slots;
1434 /* 1469 /*
1435 * If the already active stream has less channels than the calculated 1470 * If the already active stream has less channels than the calculated
1436 * limnit based on the seirializers * tdm_slots, we need to use that as 1471 * limit based on the seirializers * tdm_slots, and only one serializer
1437 * a constraint for the second stream. 1472 * is in use we need to use that as a constraint for the second stream.
1438 * Otherwise (first stream or less allowed channels) we use the 1473 * Otherwise (first stream or less allowed channels or more than one
1439 * calculated constraint. 1474 * serializer in use) we use the calculated constraint.
1440 */ 1475 */
1441 if (mcasp->channels && mcasp->channels < max_channels) 1476 if (mcasp->channels && mcasp->channels < max_channels &&
1477 ruledata->serializers == 1)
1442 max_channels = mcasp->channels; 1478 max_channels = mcasp->channels;
1443 /* 1479 /*
1444 * But we can always allow channels upto the amount of 1480 * But we can always allow channels upto the amount of
@@ -1455,7 +1491,20 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1455 0, SNDRV_PCM_HW_PARAM_CHANNELS, 1491 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1456 &mcasp->chconstr[substream->stream]); 1492 &mcasp->chconstr[substream->stream]);
1457 1493
1458 if (mcasp->slot_width) { 1494 if (mcasp->max_format_width) {
1495 /*
1496 * Only allow formats which require same amount of bits on the
1497 * bus as the currently running stream
1498 */
1499 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
1500 SNDRV_PCM_HW_PARAM_FORMAT,
1501 davinci_mcasp_hw_rule_format_width,
1502 ruledata,
1503 SNDRV_PCM_HW_PARAM_FORMAT, -1);
1504 if (ret)
1505 return ret;
1506 }
1507 else if (mcasp->slot_width) {
1459 /* Only allow formats require <= slot_width bits on the bus */ 1508 /* Only allow formats require <= slot_width bits on the bus */
1460 ret = snd_pcm_hw_rule_add(substream->runtime, 0, 1509 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
1461 SNDRV_PCM_HW_PARAM_FORMAT, 1510 SNDRV_PCM_HW_PARAM_FORMAT,
@@ -1501,12 +1550,15 @@ static void davinci_mcasp_shutdown(struct snd_pcm_substream *substream,
1501 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); 1550 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
1502 1551
1503 mcasp->substreams[substream->stream] = NULL; 1552 mcasp->substreams[substream->stream] = NULL;
1553 mcasp->active_serializers[substream->stream] = 0;
1504 1554
1505 if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) 1555 if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
1506 return; 1556 return;
1507 1557
1508 if (!cpu_dai->active) 1558 if (!cpu_dai->active) {
1509 mcasp->channels = 0; 1559 mcasp->channels = 0;
1560 mcasp->max_format_width = 0;
1561 }
1510} 1562}
1511 1563
1512static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { 1564static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
@@ -1562,7 +1614,6 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
1562 }, 1614 },
1563 .ops = &davinci_mcasp_dai_ops, 1615 .ops = &davinci_mcasp_dai_ops,
1564 1616
1565 .symmetric_samplebits = 1,
1566 .symmetric_rates = 1, 1617 .symmetric_rates = 1,
1567 }, 1618 },
1568 { 1619 {
diff --git a/sound/soc/ti/edma-pcm.c b/sound/soc/ti/edma-pcm.c
index 3ebea1bd15cb..634b040b65f0 100644
--- a/sound/soc/ti/edma-pcm.c
+++ b/sound/soc/ti/edma-pcm.c
@@ -39,7 +39,22 @@ static const struct snd_dmaengine_pcm_config edma_dmaengine_pcm_config = {
39 39
40int edma_pcm_platform_register(struct device *dev) 40int edma_pcm_platform_register(struct device *dev)
41{ 41{
42 return devm_snd_dmaengine_pcm_register(dev, &edma_dmaengine_pcm_config, 0); 42 struct snd_dmaengine_pcm_config *config;
43
44 if (dev->of_node)
45 return devm_snd_dmaengine_pcm_register(dev,
46 &edma_dmaengine_pcm_config, 0);
47
48 config = devm_kzalloc(dev, sizeof(*config), GFP_KERNEL);
49 if (!config)
50 return -ENOMEM;
51
52 *config = edma_dmaengine_pcm_config;
53
54 config->chan_names[0] = "tx";
55 config->chan_names[1] = "rx";
56
57 return devm_snd_dmaengine_pcm_register(dev, config, 0);
43} 58}
44EXPORT_SYMBOL_GPL(edma_pcm_platform_register); 59EXPORT_SYMBOL_GPL(edma_pcm_platform_register);
45 60
diff --git a/sound/soc/ti/n810.c b/sound/soc/ti/n810.c
index 2c3f2a4c1700..3ad2b6daf31e 100644
--- a/sound/soc/ti/n810.c
+++ b/sound/soc/ti/n810.c
@@ -46,6 +46,7 @@ static void n810_ext_control(struct snd_soc_dapm_context *dapm)
46 switch (n810_jack_func) { 46 switch (n810_jack_func) {
47 case N810_JACK_HS: 47 case N810_JACK_HS:
48 line1l = 1; 48 line1l = 1;
49 /* fall through */
49 case N810_JACK_HP: 50 case N810_JACK_HP:
50 hp = 1; 51 hp = 1;
51 break; 52 break;
diff --git a/sound/soc/ti/rx51.c b/sound/soc/ti/rx51.c
index bc6046534fa5..588f680a9c24 100644
--- a/sound/soc/ti/rx51.c
+++ b/sound/soc/ti/rx51.c
@@ -55,6 +55,7 @@ static void rx51_ext_control(struct snd_soc_dapm_context *dapm)
55 break; 55 break;
56 case RX51_JACK_HS: 56 case RX51_JACK_HS:
57 hs = 1; 57 hs = 1;
58 /* fall through */
58 case RX51_JACK_HP: 59 case RX51_JACK_HP:
59 hp = 1; 60 hp = 1;
60 break; 61 break;
@@ -318,12 +319,10 @@ static struct snd_soc_dai_link rx51_dai[] = {
318 319
319static struct snd_soc_aux_dev rx51_aux_dev[] = { 320static struct snd_soc_aux_dev rx51_aux_dev[] = {
320 { 321 {
321 .name = "TLV320AIC34b", 322 .dlc = COMP_AUX("tlv320aic3x-codec.2-0019"),
322 .codec_name = "tlv320aic3x-codec.2-0019",
323 }, 323 },
324 { 324 {
325 .name = "TPA61320A2", 325 .dlc = COMP_AUX("tpa6130a2.2-0060"),
326 .codec_name = "tpa6130a2.2-0060",
327 }, 326 },
328}; 327};
329 328
@@ -396,8 +395,8 @@ static int rx51_soc_probe(struct platform_device *pdev)
396 dev_err(&pdev->dev, "Auxiliary Codec node is not provided\n"); 395 dev_err(&pdev->dev, "Auxiliary Codec node is not provided\n");
397 return -EINVAL; 396 return -EINVAL;
398 } 397 }
399 rx51_aux_dev[0].codec_name = NULL; 398 rx51_aux_dev[0].dlc.name = NULL;
400 rx51_aux_dev[0].codec_of_node = dai_node; 399 rx51_aux_dev[0].dlc.of_node = dai_node;
401 rx51_codec_conf[0].dev_name = NULL; 400 rx51_codec_conf[0].dev_name = NULL;
402 rx51_codec_conf[0].of_node = dai_node; 401 rx51_codec_conf[0].of_node = dai_node;
403 402
@@ -406,8 +405,8 @@ static int rx51_soc_probe(struct platform_device *pdev)
406 dev_err(&pdev->dev, "Headphone amplifier node is not provided\n"); 405 dev_err(&pdev->dev, "Headphone amplifier node is not provided\n");
407 return -EINVAL; 406 return -EINVAL;
408 } 407 }
409 rx51_aux_dev[1].codec_name = NULL; 408 rx51_aux_dev[1].dlc.name = NULL;
410 rx51_aux_dev[1].codec_of_node = dai_node; 409 rx51_aux_dev[1].dlc.of_node = dai_node;
411 rx51_codec_conf[1].dev_name = NULL; 410 rx51_codec_conf[1].dev_name = NULL;
412 rx51_codec_conf[1].of_node = dai_node; 411 rx51_codec_conf[1].of_node = dai_node;
413 } 412 }
diff --git a/sound/soc/uniphier/aio-dma.c b/sound/soc/uniphier/aio-dma.c
index fa001d3c1a88..e8446cc4e8f8 100644
--- a/sound/soc/uniphier/aio-dma.c
+++ b/sound/soc/uniphier/aio-dma.c
@@ -276,12 +276,10 @@ int uniphier_aiodma_soc_register_platform(struct platform_device *pdev)
276{ 276{
277 struct uniphier_aio_chip *chip = platform_get_drvdata(pdev); 277 struct uniphier_aio_chip *chip = platform_get_drvdata(pdev);
278 struct device *dev = &pdev->dev; 278 struct device *dev = &pdev->dev;
279 struct resource *res;
280 void __iomem *preg; 279 void __iomem *preg;
281 int irq, ret; 280 int irq, ret;
282 281
283 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 282 preg = devm_platform_ioremap_resource(pdev, 0);
284 preg = devm_ioremap_resource(dev, res);
285 if (IS_ERR(preg)) 283 if (IS_ERR(preg))
286 return PTR_ERR(preg); 284 return PTR_ERR(preg);
287 285
@@ -291,10 +289,8 @@ int uniphier_aiodma_soc_register_platform(struct platform_device *pdev)
291 return PTR_ERR(chip->regmap); 289 return PTR_ERR(chip->regmap);
292 290
293 irq = platform_get_irq(pdev, 0); 291 irq = platform_get_irq(pdev, 0);
294 if (irq < 0) { 292 if (irq < 0)
295 dev_err(dev, "Could not get irq.\n");
296 return irq; 293 return irq;
297 }
298 294
299 ret = devm_request_irq(dev, irq, aiodma_irq, 295 ret = devm_request_irq(dev, irq, aiodma_irq,
300 IRQF_SHARED, dev_name(dev), pdev); 296 IRQF_SHARED, dev_name(dev), pdev);
diff --git a/sound/soc/uniphier/evea.c b/sound/soc/uniphier/evea.c
index f9c10165fbc1..d27e9ca07856 100644
--- a/sound/soc/uniphier/evea.c
+++ b/sound/soc/uniphier/evea.c
@@ -451,7 +451,6 @@ static const struct regmap_config evea_regmap_config = {
451static int evea_probe(struct platform_device *pdev) 451static int evea_probe(struct platform_device *pdev)
452{ 452{
453 struct evea_priv *evea; 453 struct evea_priv *evea;
454 struct resource *res;
455 void __iomem *preg; 454 void __iomem *preg;
456 int ret; 455 int ret;
457 456
@@ -475,8 +474,7 @@ static int evea_probe(struct platform_device *pdev)
475 if (IS_ERR(evea->rst_exiv)) 474 if (IS_ERR(evea->rst_exiv))
476 return PTR_ERR(evea->rst_exiv); 475 return PTR_ERR(evea->rst_exiv);
477 476
478 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 477 preg = devm_platform_ioremap_resource(pdev, 0);
479 preg = devm_ioremap_resource(&pdev->dev, res);
480 if (IS_ERR(preg)) 478 if (IS_ERR(preg))
481 return PTR_ERR(preg); 479 return PTR_ERR(preg);
482 480
diff --git a/sound/soc/xilinx/xlnx_formatter_pcm.c b/sound/soc/xilinx/xlnx_formatter_pcm.c
index dc8721f4f56b..48970efe7838 100644
--- a/sound/soc/xilinx/xlnx_formatter_pcm.c
+++ b/sound/soc/xilinx/xlnx_formatter_pcm.c
@@ -613,7 +613,6 @@ static int xlnx_formatter_pcm_probe(struct platform_device *pdev)
613 aud_drv_data->mm2s_irq = platform_get_irq_byname(pdev, 613 aud_drv_data->mm2s_irq = platform_get_irq_byname(pdev,
614 "irq_mm2s"); 614 "irq_mm2s");
615 if (aud_drv_data->mm2s_irq < 0) { 615 if (aud_drv_data->mm2s_irq < 0) {
616 dev_err(dev, "xlnx audio mm2s irq resource failed\n");
617 ret = aud_drv_data->mm2s_irq; 616 ret = aud_drv_data->mm2s_irq;
618 goto clk_err; 617 goto clk_err;
619 } 618 }
@@ -640,7 +639,6 @@ static int xlnx_formatter_pcm_probe(struct platform_device *pdev)
640 aud_drv_data->s2mm_irq = platform_get_irq_byname(pdev, 639 aud_drv_data->s2mm_irq = platform_get_irq_byname(pdev,
641 "irq_s2mm"); 640 "irq_s2mm");
642 if (aud_drv_data->s2mm_irq < 0) { 641 if (aud_drv_data->s2mm_irq < 0) {
643 dev_err(dev, "xlnx audio s2mm irq resource failed\n");
644 ret = aud_drv_data->s2mm_irq; 642 ret = aud_drv_data->s2mm_irq;
645 goto clk_err; 643 goto clk_err;
646 } 644 }
diff --git a/sound/soc/xilinx/xlnx_i2s.c b/sound/soc/xilinx/xlnx_i2s.c
index 8b353166ad44..cc641e582c82 100644
--- a/sound/soc/xilinx/xlnx_i2s.c
+++ b/sound/soc/xilinx/xlnx_i2s.c
@@ -95,7 +95,6 @@ MODULE_DEVICE_TABLE(of, xlnx_i2s_of_match);
95 95
96static int xlnx_i2s_probe(struct platform_device *pdev) 96static int xlnx_i2s_probe(struct platform_device *pdev)
97{ 97{
98 struct resource *res;
99 void __iomem *base; 98 void __iomem *base;
100 struct snd_soc_dai_driver *dai_drv; 99 struct snd_soc_dai_driver *dai_drv;
101 int ret; 100 int ret;
@@ -107,8 +106,7 @@ static int xlnx_i2s_probe(struct platform_device *pdev)
107 if (!dai_drv) 106 if (!dai_drv)
108 return -ENOMEM; 107 return -ENOMEM;
109 108
110 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 109 base = devm_platform_ioremap_resource(pdev, 0);
111 base = devm_ioremap_resource(&pdev->dev, res);
112 if (IS_ERR(base)) 110 if (IS_ERR(base))
113 return PTR_ERR(base); 111 return PTR_ERR(base);
114 112
diff --git a/sound/soc/xilinx/xlnx_spdif.c b/sound/soc/xilinx/xlnx_spdif.c
index 3b9000fd8c49..e2ca087adee6 100644
--- a/sound/soc/xilinx/xlnx_spdif.c
+++ b/sound/soc/xilinx/xlnx_spdif.c
@@ -260,8 +260,7 @@ static int xlnx_spdif_probe(struct platform_device *pdev)
260 return ret; 260 return ret;
261 } 261 }
262 262
263 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 263 ctx->base = devm_platform_ioremap_resource(pdev, 0);
264 ctx->base = devm_ioremap_resource(dev, res);
265 if (IS_ERR(ctx->base)) { 264 if (IS_ERR(ctx->base)) {
266 ret = PTR_ERR(ctx->base); 265 ret = PTR_ERR(ctx->base);
267 goto clk_err; 266 goto clk_err;
diff --git a/sound/soc/xtensa/xtfpga-i2s.c b/sound/soc/xtensa/xtfpga-i2s.c
index 9ce2c75186b9..efd374f114a0 100644
--- a/sound/soc/xtensa/xtfpga-i2s.c
+++ b/sound/soc/xtensa/xtfpga-i2s.c
@@ -531,7 +531,6 @@ static int xtfpga_i2s_runtime_resume(struct device *dev)
531static int xtfpga_i2s_probe(struct platform_device *pdev) 531static int xtfpga_i2s_probe(struct platform_device *pdev)
532{ 532{
533 struct xtfpga_i2s *i2s; 533 struct xtfpga_i2s *i2s;
534 struct resource *mem;
535 int err, irq; 534 int err, irq;
536 535
537 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); 536 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
@@ -543,8 +542,7 @@ static int xtfpga_i2s_probe(struct platform_device *pdev)
543 i2s->dev = &pdev->dev; 542 i2s->dev = &pdev->dev;
544 dev_dbg(&pdev->dev, "dev: %p, i2s: %p\n", &pdev->dev, i2s); 543 dev_dbg(&pdev->dev, "dev: %p, i2s: %p\n", &pdev->dev, i2s);
545 544
546 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 545 i2s->regs = devm_platform_ioremap_resource(pdev, 0);
547 i2s->regs = devm_ioremap_resource(&pdev->dev, mem);
548 if (IS_ERR(i2s->regs)) { 546 if (IS_ERR(i2s->regs)) {
549 err = PTR_ERR(i2s->regs); 547 err = PTR_ERR(i2s->regs);
550 goto err; 548 goto err;
@@ -572,7 +570,6 @@ static int xtfpga_i2s_probe(struct platform_device *pdev)
572 570
573 irq = platform_get_irq(pdev, 0); 571 irq = platform_get_irq(pdev, 0);
574 if (irq < 0) { 572 if (irq < 0) {
575 dev_err(&pdev->dev, "No IRQ resource\n");
576 err = irq; 573 err = irq;
577 goto err; 574 goto err;
578 } 575 }
diff --git a/sound/soc/zte/zx-tdm.c b/sound/soc/zte/zx-tdm.c
index 5e877fe9ba7b..0e5a05b25a77 100644
--- a/sound/soc/zte/zx-tdm.c
+++ b/sound/soc/zte/zx-tdm.c
@@ -211,7 +211,6 @@ static int zx_tdm_hw_params(struct snd_pcm_substream *substream,
211 ts_width = 1; 211 ts_width = 1;
212 break; 212 break;
213 default: 213 default:
214 ts_width = 0;
215 dev_err(socdai->dev, "Unknown data format\n"); 214 dev_err(socdai->dev, "Unknown data format\n");
216 return -EINVAL; 215 return -EINVAL;
217 } 216 }